How to loop through a database table to save every column as a single node?
Вопрос
I have a module, which loads company data from an external db to save this as content.
function example_create_nodes() {
// Get Data from external DATABASE
db_set_active('db_wirdfit');
$result = db_query('SELECT * FROM wirdfit.wirdfit_data');
db_set_active();
foreach ($result as $row) {
$node->language = LANGUAGE_NONE;
$node->type = "page";
$node->title = $row->post_title;
node_object_prepare($node); //Set some default values
// Try to set your custom field
$node->field_id[$node->language][0]['value'] = $row->id;
$node->field_post_content[$node->language][0]['value'] = $row->post_content;
$node->field_post_author[$node->language][0]['value'] = $row->post_author;
$node->date = 'complaint_post_date';
$node->created = strtotime('complaint_post_date');
$path = 'content/mytest-' . date('YmdHis');
$node->path = array('alias' => $path);
print_r($row);
node_save($node);
}
That works but saved only one node from the the last row of my table. How can I loop through the table and save every row as a single content page?
Thanks for help
Решение
The code shown in the question would cause a warning (Creating default object from empty value) when PHP executes $node->language = LANGUAGE_NONE;
since $node
isn't first initialized. PHP 8.0 would throw fatal error (Fatal error: Uncaught Error: Attempt to assign property "language" on null).
The code needs to first initialize $node
.
After the call to node_save()
, when the node object isn't necessary anymore, it should set $node->is_new
to TRUE
and unset $node->nid
. Differently, Drupal would think you are saving the same node.
$node = (object) array();
foreach ($result as $row) {
$node->language = LANGUAGE_NONE;
$node->type = "page";
$node->title = $row->post_title;
node_object_prepare($node);
$node->field_id[$node->language][0]['value'] = $row->id;
$node->field_post_content[$node->language][0]['value'] = $row->post_content;
$node->field_post_author[$node->language][0]['value'] = $row->post_author;
$path = 'content/mytest-' . date('YmdHis');
$node->path = array('alias' => $path);
node_save($node);
$node->is_new = TRUE;
unset($node->nid);
}
I didn't set $node->created
, which should be a Unix timestamp (and it's already set by node_object_prepare()
), nor $node->date
, which node_object_prepare()
already sets to $node->date = format_date($node->created, 'custom', 'Y-m-d H:i:s O')
;`. If you need to set those fields, you need to set them to the values Drupal expects (a timestamp and a date string).
Другие советы
This is essentially PHP - you are not initiating a new variable with each iteration of the loop. Start a new $node - otherwise you are writing to it over and over.
foreach ($result as $row) {
$node = new stdClass();
$node->type = 'page';
...
$node = node_submit($node);
node_save($node);
}