How to save node with node_save() and node_autotitle module in custom module? - drupal-7

I am writing a Drupal custom module in which I create a node based on custom values. This is the code which creates node in proper manner.
global $user;
$node = new stdClass();
$node->type = 'my_node_type';
//$node->title = $nodeInfo->title;
node_object_prepare($node);
$node->language = LANGUAGE_NONE;
$node->uid = $user->uid;
$node->field_node_refrence_field['und'][0]['nid'] = $nid-of-reference-field;
$node = node_submit($node);
node_save($node);
I have the Node Autotitle module enabled for this content type. Due to that, the title is displayed as blank. I have checked the module, and I found that auto_nodetitle_set_title($node) sets the title. When I use this function in my code nothing happens.
Can anyone give me an idea on how to save the node with node_autotitle settings?

The code executed from auto_nodetile_set_title() is the following one. (The comments identifying parts of the code are mine.)
$types = node_type_get_types();
$pattern = variable_get('ant_pattern_' . $node->type, '');
// 1
if (trim($pattern)) {
$node->changed = REQUEST_TIME;
$node->title = _auto_nodetitle_patternprocessor($pattern, $node);
}
// 2
elseif ($node->nid) {
$node->title = t('#type #node-id', array('#type' => $types[$node->type]->name, '#node-id' => $node->nid));
}
// 3
else {
$node->title = t('#type', array('#type' => $types[$node->type]->name));
}
// Ensure the generated title isn't too long.
$node->title = substr($node->title, 0, 255);
// With that flag we ensure we don't apply the title two times to the same
// node. See auto_nodetitle_is_needed().
$node->auto_nodetitle_applied = TRUE;
The first control statement is executed if there is a settings for the title of that content type. If there isn't, and you are updating a module, then the second control statement is executed, otherwise it is executed the third one.
The title should never be empty, since the module always set it. The only time it could be empty is when Drupal doesn't have information about the content type used for the node; in that case $types[$node->type] would be NULL, but $types[$node->type]->name would raise the error "trying to access the property of something that is not an object."
I would use the following code, to save the node.
global $user;
$node = new stdClass();
$node->type = 'my_node_type';
node_object_prepare($node);
$node->uid = $user->uid;
$node->language = LANGUAGE_NONE;
$node->field_node_refrence_field[$node->language][0]['nid'] = $nid-of-reference-field;
$node = node_submit($node);
node_save($node);
auto_nodetitle_set_title($node);
node_save($node);
Since you are saving a new node, calling auto_nodetitle_set_title() before node_save() would not allow the function to execute the code marked with (2), and use the node ID for the title. Once auto_nodetitle_set_title() is called, you need to call node_save() to save the new title.

Related

PHP mailer and FPDF attachment with loop - script stops after first run

I'm running a following script to generate and send email. The email body is generated in a while loop (content differs) - it works fine. But now I have tried to include a script to generate PDF attachment (via FPDF library), in each iteration the attachment is different.
Problem is: the loop runs just once, for the first case and after it stops. Thank you for your commnents in advance.
My code:
<?
$mail = new PHPMailer();
$mail->SMTPDebug = 1;
$mail->isSMTP();
$mail->addReplyTo('');
$mail->isHTML(true);
$mail->Subject = "";
$mail->Host = 'smtp.gmail.com';
$mail->SMTPAuth = true;
$mail->SMTPSecure = 'tls';
$mail->Port = 587;
$mail->CharSet = 'utf-8';
$mail->setFrom('');
while(($data=MySQL_Fetch_Array($vysl))!=NULL) {
require_once('invoicetopdf.php');
$message="";
$mail->AddStringAttachment($invoice, 'Invoice.pdf', 'base64', 'application/pdf');
$mail->Username = "";
$mail->Password = "";
$mail->addAddress($to);
$mail->Body = $message;
if (!$mail->send()) {echo "Mailer Error: " . $mail->ErrorInfo;}
else {
$mail->clearAddresses();
$mail->ClearAllRecipients();
$mail->clearAttachments();
echo "Ok";
}
} //while
//invoicetopdf.php:
$data = MySQL_Fetch_Array($vysl);
require_once('../knihovny/pdf/fpdf.php');
$pdf = new PDF();
$pdf->.....;
$invoice=$pdf->Output('S');
?>
That's a bit of an odd way to run that code repeatedly. I would define a function in your invoicetopdf.php file, load it at the top of your script, and then call the function inside the loop to get the PDF data. You're also calling mysql_fetch_array twice - once in the while loop, once in the function, meaning half your data will be going astray.
require_once('invoicetopdf.php');
while(($data=MySQL_Fetch_Array($vysl))!=NULL) {
$message="";
$mail->AddStringAttachment(generatePDF($data), 'Invoice.pdf', 'base64', 'application/pdf');
...
//invoicetopdf.php:
require_once('../knihovny/pdf/fpdf.php');
function generatePDF($data) {
$pdf = new PDF();
$pdf->.....;
return $invoice=$pdf->Output('S');
}
I also recommend moving the Username and Password out of the loop, and you probably don't need to call clearAllRecipients(); clearAddresses() is enough.
Setting SMTPDebug = 2 will let you see more of what's happening in SMTP land.
Now it works: the main problem was a mixing a class and functions together. See:Multiple PDFs in Loop with FPDF
Thank you guys!

Drupal - get the field of view

Hello!
I am trying to get the fields of views
There is a code:
$variables = module_invoke('views', 'block_view', 'news-block');
print render($variables['content']);
to display unit software.
Whether it is possible to obtain the field at such a conclusion. Rather get views across the fields from variable $variables
Advance all grateful
Sorry for my English.
You can use views_get_view_result function:
$view = views_get_view_result($name, $display_id); // returns an array conatining the result of the view
print_r($view);
If you prefer to get whole node objects, you can use node_load function with nids of each row:
$view = views_get_view_result($name, $display_id); // returns an array conatining the result of the view
$nodes = array(); // create an empty array to push each node objects
foreach ($view as $row) {
$node = node_load($row->nid); // get the node object by nid
$nodes[] = $node; // push node to $nodes array
}
print_r($nodes);
Also see: https://drupal.stackexchange.com/questions/32825/get-a-views-result-using-php-code-and-iterate-the-proper-way

Prestashop 1.4.3 I need to get a database value and use it in MailAlerts module

I have asked this question on the Prestashop forum, but haven't had a reply as of yet.
I need to be able to add a sagepay code to the new order email used in mailalert module.
What I have is;
// Filling-in vars for email
$template = 'new_order';
$subject = $this->l('New order');
$spvtxc = Db::getInstance()->ExecuteS("SELECT vendortxcode FROM `"._DB_PREFIX_."sagepay_transactions` WHERE id_cart = '$order->id_cart'");
...
$templateVars = array(
'{firstname}' => $customer->firstname,
'{lastname}' => $customer->lastname,
...
'{sagepay_no}' => $spvtxc,
...
);
Every time i test a transaction the $spvtxc returns 'ARRAY'.
I have tried;
$spvtxc = '5';
As Expected this returns 5 as the sagepay number, so I'm confident the variables are being called and added to the email.
And I tried;
$spvtxc = Db::getInstance()->ExecuteS("SELECT vendortxcode FROM `"._DB_PREFIX_."sagepay_transactions` WHERE id_cart = '2'");
So this should set $spvtxc to the value that is definatly there (i manually added it in the database), but this still returned 'ARRAY'.
If anyone can point out what I have missed, it is greatly appriceated.
As I was only needing to return a single value, I should have used getValue function instead of ExecuteS.
$spvtxc = Db::getInstance()->getValue("SELECT vendortxcode FROM `"._DB_PREFIX_."sagepay_transactions` WHERE id_cart = '$order->id_cart'");
This returned the value.

drupal 7 - attach file to a node by code

I wanted to associate a file to a node. so far so good. create a cck type file, and the problem was solved. but I can not do this, I do not want the user to choose the file. the file in question is already in the system.
I have tried to place the file as # default_value field and hide it with the hook_form_FORM_ID_alter, but failed.
function my_module_form_node_form_alter(&$form, $form_state, $form_id) {
if(isset($form['type']) && isset($form['#node'])) {
$type = $form['#node']->type;
if(stripos($type, 'node-type') === FALSE)
return;
switch($type) :
case 'node-type_xyz':
$fid = arg(3);
$file = file_load($fid);
// make a cck field_invoice a hidden field
$form['field_invoice']['#prefix'] = '<div style="display:none;">';
$form['field_invoice']['#suffix'] = '</div>';
$form['field_company']['und'][0]['value']['#default_value'] = 'ABC';
$form['field_account_number']['und'][0]['value']['#default_value'] = '09879';
break;
endswitch;
}
}
anyone have any suggestions?
Don't use #prefix and #suffix to hide it. Instead, set #access to false - that way, people can't fiddle with the form. You can set the value in hook_nodeapi or a submit function, or set the type to 'value' and the #value to your file.

NullReferenceException while saving XML File with Linq

I keep getting a NullReferenceException at this line UserRoot.Element("User_ID").Value = User.User_ID.ToString();
What exactly am I doing wrong?
Here's the majority of the code for that method
if (File.Exists(Path2UserDB + User.User_ID.ToString() + ".db") == false)
{
File.Create(Path2UserDB + User.User_ID.ToString() + ".db");
}
XElement UserRoot = new XElement("User");
UserRoot.Element("User_ID").Value = User.User_ID.ToString();
UserRoot.Element("Full_Name").Value = User.Full_Name;
UserRoot.Element("Gender").Value = User.Gender;
UserRoot.Element("BirthDate").Value = User.BirthDate.ToString();
UserRoot.Element("PersonType").Value = User.PersonType.ToString();
UserRoot.Element("Username").Value = User.Username;
UserRoot.Element("Password").Value = User.Password;
UserRoot.Element("Email_adddress").Value = User.Email_Address;
XDocument UserDoc = new XDocument();
UserDoc.Save(Path2UserDB + User.User_ID.ToString() + ".db");
Thanks
I know that saving Usernames and Passwords in plain text is incredibly unsafe, but this is only going to be accessed by one process that I will eventually implement strong security
The Element("User_ID") method returns an existing element named <User_ID>, if any.
Since your XML element is empty, it returns null.
You should create your XML like this:
var userDoc = new XDocument(
new XElement("User",
new XElement("User_ID", User.User_ID),
new XElement("Full_Name", User.Full_Name),
new XElement("Gender", User.Gender),
...
)
);
Alternatively, you can call the Add method to add a node to an existing element.
You are getting this error, because there is no XML element called User_ID under UserRoot to set its value. If you comment it out, you will get the same error on the next line and so on for every other Element, since you haven't added Elements with thos names. To create the tree that you want, try this:
XElement UserRoot =
new XElement("User",
new XElement("User_ID", User.User_ID.ToString()),
new XElement("Full_Name", User.Full_Name),
new XElement("Gender", User.Gender),
new XElement("BirthDate", User.BirthDate.ToString()),
new XElement("PersonType", User.PersonType.ToString()),
new XElement("Username", User.Username),
new XElement("Password", User.Password),
new XElement("Email_adddress", User.Email_Address)
);
The following MSDN link on XML Tree Creation with XElement will be of help.
You want to check if the value is null or empty before running methods on it.
if(!String.IsnullorEmpty(User.User_ID))
UserRoot.Element("User_ID").Value = User.User_ID.ToString();

Resources