When saving an entity containing a image or file subfield inside a multifield, I get the following PDOException:

PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column fid; cannot be null: INSERT INTO {file_usage} (fid, module, type, id, count) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); Array(
    [:db_insert_placeholder_0] =>
    [:db_insert_placeholder_1] => file
    [:db_insert_placeholder_2] => multifield
    [:db_insert_placeholder_3] => 122
    [:db_insert_placeholder_4] => 1
) in file_usage_add() (line 697 of /var/www/develop/dist/webroot/includes/file.inc).

When file_field_insert() is called for the image/file subfield, $items contains one iten with a NULL fid. This NULL-fid item is added by multifield_item_serialize() called at the end of multifield_field_presave().

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

pbuyle’s picture

I tried forcing the call to multifield_field_presave() in multifield_field_insert(). While it does call file_field_presave() with a NULL-fid item (which is removed), this does not solve the issue. When _multifield_field_attach_insert() is called for the image field, the NULL-fid item is still present.

pbuyle’s picture

Issue summary: View changes

The NULL-fid item is added in multifield_item_serialize() called at the end of multifield_field_presave().

pbuyle’s picture

The bug was introduced in commit 0a4d448b6bd615bc80bc8d148d67ab2ff82956de (when using a checkout at commit 64c468327c65b6038d073a1997a1fafbd1328114, the issue disappear).

Dave Reid’s picture

If we wrapped an else condition around $item[$subfield_name . '_' . $column] = &$item[$subfield_name][LANGUAGE_NONE][0][$column]; would that help?

pbuyle’s picture

The issue in multifield_item_serialize() is with the following code

      if (!isset($item[$subfield_name][LANGUAGE_NONE][0][$column])) {
        $item[$subfield_name][LANGUAGE_NONE][0][$column] = isset($details['default']) ? $details['default'] : NULL;
      }

For a file subfield, this create a value like array('fid' => NULL, ...) at $item[$subfield_name][LANGUAGE_NONE][0]. When file_field_insert() is called, it invokes file_usage_add() with that value, which in turn try to insert a {file_usage} row with a NULL fid.

Normally, for a file field, file_field_presave() will remove an item with a NULL fid. It actually does it for a file subfield, but multifield_item_serialize() add it back when called at the end of multifield_field_presave().

sistro’s picture

I've the same issue... any solution?!

sistro’s picture

Here I'am... now I can describe my issue better.

I've got the error message (and the content not saved) when in the multifield I've a image field.

I've:
- Title
- Description
- Image
- Tablefield

If i leave blank all the field no problems.
If I have another field without image I've the error!

Also I've an issue with tablefield, when I try to rebuild tables but I've discovered that it is a tablefield module you can find the patch here: https://www.drupal.org/node/1288510#comment-9183039

This is a great module but I can't use it with this two errors!

rgrms’s picture

Is there any progress on solving this issue?

jerodfritz’s picture

I have this same problem

rgrms’s picture

Guys, I know that normally I have to be shot in head for such solution, but I faced a situation when this problem had to be fixed on working website within 5 minutes.

SO, below is extremely dirty workaround.
1) Since Multifield has no validation on empty image subfields, I manually created an image at public directory and added a managed_file entry into database with some fid to give it something than NULL for fid.
2) I replaced:

$item[$subfield_name][LANGUAGE_NONE][0][$column] = isset($details['default']) ? $details['default'] : NULL;

to this:

$my_fid = 1234;
if (!isset($item[$subfield_name][LANGUAGE_NONE][0][$column])) {
	if ($column == 'fid'){
	        $item[$subfield_name][LANGUAGE_NONE][0][$column] = isset($details['default']) ? $details['default'] : $my_fid;
	    } else $item[$subfield_name][LANGUAGE_NONE][0][$column] = isset($details['default']) ? $details['default'] : NULL;
}
mix359’s picture

Maybe is not the right solution, but I've changed the multifield_item_serialize() code, adding this

if(!isset($item[$subfield_name][LANGUAGE_NONE][0])) {
        $item[$subfield_name . '_' . $column] = NULL;
        continue;
      }

before this

if (!isset($item[$subfield_name][LANGUAGE_NONE][0][$column])) {
        $item[$subfield_name][LANGUAGE_NONE][0][$column] = isset($details['default']) ? $details['default'] : NULL;
      }

The idea is to check if the field doesn't have data ([0] doesn't exist on a field if it doesn't have data) and in that case return NULL...
don't know if there's any problem with the fact that it isn't a reference to a variable...
Hope can help :)

Mixologic’s picture

Nice find @Mongolito404, Dave's Comment in #4 is exactly where the issue is.

The reference assignment alters the existing data such that if it doesnt already have a value, one gets added to it:
so:
$item[$subfield_name . '_' . $column] = &$item[$subfield_name][LANGUAGE_NONE][0][$column];

Not only assigns a value to $item[$subfield_name . '_' . $column], but it *also* adds array elements to $item[$subfield_name][LANGUAGE_NONE][0] if they didnt exist before.

Attached is a patch that wraps the assignment in an if, as well only assigns the defaults to the subfields if it has a default set. (might break other things.. havent fully tested)

ysmith’s picture

Hi Mixologic:

I use the deploy module to pass the content from one site to another. Before this patch, using multifield (one textbox field and one image field), the content in dev site deploy normal without errors, but the content not arrive to production page. Now with your patch, the content arrive to production page, text fields are filled, but the field image are empty. In error log not show nothing.

Help!

Alienpruts’s picture

Hi Mixologic,

I had the same issue as above, multifield with two file subfields (one image and one file).

After applying your patch : no luck, allthough the error message now is accompagnied by a notice :

 Notice: Undefined property: stdClass::$fid in file_usage_add() (regel 689 van /home/vagrant/apps/default/******/includes/file.inc).
    PDOException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'fid' cannot be null: INSERT INTO {file_usage} (fid, module, type, id, count) VALUES (:db_insert_placeholder_0, :db_insert_placeholder_1, :db_insert_placeholder_2, :db_insert_placeholder_3, :db_insert_placeholder_4); Array ( [:db_insert_placeholder_0] => [:db_insert_placeholder_1] => file [:db_insert_placeholder_2] => multifield [:db_insert_placeholder_3] => 2 [:db_insert_placeholder_4] => 1 ) in file_usage_add() (regel 696 van /home/vagrant/apps/default/*******/includes/file.inc).

I'm guessing this is specific to my use case and I'll keep looking for an answer, but I thought you should at least know :)

Tnx for your work.
makkelijkegroenten

EDIT : i'm goofin' : there is only one file field, no image field. Sorry for the confusion.

EDIT2 : strange, all seemed to be working, until i started with Entity Translation of these fields. The error returned there.

alisaeedi’s picture

#12 worked for me, Thanks Mixologic

JamesAn’s picture

I'm confirming the exact error outcome in #2327317-14: Integrity constraint violation when saving multifield with a file subfield (i.e. same PHP errors occuring on the same specific PHP files and lines), but I'm having trouble isolating the source of the bug -- even to just the culprit field or field type, except that I know either or both of image field and file field are involved, as well as multifield. The client site has multilingual requirements which will be implemented using Entity Translations, but that hasn't even been turned on yet.

The entity architecture affected by this is a bit complicated in that the entity type has a polymorphic multifield bundle that has a list_text subfield that controls the set of fields that can be both editted by content creator roles and viewed at large by everyone through conditional_fields. I've confirmed that the bug reliably occurs even when field dependencies, but the error seems to reliably occur and also not occurring when the same subfield instances are in place, depending on the ordered steps I've taken to reinstantiate them in the multifield bundle...

In isolated debugging tests, the error doesn't seem to occur when an entity type only a multifield, which is made up of none of, either, or both of: an image or file field (i.e. respectively, a reference to the image bundle of file entities and a reference to any bundle of file entities) -- and, of course, a title or title_field via the Title module). The bug also doesn't trigger when the entity type itself has either or both an image and file field which is the same reference fields instantiated in the multifield or instances of distinct fields entirely.

Will try some other ideas to trace the source of what's going on here.

I managed to rewrite the logic in multifield_item_serialize() to correctly serialise the respective columns of the subfields while taking into account default values when the user submits no value for the subfield and the fact that this function is executed multiple times (and the serialisation should only occur the first function call for each subfield.

Will wrap this into a patch shortly. TBC...

JamesAn’s picture

Status: Active » Needs review
FileSize
1.83 KB

Voici. Le patch.

I've modified the logic itself in how the multifield_item_serialize() function determines what value to assign to the multiple $item[$subfield_name . '_' . $column] that correspond to the subfield's actual database table columns with the following logic flow:

  • Don't assign anything if $item[$subfield_name . '_' . $column] is already set (i.e. been assigned a value in an earlier invocation of multifield_item_serialize().
  • If the $column as derived from the field's definition constructed by field_info_field() also exists in the $item array that contain the actual values that make up the subfield, copy the matching value to $item[$subfield_name . '_' . $column] to be saved in the database.
  • Otherwise, that particular value of the subfield has been left blank:
    • If the field's definition contains a default value for this specific column, assign that default value to $item[$subfield_name . '_' . $column].
    • Else if the field's definition allows the column to be NULL, assign NULL to $item[$subfield_name . '_' . $column].

There is no catch-all else statement as any case that falls through these control statements is invalid/inconsistent (or I'm misunderstanding this data model). The last elseif statement shouldn't be replaced with a general else statement as it acts as assertion as that last elseif's condition should always trigger if the specific subfield column hasn't satisfied any earlier conditions.

Also, unset $item[$subfield_name] as it's now broken up and entirely represented by the various $item[$subfield_name . '_' . $column], and is therefore redundant/no longer of use.

Preliminary testing (not exhaustive at all) shows this patch resolving this issue insofaras the PDOException is no longer triggered, the inputted, default, or empty values are saved in that order of precedence as expected. This doesn't appear to cause any regressions with respect to non-image/-file fields either. I also haven't tested this in a multilingual environment, but that'll happen in the coming days at the latest.

LonitaD’s picture

The patch in #17 fixed it for me.

acolden’s picture

The patch in #17 fixed it for me too.

JamesAn’s picture

We've been depending on this patch for over two week now without issue. With these two confirmations, can we RBTC this?

Dave Reid’s picture

Status: Needs review » Needs work
Issue tags: +undefined

This needs some tests to prove the bug and fix is good. I know the 7.x-1.x branch tests are currently failing, but we still need tests for this.

Also the code style needs to be fixed to use the Drupal coding standards, especially around the if statements.

Dave Reid’s picture

Issue tags: -undefined +Needs tests

The last submitted patch, 17: multifield-integrity-constraint-violation-2327317-17.patch, failed testing.

rituraj.gupta’s picture

#17 seems to be working for me too!

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 17: multifield-integrity-constraint-violation-2327317-17.patch, failed testing.

The last submitted patch, 12: file_subfield_defaults-2327317-12.1380875.patch, failed testing.

doakym’s picture

The patch in #17 fixed it for me.

jenlampton’s picture

Rerolled the patch from #17 with correct coding standards. Still needs tests, but I'm happy to have the bug fixed - thanks for the hard work all! :)

Lepakshi Reddy Gollapalli’s picture

Still shows "The file used in the {file field name} field may not be referenced." while updating the content. While insert the content its success, but fails while update content.

Lepakshi Reddy Gollapalli’s picture

if comment the line unset($item[$subfield_name]); it works for me.

//unset($item[$subfield_name]);

justafish’s picture

The patch in #29 works well for me, thanks!

justafish’s picture

Spoke too soon... resaving the node gives the error
The file used in the Image field may not be referenced.

juampynr’s picture

irowboat’s picture

Temporarily solved this by commenting this line out in core (NOT RECOMMENDED but works as a very quick temp fix):
form_error($element, t('The file used in the !name field may not be referenced.', array('!name' => $element['#title'])));

Another thing, patch #29 has these lines:
--- a/multifield/multifield.module
+++ b/multifield/multifield.module

Patch won't apply in multifield root with this, you need to remove the dir name.

Lepakshi Reddy Gollapalli’s picture

Assigned: Unassigned » Lepakshi Reddy Gollapalli
Status: Needs work » Needs review
FileSize
1.78 KB

This patch created on top of #29 patch, It resolves the "The file used in the {file field name} field may not be referenced." issue.

Status: Needs review » Needs work

The last submitted patch, 36: multifield-integrity-constraint-violation-2327317-36.patch, failed testing.

noman_297’s picture

@jenlampton patch #29 worked form me.Thanks

lachris’s picture

The "The file used in the {file field name} field may not be referenced." error is because for each file uploaded, a record needs to be added to the "file_usage" table. I created a patch that runs file_usage_add before each field is saved. There might be a more appropriate place to put it. But this works, and I need to continue working on my project. Anyone willing to take over and improve, be my guest :)

@jenlampton, I included your #29 patch in mine as well if you don't mind.

lachris’s picture

My patch #39 gets the "Integrity contraint violation" errors when creating a new node, because it couldn't find the node id, which hasn't been generated at that point. A workaround is to call file_usage_add() every time we open the node/%/edit page. Now it works both when creating a node and updating a node.

loparr’s picture

#17 works for me. Thank you

detroz’s picture

.

badrange’s picture

Attaching a version of the patch from #29 which should work also from drush make files. The patch in 29 would be needed to be applied from the modules directory, and not the multifield module's own directory.

Quick test with patch from #29 and "#2054243: Ensure file usage is tracked appropriately for image and file fields." together seem very promising.

anjjriit’s picture

Patch #40 work for me too

detroz’s picture

I apply the solution proposed by badrange (see his comment : https://www.drupal.org/node/2327317#comment-10445483).

But I have a little bug with empty array.
I have a content with a "link" field.
No link attribute was attributed. So this array is empty.
In the request, the empty array was remplaced by nothing.
Ans MySQL is not agreed to have no value for "field_multifield_field_link_attributes" column...

[Update 19/01] After tests, every "attributes" array from "link" field provokes a SQL exception.
Because the array is not serialized...

To correct that, I alter the function multifield_item_serialize like that:

function multifield_item_serialize(&$item, $delta, $machine_name) {
  // Serialize the multifield values into separate columns for saving into the
  // field table.
  foreach (multifield_type_get_subfields($machine_name) as $subfield_name) {
    $subfield = field_info_field($subfield_name);
    foreach ($subfield['columns'] as $column => $details) {
      // @see field_sql_storage_field_storage_write()
      if (!isset($item[$subfield_name . '_' . $column])) {
        if (array_key_exists($subfield_name, $item) && \
            count($item[$subfield_name][LANGUAGE_NONE]) > 0 && \
            array_key_exists($column, $item[$subfield_name][LANGUAGE_NONE][0])) {
          // This value is assigned by reference as $items[$delta][$subfield_name]
          // could be modified in multifield_field_insert() or multifield_field_update().
          $item[$subfield_name . '_' . $column] = &$item[$subfield_name][LANGUAGE_NONE][0][$column];
+          // Serialize "attributes" data form "link" field.
+          if ($subfield['type'] == 'link_field' && $column == 'attributes') {
+            $item[$subfield_name . '_' . $column] = serialize($item[$subfield_name . '_' . $column]);
+          }
        }
        elseif (array_key_exists('default', $details)) {
          $item[$subfield_name . '_' . $column] = $details['default'];
        }
        elseif (array_key_exists('not null', $details) && $details['not null'] === FALSE) {
          $item[$subfield_name . '_' . $column] = NULL;
        }
      }
    }
    unset($item[$subfield_name]);
  }
}
takirami’s picture

Patch #43 worked for me.
However I do get a "The file used in the Picture field may not be referenced." error when editing nodes with images in multifield instances.

takirami’s picture

Nevermind, patch #40 works for me.

Bohus Ulrych’s picture

Hi all,
thank you for this great module which is the only one of such kind which works with entity translation (at least the way how I need).
But I have also issue to attach image. I tried patches #40 and #43 but they didn't worked.
I'm currently using solution #11 by mix359 which seems to be working well.

jenlampton’s picture

Status: Needs work » Reviewed & tested by the community

Patch in #40 is working for me as well. Thanks for the updates, everyone!

edit: Oh, just read the last comment. Not sure if this is RTBC yet, @Bohus Ulrych can you describe the problems you are having after using the patch in #40?

The last submitted patch, 29: multifield-integrity-constraint-violation-2327317-29.patch, failed testing.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 43: multifield-integrity-constraint-violation-2327317-43.patch, failed testing.

The last submitted patch, 39: multifield-integrity-constraint-violation-2327317-39.patch, failed testing.

The last submitted patch, 40: multifield-integrity-constraint-violation-2327317-40.patch, failed testing.

jayturn’s picture

The patches in #40 and #43 didn't work for me. I've added a patch that removes the file fields from the $pseudo_entity but keeps it in the original $item array. That way the field entity isn't affected but the multifield table is updated accordingly.

glynster’s picture

Patch 40 worked worked for us @jayturn, as your patch was not successful :(

badrange’s picture

A lot of water has flowed under the bridge since I last touched this issue, and I realised to my own surprise that the project in question had this issue - and not my own patch. I have a feeling that it never left the testing stage of the project and thus did not get put into production.

Just now, I upgraded the multifield module to the latest git revision and added jayturn's patch from #54, and I am able to save those nodes that caused the PDOException upon saving, so crossing my fingers that our solution is solved with that one.

glynster: In what way doesn't that patch work for you?
and jayturn: in what way didn't 40 or 43 work for you?

Would be great to move this issue forward and get a proper fix committed at some point.

glynster’s picture

@badrange I received the same initial error with the path from #54. So patched or not the same error. Once patch #40 was installed all worked as expected.

ArnaudDabouis’s picture

#40 works for me too, #54 leaves the same error.

Dave Reid’s picture

Assigned: Lepakshi Reddy Gollapalli » Dave Reid
Status: Needs work » Needs review
Issue tags: -Needs tests
FileSize
6.96 KB

I think I've got tests and a fix that might work. This will need real-world testing.

Dave Reid’s picture

Removing the debug() calls.

Dave Reid’s picture

Patch showing the test only which should fail with the well-known PDO Exception errors.

Dave Reid’s picture

Forgot the .info file change for the test-only patch.

Status: Needs review » Needs work

The last submitted patch, 62: 2327317-fix-empty-file-field-errors-fail.patch, failed testing.

Dave Reid’s picture

Status: Needs work » Needs review

Confirmed test failure, setting back to needs review for #60. Please test it everyone if you can.

The last submitted patch, 54: multifield-integrity-constraint-violation-2327317-54.patch, failed testing.

Dave Reid’s picture

  • Dave Reid committed acf0522 on 7.x-1.x
    Issue #2327317 by Dave Reid, lachris, lepakshi, JamesAn, badrange,...
Dave Reid’s picture

Status: Needs review » Fixed

Ok, I went ahead and committed #60 to 7.x-1.x. I'm confident it fixes the issue.

jenlampton’s picture

Thanks @Dave Reid!!! :)

  • Dave Reid committed acf0522 on 7.x-2.x
    Issue #2327317 by Dave Reid, lachris, lepakshi, JamesAn, badrange,...
darol100’s picture

Thank you so much. I just run into this issue right now. And it seem to be working if we are using the 7.x-2.x-dev version.

Status: Fixed » Closed (fixed)

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