phpdrupaldrupal-7

Drupal How to fix notice unserialize() and Undefined index?


I am getting below mention notice on /admin/reports/status page.

  1. Notice: unserialize(): Error at offset 0 of 728 bytes in field_read_fields() (line 374 of /my_website/modules/field/field.crud.inc).
  2. Notice: Undefined index: settings in text_field_schema() (line 17 of /my_website/modules/field/modules/text/text.install).

How to fix the notice?


Solution

  • The function unserialize() fails to convert a serialized value back into a PHP value because of an invalid length (or a length mismatch) in the stored representation of the data.

    This means that a field record was not stored correctly in its field table.

    The second notice tells us the type of the incriminated field : text_field_schema(), invoked via the hook_field_schema, exposes three field types : text, text_long, text_with_summary.

    // line 392 of modules/field/field.crud.inc
    $schema = (array) module_invoke($field['module'], 'field_schema', $field);
    

    Just above, line 388, you got this :

    module_invoke_all('field_read_field', $field);
    

    By implementing this hook you should be able to point out which record is broken :

    function yourmodule_field_read_field($field) {
      if ($field['module'] === 'text' && !isset($field['settings'])) {
        dpm($field);
      }
    }
    

    Once identified, you will probably have to "repair" the field structure before saving it as usual via FieldAPI, e.g. :

    $field += array(
      'settings' => array(
        'max_length' => $somelength
      )
    );
    field_update_field($field);
    

    The structure should be as defined in field_create_field().


    [EDIT]

    If you can't use field API, still you should be able to see which record is broken for that field.

    Call field_read_field($field_name) and debug :

    // line 370 of modules/field/field.crud.inc
    $fields = array();
    $results = $query->execute();
    foreach ($results as $record) {
      dpm($record); // check $record['data']
      $field = unserialize($record['data']); 
      // ...
    }
    

    The broken record should be printed just before the first notice (if you display it).

    Check the serialized value ($record['data']), and compare it with other records to see what's wrong. In the end you may have to update the field using SQL statements if you can't use field API.