if clear cache(use devel)

Notice: unserialize() [function.unserialize]: Error at offset 0 of 5 bytes in funcion commerce_price_field_load() (line 85 in file /home/path_to_root/sites/all/modules/commerce/modules/price/commerce_price.module).

&

Notice: Array to string conversion in function DatabaseStatementBase->execute() (line 2108 in file /home/path_to_root/includes/database/database.inc).

Comments

rszrama’s picture

I'll need more information to debug this. Is there anything I should know about the way you're using price fields? I've never had a problem clearing the cache before...

kratkar’s picture

I have 2 field price. Maybe because of this?

rszrama’s picture

How is the second one setup?

BenK’s picture

Subscribing

BenK’s picture

I'm experiencing this issue and I don't have two price fields... just a single one.

@kratkar: Do you happen to be using the Display Suite module and its custom view modes? I am and I'm wondering if this could be related.

--Ben

kratkar’s picture

@BenK Do not install this module.
I cleared all the data modules (admin/modules/uninstall) problem has been resolved. Modules uninstall: Product Attributes, Commerce Delivery, Features, Payment, Payment UI.
Now added another field to the node, where installed product reference. I entered value and clear cache - this message appears.
add dvm:

function commerce_price_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
  // Convert amounts to their floating point values and deserialize data arrays.
  dvm($entities); //!!!
  foreach ($entities as $id => $entity) {
    foreach ($items[$id] as $delta => $item) {
      // Unserialize the data array if necessary.
      if (!empty($items[$id][$delta]['data'])) {
        dvm($item[$id][$delta]['data']); //!!!
        $items[$id][$delta]['data'] = unserialize($items[$id][$delta]['data']);
      }
      else {
        $items[$id][$delta]['data'] = array('components' => array());
      }
    }
  }
}

Result http://ubuntuone.com/p/1Bhw/
I do not know it would help.

rszrama’s picture

Hmm, I see in your debug message where unserialization is partially happening... I haven't had problems with multiple fields before.

@kratkar, I couldn't tell from your reply to BenK, are you saying you're not using Display Suite?

kratkar’s picture

@rszrama I not using Display Suite
Now install drupal separately and will be installing modules and check.

kratkar’s picture

Not yet installed the modules.
But here's what did:

foreach ($entities as $id => $entity) {
    foreach ($items[$id] as $delta => $item) {
       drupal_set_message($items[$id][$delta]['data']);//!!

Output:

Array
a:1:{s:10:"components";a:0:{}}
a:1:{s:10:"components";a:0:{}}
a:1:{s:10:"components";a:1:{i:0;a:3:{s:4:"name";s:10:"base_price";s:5:"price";a:3:{s:6:"amount";i:0;s:13:"currency_code";s:3:"RUB";s:4:"data";a:0:{}}s:8:"included";b:1;}}}

First "Array"!
Check this:

function commerce_price_field_load($entity_type, $entities, $field, $instances, $langcode, &$items, $age) {
...
if (!empty($items[$id][$delta]['data']) && $items[$id][$delta]['data']!='Array') {
   $items[$id][$delta]['data'] = unserialize($items[$id][$delta]['data']);
}
...

Notice did not appear.

bendiy’s picture

I'm getting this same error. We have an import modules setup that pull products from another database and creates them in Drupal Commerce. It then creates product nodes. I have three price fields. I get this error at Store > Products > List after an import. Making the change in #9 appears to have fixed it.

rszrama’s picture

Hmm, the problem, though, is that it should never have attempted to write the "Array" to that column without first serializing it. The change in #9 just hides the issue... the real issue is we need to ensure every price field data array is properly serialized on save. We'll need to find the common denominator in your three scenarios.

Are you all using some sort of import routine or creating your products / nodes and price data through the UI?

Are you all getting this problem with price fields on nodes?

bendiy’s picture

Using Eclipse and xDebug, this is what my $item variable looks like for one item:

$items	Array [47]	
	[0...30]	
		7	Array [1]	
			[0...0]	
				0	Array [3]	
					[0...2]	
						amount	30	
						currency_code	USD	
						data	<Uninitialized>	

There are a few hundred items it loops through that all look like that.

bendiy’s picture

I also get the error if I have an item in the cart and the cart block on every page. If I Flush All Caches, when the page loads, I get the error. Here's the $item array for the cart:

$item	Array [3]	
	[0...2]	
		amount	7000	
		currency_code	USD	
		data	a:1:{s:10:"components";a:1:{i:0;a:3:{s:4:"name";s:10:"base_price";s:5:"price";a:3:{s:6:"amount";i:7000;s:13:"currency_code";s:3:"USD";s:4:"data";a:0:{}}s:8:"included";b:1;}}}
sreynen’s picture

I saw this error with products I created in code where I didn't set the price field at all.

bendiy’s picture

My price field is set for my products. I'm using the default price field and 3 additional ones that were added. Not all of the additional price fields have a value in them. Maybe that's the issue?

I upgraded my site yesterday to the new Drupal Commerce 1.0, all suggested versions of the required modules for Drupal Commernce (Ctools, Rules, etc) and moved to Drupal 7.8. I'm not getting the error any more.

Can anyone else confirm upgrading fixes their errors?

thesurfinganalyst’s picture

Version: 7.x-1.0-rc3 » 7.x-1.x-dev

Not sure if this is related, but I'm using devel-generate to create content product nodes that have a price field. Note: I'm not generating products, but nodes that have product references.

Using devel-generate to receive the following notice:

Notice: Array to string conversion in DatabaseStatementBase->execute() (line 2137 of C:\cygwin\home\Simon\work\drupal\includes\database\database.inc). Backtrace:
PDOStatement->execute(Array) database.inc:2137
DatabaseStatementBase->execute(Array, Array) database.inc:664
DatabaseConnection->query('INSERT INTO {field_data_field_recommended_price} (entity_type, entity_id, revision_id, bundle, delta, language, field_recommended_price_amount, field_recommended_price_currency_code, field_recommended_price_data) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8)', Array, Array) query.inc:36
InsertQuery_mysql->execute() field_sql_storage.module:424
field_sql_storage_field_storage_write('node', Object, 'insert', Array) 
call_user_func_array('field_sql_storage_field_storage_write', Array) module.inc:795
module_invoke('field_sql_storage', 'field_storage_write', 'node', Object, 'insert', Array) field.attach.inc:928
field_attach_insert('node', Object) node.module:1132
node_save(Object) devel_generate.inc:697
devel_generate_content_add_node(Array) devel_generate.inc:133
devel_generate_content(Array) devel_generate.module:229
devel_generate_content_form_submit(Array, Array) form.inc:1414
form_execute_handlers('submit', Array, Array) form.inc:832
drupal_process_form('devel_generate_content_form', Array, Array) form.inc:352
drupal_build_form('devel_generate_content_form', Array) form.inc:189
drupal_get_form('devel_generate_content_form') 
call_user_func_array('drupal_get_form', Array) menu.inc:503
menu_execute_active_handler() index.php:21

When I view the generated nodes I receive the 'Notice: unserialize'.

carn1x’s picture

Notice: unserialize() [function.unserialize]: Error at offset 0 of 5 bytes in funcion commerce_price_field_load() (line 85 in file /home/path_to_root/sites/all/modules/commerce/modules/price/commerce_price.module).

I am getting this error after running import from CSV through Commerce Feeds, seemingly 1 instance of the error for each imported product.

If I remove all the imported products, and keep only manually entered products, all the errors go away.

Wasn't getting the issue at all before hand.

I am storing 5 different price fields if that makes any difference?

wojtha’s picture

I'm just debugging that... found this

INSERT INTO field_revision_field_course_fee_concession (entity_type, entity_id, revision_id, bundle, delta, language, field_course_fee_concession_amount, field_course_fee_concession_currency_code, field_course_fee_concession_data) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8_components)

Notice the :db_insert_placeholder_8_components key, it contains empty array - "Array[0]".

I suspect the filefield_paths module since I had bit similar kind of problems (messed up node object) in Drupal 6 half year ago and filefield_paths was the principal offender. It is because filefield_paths module needs tokens for paths replacement so during node save it loads node object again and node object is being modified by this process because it is passed by reference. The second thing is that this module itself invokes node update hook so the data flows in a bit different way and some parts of the usual node/field update process is bypassed.

Stack when saving the invalid data just before DB exception is going to be thrown:

  1. query(): /css1-001-centralschool/www/includes/database/database.inc at line 2137
  2. query(): /includes/database/database.inc at line 664
  3. execute(): /includes/database/mysql/query.inc at line 36
  4. field_sql_storage_field_storage_write(): /modules/field/modules/field_sql_storage/field_sql_storage.module at line 425
  5. module_invoke(): /includes/module.inc at line 795
  6. field_attach_update(): /modules/field/field.attach.inc at line 979
  7. filefield_paths_node_update(): /sites/all/modules/contrib/filefield_paths/filefield_paths.module at line 355
  8. module_invoke_all(): /includes/module.inc at line 819
  9. node_save(): /modules/node/node.module at line 1134
  10. node_form_submit(): /modules/node/node.pages.inc at line 406
  11. form_execute_handlers(): /includes/form.inc at line 1414
  12. drupal_process_form(): /includes/form.inc at line 832
  13. drupal_build_form(): /includes/form.inc at line 352
  14. drupal_get_form(): /includes/form.inc at line 189
  15. node_page_edit(): /modules/node/node.pages.inc at line 15
  16. workbench_moderation_node_edit_page_override(): /sites/all/modules/contrib/workbench_moderation/workbench_moderation.module at line 846
  17. menu_execute_active_handler(): /includes/menu.inc at line 503
  18. /index.php at line 22

wojtha’s picture

So I disabled the suspect - filefield_paths but still experiencing this bug.

I found that the data are saved twice during the node_save(). Here is node update lifecycle with important stages in bold:

  1. field_attach_presave() - price field data are serialized
  2. hook_node_presave()
  3. hook_entity_presave()
  4. Node and revision records are written to the database
  5. hook_update()
  6. field_attach_update() - price field data are saved correctly but during this phase node object is messed up - price data are unserialized
  7. hook_node_update() - price field data are saved again incorrectly (w/o being serialized)
  8. hook_entity_update()
  9. hook_node_access_records()
  10. hook_node_access_records_alter()

So in short:

  1. some module touches (or might be core itself?) the node object during field_attach_update/insert() short after the fields are saved correctly and overwrites the serialized data
  2. during the hook_node_update/insert() are fields saved again (e.g. when using Workbench or Filefield paths) but with data unserialized which results in this issue.
wojtha’s picture

some module touches (or might be core itself?) the node object during field_attach_update/insert() short after the fields are saved correctly and overwrites the serialized data

And the winner is ... Drupal Commerce! :-)

These two functions unserialize the price during node insert/update lifecycle.

/**
 * Implements hook_field_attach_insert().
 *
 * This hook is used to unserialize the price field's data array after it has
 * been inserted, because the data array is serialized before it is saved and
 * must be unserialized for compatibility with API requests performed during the
 * same request after the insert occurs.
 */
function commerce_price_field_attach_insert($entity_type, $entity) {
  _commerce_price_field_attach_unserialize_data($entity_type, $entity);
}

/**
 * Implements hook_field_update().
 *
 * This hook is used to unserialize the price field's data array after it has
 * been updated, because the data array is serialized before it is saved and
 * must be unserialized for compatibility with API requests performed during the
 * same request after the update occurs.
 */
function commerce_price_field_attach_update($entity_type, $entity) {
  _commerce_price_field_attach_unserialize_data($entity_type, $entity);
}
wojtha’s picture

Thinking about workaround... but it is not easy. Node object is shared across all node and field hooks so if we made change such as the serialization, the change is global.

The conflicting modules are e.g. Filefield Paths

/**
 * Implements hook_node_update().
 */
function filefield_paths_node_update($node) {

    // { ... stripped  code ... }

    field_attach_update('node', $node);
  }
}

or Workbench Moderation

/**
 * Implements hook_node_update().
 *
 * Handles the submit of the node form moderation information
 */
function workbench_moderation_node_update($node) {

  // { ... stripped  code ... }

  // Apply moderation changes if this is a new revision or if the moderation
  // state has changed.
  if (!empty($node->revision) || $node->workbench_moderation_state_current != $node->workbench_moderation_state_new) {
    // Update attached fields.
    field_attach_update('node', $node);
    // Moderate the node.
    workbench_moderation_moderate($node, $node->workbench_moderation_state_new);
  }

  return;
}

The given chunks of code could be IMHO fixed by calling node_presave() or field_attach_presave() before calling field_attach_update().

Question is if it is the right approach and if is Commerce issue or Drupal core issue or the conflicting modules issue...

5n00py’s picture

Any working solutions?

adroid’s picture

Subscribing

sixelats’s picture

I've altered the if statement in line 84 of commerce_price.module with the code from #9

if (!empty($items[$id][$delta]['data']) && $items[$id][$delta]['data']!='Array') {

and haven't seen the error since. Also, everything about prices seems to work fine but it's not on a live site.

mr.baileys’s picture

It might be a long shot, but since the errors seem similar, try and see if the patch from #1403140: Rule to copy price from one product to another causes PHP notices fixes the issue (also deals with price field (un-)serialization issues.

amateescu’s picture

Component: Product reference » Price
Status: Active » Needs review
StatusFileSize
new4.51 KB

This was quite hard to crack, took me a few hours :) Anyway, the answer is... *drumroll*: hook_field_storage_pre_insert() and hook_field_storage_pre_update().

This patch also fixes #1403140: Rule to copy price from one product to another causes PHP notices so I'm going to close that as a duplicate.

I'm not very happy with this piece of code, but I hope Ryan will have some ideas on how to clean it.

          if (!empty($item['data'])) {
            // If we have an array $item['data'], serialize it.
            if ($op == 'serialize' && is_array($item['data'])) {
              $entity->{$field_name}[$langcode][$delta]['data'] = serialize($item['data']);
            }
            // If we have a non-array $item['data'], unserialize it.
            elseif ($op == 'unserialize' && !is_array($item['data'])) {
              $entity->{$field_name}[$langcode][$delta]['data'] = unserialize($item['data']);
            }
          }
          // If we have no data element (or an existing empty), create an empty
          // array.
          elseif (empty($item['data']) && $op == 'unserialize') {
            $entity->{$field_name}[$langcode][$delta]['data'] = array('components' => array());
          }
sixelats’s picture

Applied patch #26 with commerce 7.x-1.2 but I still get the notice: unserialize data error.

amateescu’s picture

@sixelats: the patch from #26 doesn't include an update function to clean existing 'bad' data, I don't know if that's even possible. It just prevents the error to appear in the future by moving data serialization to a later stage in the process :)

lukus’s picture

Version: 7.x-1.x-dev » 7.x-1.2

Thanks for the patch - I was experiencing the error after a cache refresh. The patch solved the problem for me.

msmithcti’s picture

@amateescu If I'm understanding comment #28 correctly: I'm getting this error on a site I'm developing at the moment with some dummy products. If I delete the dummy products and apply this patch before adding the products for real will that sort the error?

wojtha’s picture

@splatio yes, the problem is that the price data was wrong serialized during node insert/update. Theoretically you can just update the nodes (after applying the patch) which forces the price field to resave and hopefully save the correct price data this time.

Ahyari’s picture

@No need to deleted the old products, After applying the patch I disabled then enabled all products. The error disappeared.

msmithcti’s picture

@Ahyari, @wojtha - thanks for the clarification!

chrisjlee’s picture

Status: Needs review » Reviewed & tested by the community

@amateescu Patch seems to work for me and solved my problem thus far!

I just had some issues patching it because my git root dir was different. For others trying this out you may need to just use unix's native patch system:

patch < 1253114-26.patch

batigol’s picture

I can confirm that patch from #26 is working for me - at last I can include proper tax in my product.

Before I did got this error:

Notice: Array to string conversion in DatabaseStatementBase->execute() (line 2139 of C:\xampp\htdocs\drupal\includes\database\database.inc).
PDOException: SQLSTATE[21S01]: Insert value list does not match column list: 1136 Column count doesn't match value count at row 1: INSERT INTO {field_data_commerce_price} (entity_type, entity_id, revision_id, bundle, delta, language, commerce_price_amount, commerce_price_currency_code, commerce_price_data) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4, :db_insert_placeholder_5, :db_insert_placeholder_6, :db_insert_placeholder_7, :db_insert_placeholder_8_components, :db_insert_placeholder_8_include_tax); Array ( [:db_insert_placeholder_0] => commerce_product [:db_insert_placeholder_1] => 2 [:db_insert_placeholder_2] => 9 [:db_insert_placeholder_3] => XXXXX [:db_insert_placeholder_4] => 0 [:db_insert_placeholder_5] => und [:db_insert_placeholder_6] => 2000 [:db_insert_placeholder_7] => EUR [:db_insert_placeholder_8_components] => Array ( ) [:db_insert_placeholder_8_include_tax] => vat ) in field_sql_storage_field_storage_write() (line 448 of C:\xampp\htdocs\drupal\modules\field\modules\field_sql_storage\field_sql_storage.module).
aidanlis’s picture

I'm getting this problem too. My products are created through the GUI, but the rest of the data in commerce (orders, line items, etc) are created using the Migrate module. The patch in #26 solves my problem.

wojtha’s picture

It will be nice to provide some update function for this issue. I don't think we need to load each product as full object and re-save it. The price data columns is broken anyway so some kind of addittional data is lost anyway so I propose just filling the DB columns with the right data "empty" data.

Pseudocode:

foreach ($commmerce_fields as $field) {
   UPDATE field_revision_{$field} SET {$field}_data ='a:1:{s:10:"components";a:0:{}}' WHERE {$field}_data = 'Array';
   UPDATE field_data_{$field} SET {$field}_data ='a:1:{s:10:"components";a:0:{}}' WHERE {$field}_data = 'Array';
}

Or is there any way how to update the price field via API without need to load the whole product node object?

rszrama’s picture

Status: Reviewed & tested by the community » Needs work

Ahh, you know what, that's a perfectly reasonable update solution. I was wondering how we'd end up doing that, and since "Array" obviously isn't useful at all, nuking the column entirely is fair game. I've been struggling in my review of this patch lately, and I think the reason is because it unnecessarily combines two separate functions into one. I'm going to revert the combination of serialization / unserialization code into the single "prepare" function so that we have two separate functions for it, but I'll stick with the field storage hooks approach.

no2e’s picture

Had the same problem as described in #1446132: Notice: Array to string conversion in DatabaseStatementBase->execute().
The attached patch from #26 helped: the warnings don't appear anymore.

I'm not sure what I should do with the posted php code (in #26, too)? Do I need it in addition to the patch?

And: can't this #26 patch be committed now?
As far as I understand, it is only missing a way to update existing products, correct? But couldn't this be another issue? For ppl who freshly start, the fix would save trouble, wouldn't it?

ryumkin’s picture

subscribe

murz’s picture

jbova’s picture

The patch in #26 solved some problems. I had to delete any open shopping carts or orders containing the products, then delete the products in order for the error to disappear.

mrpeanut’s picture

The patch from #26 also worked for me. Like jbova in #42, I also had to delete any open shopping carts and orders. I also cleared the cache and disabled then enabled my dummy product.

rszrama’s picture

Just to reiterate, my recommendation in #38 needs to happen before a fix is committed. I've been meaning to do it myself but just didn't have the time with everything happening at DrupalCon.

giorgosk’s picture

any progress ?
I have changed status of all products using latest VBO http://drupal.org/project/views_bulk_operations
status disabled then again enabled and the error message are gone ... (also using patch #26)

dimitriseng’s picture

I can also confirm that patch #26 removes the error messages. Will be waiting for the updated patch as per #38... Thanks.

wedge’s picture

#26 fixed this for me too. Thanks.

rszrama’s picture

Issue tags: +1.3 blocker

Tagging this for 1.3. Even though people keep +1'ing the patch in #26, we won't commit anything until it's been reworked according to #38. I started this work but then got sidetracked, so I don't have any patch to share on this atm.

amateescu’s picture

Version: 7.x-1.2 » 7.x-1.x-dev
Status: Needs work » Needs review
StatusFileSize
new6.87 KB

Here's an updated patch that provides separate serialize/unserialize code and an update function.

Status: Needs review » Needs work

The last submitted patch, 1253114-49.patch, failed testing.

amateescu’s picture

Status: Needs work » Needs review
StatusFileSize
new6.89 KB

Sloppy copy-paste :)

Anonymous’s picture

I was getting the error message from #35 when trying to create a product, which brought me to this issue. I applied the patch from #51 to the latest dev version of Commerce and now the error's gone and products are being created successfully.

I'll let others test and mark as RTBC, but it's working for me!

helior’s picture

Status: Needs review » Reviewed & tested by the community

Everything works smoothly with applying the patch from #51. Great work!

Marcus VBP’s picture

Hi, after the last -dev release, I get this error again, and the patch not worked.

thanks.

rszrama’s picture

@Marcus VBP, did you actually apply the patch? It hasn't been committed to any -dev yet.

Marcus VBP’s picture

@rszrama yes, I applied the patch after upgrading to the latest version -dev and not worked

k4v’s picture

@Marcus VBP: Did you update the database (drush updatedb, update.php?). After applying the patch I still saw the error before updating. The patch works for me =).

rszrama’s picture

Status: Reviewed & tested by the community » Fixed

Alrighty, got a quickie review in before committing and realized we needed to add a confirmation message in the update function. Additionally, instead of the update function initializing components arrays in all the data columns, I just reset the values to NULL. We're initializing components arrays on load, so there's no reason to take up disk space with all those initialized strings. : )

Thanks so much to amateescu for sticking with this and for everyone who brought new insight to the table. This was particularly nasty to track down, and I'm sorry it took so long to finally commit a solution.

Commit: http://drupalcode.org/project/commerce.git/commitdiff/3d45979

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

English version & delete home dir

ollaankoodeis’s picture

Issue summary: View changes

I get this same error when updating product images filenames with Filefield paths.

Notice: unserialize(): Error at offset 0 of 5 bytes funktiossa commerce_price_table_field_load() (line 180 in file /[path_to_drupal]/sites/all/modules/contrib/commerce_price_table/commerce_price_table.module).

I'm using latest stable releases of Drupal and modules so fixes to this issue should be committed?

wittehond’s picture

StatusFileSize
new4.79 KB

rerolled the patch against 7.x-1.x dev from git. the checks for empty are still needed with commerce_price_table