Problem statement

PHP Fatal error occurs in Image_Attach submodule when saving a node that has no images attached. In various cases the 'iids' array key is empty (eg node import, biblio module, or custom code that sets the form field '#access' to FALSE.

The error message is:

PHP Fatal error:  Cannot unset string offsets in image_attach.module on line 457

Proposed solution

Wrap the unset() in an if (isset()).

Original issue summary:

Please see my description here #589422: PHP fatal error

I think that a change in Image.Module has impacted another module

Comments

sphopkins’s picture

Component: image.module » image_attach
joachim’s picture

It helps if you repeat the problem here:

Drupal 6.13, Image 6.x-1.0-beta3

When attempting an import (that had worked flawlessly before) I get the following error on my server:

PHP Fatal error: Cannot unset string offsets in /var/www/html/sites/all/modules/image/contrib/image_attach/image_attach.module on line 343, referer: http://x.x.x.x/?q=admin/content/node_import/41

Can you confirm your line 343 is this:

      // Unsetting the "- None -" entry from the form select entries
      unset($node->iids[0]);

If so, I'm sure there are better places for this than hook_nodeapi -- it's dealing with a quirk of the form, whereas hook_nodeapi is meant to be general. We should move it to a submit handler perhaps?

On the other hand, apparently
"PHP 5 seems to have an error where it tries to treat strings as arrays instead of highlighting the error"
did you run update.php after upgrading to the latest image module?

sphopkins’s picture

I will confirm tomorrow when I have full access to my server. However as I have not touched anything I am sure it is whatever you guys released ;-)

I did run update.php but I will verify that it has been completely done...

sphopkins’s picture

Confirmed:

// Unsetting the "- None -" entry from the form select entries
      unset($node->iids[0]);

As well I have confirmed that update.php was run, and I reran it to verify.

Hope this helps.

joachim’s picture

Does commenting out that line fix the problem?

sphopkins’s picture

I will test that. I am not normally comfortable changing some of the code without someone who knows what is happening giving me the go-ahead !

sphopkins’s picture

Commenting the line out worked to allow the Node_import to work properly.

Thanks for reviewing.

joachim’s picture

Title: PHP Fatal Error - interaction with Node_Import ? » clean up form data in submit handler, not hook_nodeapi -- produces PHP Fatal Error with Node_Import

Thanks for confirming.
Better title.

joachim’s picture

Status: Active » Needs review
StatusFileSize
new1.73 KB

Please could you test this patch?

You'll need either a clean copy of beta3 or the dev release to apply it to.

This patch also needs to be tested for regular use of image attach: creating and editing nodes normally, without node_import.

sphopkins’s picture

I will look at this patch. I only have a production server so I am leery of messing it up ;-)

joachim’s picture

The drupal docs have a section on running a test server locally. This is a good idea to have in general, and is a lot easier to set up than it used to be: basically, xampp on Windows and mamp on a mac.

sphopkins’s picture

Yeah I have MAMP Pro and I did use it for testing to get the website up and running but it has gone stale since I implemented the site. I will try and update things to the same level before testing.

joachim’s picture

I recommend this for cloning your live site to your dev server: http://drupal.org/project/backup_migrate -- does it in about three clicks; an absolute breeze.

magpie5212’s picture

Subscribing

bails’s picture

Hi I've tested the above patch on a production server and it seems not to fix the issue.

before

Tue Oct 20 14:09:37 2009] [error] [client 192.168.1.1] PHP Fatal error: Cannot unset string offsets in foobar/drupal-6.14/sites/all/modules/image/contrib/image_attach/image_attach.module on line 343

after

[Tue Oct 20 14:55:09 2009] [error] [client 192.168.1.1] PHP Fatal error: Cannot unset string offsets in foobar/drupal-6.14/sites/all/modules/image/contrib/image_attach/image_attach.module on line 332

So I'm left with a commented out version which does work.

joachim’s picture

Status: Needs review » Postponed (maintainer needs more info)

Gah, what is node_import doing???
If it's triggering the form submit handler, then surely it's using the form in some way and so the values should be there.

What version of node_import are you using?
And could you post a sample node that causes this problem so I can try the import myself?

sun’s picture

Status: Postponed (maintainer needs more info) » Closed (won't fix)

I can tell - with confidence - that node_import really is a mess. Hence, with a chance of 99% this bug is caused by node_import and the code in there needs to be fixed instead.

krysgeek’s picture

I was having the same problem with node_import and image_attach. I just added the conditional to test if that exists. Works great now. No more error.

I changed the following in /sites/all/modules/image/contrib/image_attach.module

(Image Module version 6.x-1.0-beta5)

Starting Line 396

/**
 * Extra submit handler for node forms.
 */
function image_attach_node_form_submit(&$form, &$form_state) {
  // Clear the 0 key in the iids array that arises from selecting the 'None' 
  // option. We do this here so image_attach_nodeapi() gets clean data.
    unset($form_state['values']['iids'][0]);
 }

To

/**
 * Extra submit handler for node forms.
 */
function image_attach_node_form_submit(&$form, &$form_state) {
  // Clear the 0 key in the iids array that arises from selecting the 'None' 
  // option. We do this here so image_attach_nodeapi() gets clean data.
  if ($form_state['values']['iids'][0]) {
    unset($form_state['values']['iids'][0]);
  }
}
joachim’s picture

I'm not going to make that changed because node_import should be calling node_save, not pretending to submit the form. That cleaning up of the 0 key has already been moved from the save hook to the form submit, which is where it belongs.

krysgeek’s picture

I didn't like having to make the change either, but I do like that node_import is finally working. I kept getting the PHP fatal error of this file at line 402.

Do you see a problem going with the change?

joachim’s picture

Node import should be Doing the Right Thing and either not pretending to submit a form, or pretending to submit it properly!

sphopkins’s picture

I agree that Node Import should do the right thing but I think that the maintainer has disappeared and there has been no activity in a long time by him... for a very useful module.

joachim’s picture

You can request to take over a project that's been abandoned -- there's a page all about it in the handbooks :)

sphopkins’s picture

If I had the skillz I would... I am a user for sure, not a coder. I may look to get someone that is a coder to look at the module!

jriedel’s picture

I just ran into this same issue, but I don't have node_import on this site.

It happened when a user tried to edit a forum post. Edit as admin didn't triger the problem.

I applied the fix in 18 and now things are working.

Any ideas on how to track down what other module is not playing well with others?

joachim’s picture

> Any ideas on how to track down what other module is not playing well with others?

Try it on a fresh site and then add modules. Or disable modules on your current site.

I can't tell any more -- did the patch above go in or not?

joachim’s picture

Status: Closed (won't fix) » Active

No sign of 589428 in the codebase.

@jriedel : do your users have the permission to attach images themselves?

jriedel’s picture

@joachim

I put that change in #18 and that fixed the issue. Yes, my users can attach images.

natali’s picture

Hello,
I have the same error "Fatal error: Cannot unset string offsets in /udata/WWW/test_zoi.utia.cas.cz/sites/all/modules/image/contrib/image_attach/image_attach.module on line 343".
Module Image Import is not enabled.
I got this error while tried to create a node programmatically. Node can have image attached, but i'm attaching none.
I tried to use patch, but in my file image_attach.module is not function image_attach_node_form_submit present.
My file version is image_attach.module,v 1.66 2009/09/08.
My user have permition to attach images.
Thanks for help.

joachim’s picture

Status: Active » Postponed (maintainer needs more info)

Could you give more detail about how you're trying to create a node programmatically?

natali’s picture

Here is code, for testing i run it from body of node:

     <?php
        $form_state = array();
        module_load_include('inc', 'node', 'node.pages');  
        $nodeTmp = array('type' => 'clovek'); 
       
        $form_state['values']['type'] = 'clovek'; 
        $form_state['values']['status'] = '1'; 
        $form_state['values']['title'] = "title"; 
        $form_state['values']['body'] = "body";
        $form_state['values']['name'] = 'username'; 
        $form_state['values']['op'] = t('Save');  

        // CCK fields and taxonomy 
        $form_state['values']['taxonomy'][1][0] = '5';
        $form_state['values']['field_foto_verejna']['value'] = "Ano";
        $form_state['values']['field_seznam']['value'] = "Ano";
        $form_state['values']['field_doktorand']['value'] = "Ne";
        $form_state['values']['field_aktivn']['value'] = "Ano";
        $form_state['values']['field_vedecky_pracovnik']['value'] = "Ano";
        $form_state['values']['field_oddlen']['value'][0] = "ZOI";
          
        $errs = drupal_execute('clovek_node_form', $form_state, (object) $nodeTmp);
        
        if (count($errs)) {
          echo "Person has NOT been created";
        }
        else{
          echo "Person has been created. Hurej!!!";
        }
    ?>
joachim’s picture

Yeah, that's wrong. Don't pretend to be a form -- or if you must, put in the values that the code expects; in other words, the ['iids'] key.

Better still, build your node object and do node_save().

natali’s picture

Thank you for your quick response and advise :-)
i was trying to use node_save

<?php
$node = array(
  'title' => $title,
  'uid' => $uid,
  'body' => $body,
  'promote' => 0,
);

if ($node = node_submit($node)) {
  node_save($node);
}
?>

but i found somewhere here http://drupal.org/node/178506 , it is working only for drupal 5 (it work fine for 5, but not for 6)
and i use drupal 6 example from same site.
Do you have another example for drupal 6 I can use?

natali’s picture

My solution is to add

$form_state['values']['iids'] = array();

Thanks again for help!

damienmckenna’s picture

Version: 6.x-1.0-beta3 » 6.x-1.x-dev
Status: Postponed (maintainer needs more info) » Needs review
StatusFileSize
new668 bytes

+1 for the fix in #18. Here it is in patch format.

Status: Needs review » Needs work

The last submitted patch, image-n589428-35.patch, failed testing.

damienmckenna’s picture

Status: Needs work » Needs review

#35: image-n589428-35.patch queued for re-testing.

damienmckenna’s picture

Could someone please just commit the patch from #35 so this bug is fixed? The error is still happening in v6.x-1.1.

joachim’s picture

I need to look into this more, but my gut feeling is that it's Node Import's problem.

damienmckenna’s picture

@joachim: Whatever the root problem, it should not be trying to unset a variable if it doesn't exist.

sun’s picture

@DamienMcKenna: The variable does exist. And unsetting a non-existing array key also does not trigger a fatal error.

The fatal error is caused by Node Import passing a completely invalid variable having a different data type (not an array).

Is there a patch for Node Import already? I have commit access.

damienmckenna’s picture

In my case I'm not using node_import, I'm making the following adjustment via hook_form_alter() based on certain conditions (only show the fields if the date on a CCK Date field has already elapsed):

$form['image_attach']['#access'] = FALSE;

With this line in place, when image_attach_node_form_submit() executes the $form['values']['iids'] value shows up as a string - I don't know why it becomes a string, that's just what it ends up as.

longwave’s picture

Also seeing this "cannot unset string offsets" error - this is on a live site and currently I can't debug it easily but Node Import is not installed.

joachim’s picture

Title: clean up form data in submit handler, not hook_nodeapi -- produces PHP Fatal Error with Node_Import » clean up form data in submit handler, not hook_nodeapi -- produces PHP Fatal Error

Updating the title.

jwilson3’s picture

I've marked #1871218: Cannot unset string offsets in image_attach.module on line 457 as a duplicate of this.

I've also rerolled patch in #35 to use the new git patch format (#35 still applies, but there was also a 60 line offset that is now fixed).

joachim’s picture

Status: Needs review » Fixed

Committed. Thanks everyone!

I'm going to check a few other patches needing review and then make a release soon.

  • joachim committed dfde443 on 6.x-1.x authored by jwilson3
    Issue #589428 by joachim, DamienMcKenna, jwilson3: Fixed fatal error...

Status: Fixed » Closed (fixed)

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