I have very little experience working with Drupal and it may be possible that I'm missing something very basic here.
I have created a module to add/update nodes pro-grammatically from an XML file, this nodes have a file for images. For every node there's a French version and an English version, this means that they share the same images.
When I import these nodes I would like to avoid refetching the images (since those are already into the public://
folder) and populate only the image field.
The first run goes smoothly, the images are fetched and saved from URL for all the English nodes using this code:
if(!file_exists("public://" . $name)) {
$file_temp = file_get_contents($URL);
$file_temp = file_save_data($file_temp, "public://" . $name, FILE_EXISTS_REPLACE);
}
$node->field_image[LANGUAGE_NONE][$k]['fid'] = $file_temp->fid;
$node->field_image[LANGUAGE_NONE][$k]['title'] = $name;
The second round, for the french nodes, what I've done is:
else {
$file_temp = new stdClass();
// Get the image id corresponding to the $name parameter, returns string.
$file_temp->fid = _xml_importer_get_image_id($name, $table, $fid, $title);
}
$node->field_image[LANGUAGE_NONE][$k]['fid'] = $file_temp->fid;
$node->field_image[LANGUAGE_NONE][$k]['title'] = $name;
This works, in a sense, meaning that the fields are populated correctly and the image are shared between the nodes, the problem is that I get warning and notices for this part.
This is the full dump:
Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of /drupal/includes/entity.inc). Notice: Trying to get property of non-object in file_field_presave() (line 220 of drupal/modules/file/file.field.inc). Strict warning: Creating default object from empty value in file_field_presave() (line 221 of drupal/modules/file/file.field.inc). Notice: Undefined property: stdClass::$uri in file_save() (line 566 of drupal/includes/file.inc). Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of drupal/includes/entity.inc). Notice: Trying to get property of non-object in file_field_presave() (line 220 of drupal/modules/file/file.field.inc). Strict warning: Creating default object from empty value in file_field_presave() (line 221 of drupal/modules/file/file.field.inc). Notice: Undefined property: stdClass::$uri in file_save() (line 566 of drupal/includes/file.inc). SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '' for key 'uri' Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of drupal/includes/entity.inc). Notice: Trying to get property of non-object in file_field_presave() (line 220 of drupal/modules/file/file.field.inc). Strict warning: Creating default object from empty value in file_field_presave() (line 221 of drupal/modules/file/file.field.inc). Notice: Undefined property: stdClass::$uri in file_save() (line 566 of drupal/includes/file.inc). Warning: array_flip() [function.array-flip]: Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 178 of drupal/includes/entity.inc). Notice: Trying to get property of non-object in file_field_presave() (line 220 of drupal/modules/file/file.field.inc). Strict warning: Creating default object from empty value in file_field_presave() (line 221 of drupal/modules/file/file.field.inc). Notice: Undefined property: stdClass::$uri in file_save() (line 566 of drupal/includes/file.inc).
I looked for this kind of warnings/notices and I found out that somewhere I'm passing some parameters not in a correct way (e.g. arrays instead of strings) and for me doesn't make sense.
My guess is that not invoking file_save_data
has some effect on the file_managed
table and gives missing or malformed parameter, anyway with my poor experience I may be very well mistaking.
This is the full code snippet I'm using:
for($k=0; $k<sizeof($file_list); $k++) {
if(!file_exists("public://" . $file_list[$k]->name)) {
$file_temp = file_get_contents($URL);
$file_temp = file_save_data($file_temp, "public://" . $file_list[$k]->name, FILE_EXISTS_REPLACE);
}
else {
$file_temp = new stdClass();
// Get the image id corresponding to the $name parameter, returns string.
$file_temp->fid = _xml_importer_get_image_id($file_list[$k]->name, $table, $fid, $title);
}
$node->field_image[LANGUAGE_NONE][$k]['fid'] = $file_temp->fid;
$node->field_image[LANGUAGE_NONE][$k]['title'] = $file_list[$k]->name;
}
And this is the function _xml_importer_get_image_id:
_xml_importer_get_image_id($image_name, $table, $field, $title_field) {
$query = db_select($table, 'ill')
->condition('ill.' . $title_field, $image_name, '=')
->fields('ill', array($field))
->execute()
->fetchCol();
if(empty($query)) {
return false;
}
else{
return (string)$query[0];
}
}
_xml_importer_get_image_id()
function. BTW if that really is your full code snippet then$k
isn't defined which won't help_xml_importer_get_image_id()
function and thefor
cycle for the$k
variable, I left it out at the beginning because i thought it was not important, I forgot to say that every node can have more than 1 image.$file_list
coming from?$file_list = $xml->xpath($xpath_query)
, I dsm'd the hell out of this xpath parsing and I know I get all the names correctly (otherwise it wouldn't work at all, meaning it wouldn't fetch the images).