I found a bug. It only outputs a PHP notice but it could be avoided with an if statement methinks...

Steps to reproduce:

  1. Install module
  2. enable module
  3. configure module
  4. under Node, click 'Add new view mode'
  5. Label > 'Teaser 2'
  6. leave 'Use custom display settings' checked.
  7. uncheck all but content type, 'Art Gallery'
  8. click save.
  9. error displayed: Notice: Undefined index: teaser_2 in field_entity_view_mode_update() (line 179 of /srv/www/.../.../all/modules/entity_view_mode/entity_view_mode.module).

There's also a similar error on delete of a view mode:

Notice: Undefined index: machine_name in field_entity_view_mode_delete() (line 204 of /home/.../all/modules/entity_view_mode/entity_view_mode.module).

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

RobW’s picture

I get this too, but only on creation of a new view mode. One refresh and it's gone. Maybe a race condition?

RobW’s picture

Title: Undefined index notice » Undefined index notice on Save and Delete of view mode.

There's also a similar error on delete of a view mode:

Notice: Undefined index: machine_name in field_entity_view_mode_delete() (line 204 of /home/.../all/modules/entity_view_mode/entity_view_mode.module).

Added to the issue description.

anandkp’s picture

Thanks and Kudos!!!

Many thanks to Dave Reid for making this module. Being able to add View Modes easily without hand-coding it makes life A LOT easier. I'm using the module to allow for simple, semantic and Drupally customisation of formats using View Modes for the following modules: Field Collections, Media (and through it the File entities) and Panels.

I'm really sorry that I still haven't learned how to make patch files. I'm uploading my version of entity_view_mode/entity_view_mode.module and citing the old/new code below as well.

Notice On Save

Perceived Cause

I believe that the fact that the View Mode is new was not being carried forward to field_entity_view_mode_update() - which is called by both hook_entity_view_mode_insert() as well as hook_entity_view_mode_update() - was causing this problem. After saving the View Mode (new or old - save or update), the module produces a helper message that tries to get the $label of the View Mode for use in the message.

By updating the both hooks - hook_entity_view_mode_insert and hook_entity_view_mode_update - so that they provide an additional argument, $is_new (which is set before they're invoked in entity_view_mode_save()), the boolean can be used to decide where the label is supposed to come from.

Suggested code follows:

ORIGINAL CODE

/**
 * Save a custom entity view mode.
 */
function entity_view_mode_save($entity_type, $view_mode) {
  $existing_view_mode = !empty($view_mode['old_machine_name']) ? $view_mode['old_machine_name'] : $view_mode['machine_name'];
  $view_mode_name = $view_mode['machine_name'];

  // Load the original, unchanged view mode, if it exists.
  if ($original = entity_view_mode_load($entity_type, $existing_view_mode)) {
    $view_mode['original'] = $original + array('machine_name' => $existing_view_mode);
    unset($view_mode['old_machine_name']);
  }

  // The key value for custom settings needs to be converted from
  // 'custom_settings' to 'custom settings' before saving.
  if (isset($view_mode['custom_settings'])) {
    $view_mode['custom settings'] = $view_mode['custom_settings'];
    unset($view_mode['custom_settings']);
  }

  // Determine if we will be inserting a new view mode.
  if (!isset($view_mode['is_new'])) {
    $view_mode['is_new'] = !empty($view_mode['original']);
  }

  // Let modules modify the view mode before it is saved.
  module_invoke_all('entity_view_mode_presave', $view_mode, $entity_type);

  // Save the view mode.
  $view_modes = variable_get('entity_view_modes', array());
  unset($view_modes[$entity_type][$existing_view_mode]);
  $view_modes[$entity_type][$view_mode_name] = array_intersect_key($view_mode, drupal_map_assoc(array('label', 'custom settings')));
  $view_modes[$entity_type][$view_mode_name] += array('custom settings' => TRUE);
  variable_set('entity_view_modes', $view_modes);

  // Allow modules to respond after the view mode is saved.
  if ($view_mode['is_new']) {
    module_invoke_all('entity_view_mode_insert', $view_mode, $entity_type);
  }
  else {
    module_invoke_all('entity_view_mode_update', $view_mode, $entity_type);
  }

  // Clear internal properties.
  unset($view_mode['original']);
  unset($view_mode['is_new']);

  // Clear the static entity info cache and rebuild the menu.
  entity_info_cache_clear();
  variable_set('menu_rebuild_needed', TRUE);
}

UPDATED CODE

/**
 * Save a custom entity view mode.
 */
function entity_view_mode_save($entity_type, $view_mode) {
  $view_mode_machine_name = !empty($view_mode['old_machine_name']) ? $view_mode['old_machine_name'] : $view_mode['machine_name'];
  $view_mode_name         = $view_mode['machine_name'];

  // Load the original, unchanged view mode, if it exists.
  if($original = entity_view_mode_load($entity_type, $view_mode_machine_name)) {
    $view_mode['original'] = $original + array('machine_name' => $view_mode_machine_name);
    unset($view_mode['old_machine_name']);
  }

  // The key value for custom settings needs to be converted from
  // 'custom_settings' to 'custom settings' before saving.
  if(isset($view_mode['custom_settings'])) {
    $view_mode['custom settings'] = $view_mode['custom_settings'];
    unset($view_mode['custom_settings']);
  }

  // Determine if we will be inserting a new view mode.
  if(!isset($view_mode['is_new'])) {
    $view_mode['is_new'] = !isset($view_mode['original']) ? TRUE : FALSE;
    $is_new              = $view_mode['is_new'];
  }

  // Let modules modify the view mode before it is saved.
  module_invoke_all('entity_view_mode_presave', $view_mode, $entity_type);

  // Retrieve View Modes from variables table.
  $view_modes = variable_get('entity_view_modes', array());

  // Check if the view mode was already there (meaning this is an update not save) and if so, unset it.
  if(isset($view_modes[$entity_type][$view_mode_machine_name])) {
    unset($view_modes[$entity_type][$view_mode_machine_name]);
  }

  // Prepare the new View Mode settings array for saving, merging values provided by modules implementing hook_entity_view_mode_presave()
  $view_modes[$entity_type][$view_mode_name] = array_intersect_key($view_mode, drupal_map_assoc(array('label', 'custom settings')));
  // Update the View Mode settings array with necessary values.
  $view_modes[$entity_type][$view_mode_name] += array('custom settings' => TRUE);
  $view_modes[$entity_type][$view_mode_name] += array('machine_name'    => $view_mode_machine_name);
  variable_set('entity_view_modes', $view_modes);

  // Allow modules to respond after the view mode is saved.
  if($view_mode['is_new']) {
    module_invoke_all('entity_view_mode_insert', $view_mode, $entity_type, $is_new);
  } else {
    module_invoke_all('entity_view_mode_update', $view_mode, $entity_type, $is_new);
  }

  // Clear internal properties.
  unset($view_mode['original']);
  unset($view_mode['is_new']);

  // Clear the static entity info cache and rebuild the menu.
  entity_info_cache_clear();
  variable_set('menu_rebuild_needed', TRUE);
}

ORIGINAL CODE

/**
 * Implements hook_entity_view_mode_insert() on behalf of core field module.
 */
function field_entity_view_mode_insert($view_mode, $entity_type) {
  field_entity_view_mode_update($view_mode, $entity_type);
}

/**
 * Implements hook_entity_view_mode_update() on behalf of core field module.
 */
function field_entity_view_mode_update($view_mode, $entity_type) {
  module_load_include('inc', 'field_ui', 'field_ui.admin');
  $entity_info = entity_get_info($entity_type);
  $view_mode_name = $view_mode['machine_name'];

  // If custom settings is set to false, then we should be disabling this view
  // view mode for all bundles.
  //if (empty($view_mode['custom settings'])) {
  //  $view_mode['enabled_bundles'] = array_fill_keys(array_keys($entity_info['bundles']), 0);
  //}

  if (!empty($view_mode['enabled_bundles'])) {
    foreach ($view_mode['enabled_bundles'] as $bundle => $value) {
      $bundle_settings = field_bundle_settings($entity_type, $bundle);

      // Display a message for each view mode newly configured to use custom
      // settings.
      $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
      if (!empty($value) && empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
        $view_mode_label = $entity_info['view modes'][$view_mode_name]['label'];
        $path = _field_ui_bundle_admin_path($entity_type, $bundle) . "/display/$view_mode_name";
        drupal_set_message(t('The %view_mode @entity_type @bundle view mode now uses custom display settings. You might want to <a href="@url" target="_new">configure them</a>.', array(
          '%view_mode' => $view_mode_label,
          '@entity_type' => $entity_info['label'],
          '@bundle' => $entity_info['bundles'][$bundle]['label'],
          '@url' => url($path),
        )));
        // Initialize the newly customized view mode with the display settings
        // from the default view mode.
        _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode_name, $bundle_settings);
      }

      // Save updated bundle settings.
      $bundle_settings['view_modes'][$view_mode_name]['custom_settings'] = !empty($value);
      field_bundle_settings($entity_type, $bundle, $bundle_settings);
    }
  }
}

UPDATED CODE

/**
 * Implements hook_entity_view_mode_insert() on behalf of core field module.
 */
function field_entity_view_mode_insert($view_mode, $entity_type, $is_new) {
  field_entity_view_mode_update($view_mode, $entity_type, $is_new);
}

/**
 * Implements hook_entity_view_mode_update() on behalf of core field module.
 */
function field_entity_view_mode_update($view_mode, $entity_type, $is_new) {
  module_load_include('inc', 'field_ui', 'field_ui.admin');
  $entity_info    = entity_get_info($entity_type);
  $view_mode_name = $view_mode['machine_name'];

  // If custom settings is set to false, then we should be disabling this view
  // view mode for all bundles.
  /*if (empty($view_mode['custom settings'])) {
    $view_mode['enabled_bundles'] = array_fill_keys(array_keys($entity_info['bundles']), 0);
  }*/
  if(!empty($view_mode['enabled_bundles'])) {
    foreach($view_mode['enabled_bundles'] as $bundle => $bundle_name) {
      $bundle_settings = field_bundle_settings($entity_type, $bundle);

      // Display a message for each view mode newly configured to use custom settings.
      $view_mode_settings = field_view_mode_settings($entity_type, $bundle);
      if(!empty($bundle_name) && empty($view_mode_settings[$view_mode_name]['custom_settings'])) {
        $view_mode_label = ($is_new) ? $view_mode['label'] : $entity_info['view modes'][$view_mode_name]['label'];
        $path            = _field_ui_bundle_admin_path($entity_type, $bundle) . "/display/$view_mode_name";
        drupal_set_message(t('The %view_mode @entity_type @bundle view mode now uses custom display settings. You might want to <a href="@url" target="_new">configure them</a>.', array(
          '%view_mode'   => $view_mode_label,
          '@entity_type' => $entity_info['label'],
          '@bundle'      => $entity_info['bundles'][$bundle]['label'],
          '@url'         => url($path),
        )));
        // Initialize the newly customized view mode with the display settings from the default view mode.
        _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode_name, $bundle_settings);
      }

      // Save updated bundle settings.
      $bundle_settings['view_modes'][$view_mode_name]['custom_settings'] = !empty($bundle_name);
      field_bundle_settings($entity_type, $bundle, $bundle_settings);
    }
  }
}

Notice on Delete View Mode

Perceived Cause

I think that the notices mentioned above are due to the non-existence of the "machine_name" array key in the $view_mode variable as it is passed to both field_entity_view_mode_update()and field_entity_view_mode_delete().

The PHP Notices went away when I updated entity_view_mode_load() as follows:

ORIGINAL CODE

/**
 * Load a custom entity view mode by entity type and machine name.
 */
function entity_view_mode_load($entity_type, $machine_name) {
  $view_modes = variable_get('entity_view_modes', array());
  return !empty($view_modes[$entity_type][$machine_name]) ? $view_modes[$entity_type][$machine_name] : FALSE;
}

UPDATED CODE

/**
 * Load a custom entity view mode by entity type and machine name.
 */
function entity_view_mode_load($entity_type, $machine_name) {
  // retrieve all Viewmodes
  $view_modes = variable_get('entity_view_modes', array());
  // convenience assignment of the requested Entity's requested View Mode
  $current_view_mode =& $view_modes[$entity_type][$machine_name];
  // checks to ensure that information was found
  if($current_view_mode && is_array($current_view_mode)) {
    // both hook_entity_view_mode_update & hook_entity_view_mode_delete
    // expect that the returned value have the machine_name as one of the array keys
    $current_view_mode['machine_name'] = $machine_name;
  }
  return !empty($view_modes[$entity_type][$machine_name]) ? $view_modes[$entity_type][$machine_name] : FALSE;
}

One other tiny fix was needed...

I found a variable-name typo in field_entity_view_mode_delete()... $bundle_settings is spelled as $bundles_settings on the line just below it:

ORIGINAL CODE

/**
 * Implements hook_entity_view_mode_delete() on behalf of core field module.
 */
function field_entity_view_mode_delete($view_mode, $entity_type) {
  $entity_info = entity_get_info($entity_type);
  $view_mode_name = $view_mode['machine_name'];

  foreach (array_keys($entity_info['bundles']) as $bundle) {
    // Remove bundle settings for the view mode.
    $bundle_settings = field_bundle_settings($entity_type, $bundle);
    if (isset($bundle_settings['view_modes'][$view_mode_name])) {
      unset($bundles_settings['view_modes'][$view_mode_name]);
      field_bundle_settings($entity_type, $bundle, $bundle_settings);
    }

    // @todo Delete view mode settings in field instances?
  }
}

UPDATED CODE

/**
 * Implements hook_entity_view_mode_delete() on behalf of core field module.
 */
function field_entity_view_mode_delete($view_mode, $entity_type) {
  $entity_info = entity_get_info($entity_type);
  $view_mode_name = $view_mode['machine_name'];

  foreach (array_keys($entity_info['bundles']) as $bundle) {
    // Remove bundle settings for the view mode.
    $bundle_settings = field_bundle_settings($entity_type, $bundle);
    if (isset($bundle_settings['view_modes'][$view_mode_name])) {
      // SPELLING FIX - $bundles_settings to $bundle_settings
      unset($bundle_settings['view_modes'][$view_mode_name]);
      field_bundle_settings($entity_type, $bundle, $bundle_settings);
    }

    // @todo Delete view mode settings in field instances?
  }
}
anandkp’s picture

FileSize
2.94 KB

Sorry, forgot to attach the file in my post above... Here's the modified file:

entity_view_mode.module

anandkp’s picture

Status: Active » Needs review

Also forgot to update the Status of the issue... Sorry!

RobW’s picture

anandps, awesome post and summary. You have the skills to make a patch, for sure! Check out http://drupal.org/node/707484 next time you have an hour to bring your game to the next level.

In the meantime, here's a patch of your changes:

[edit] There are a bunch of changes in there that are just whitespace removal, not in alignment with Drupal coding standards. That makes it harder to review. Something to think about for next time.

anandkp’s picture

Hey there RobW!

Thank you very much for the link, I'll be reading that asap!

Regarding the whitespaces, I use PHPStorm as my IDE and have been trying to make it more Drupal-friendly. I've heard about a module that does a code check for you... a colleague at work had mentioned it once upon a time. I'll be sure to look that up and get my IDE into line!

(If the whitespaces were bad, I guess I shouldn't tell you that I used to use the tab character... :-O )

Once again, thanks for the input!

Dave Reid’s picture

Status: Needs review » Needs work

There is a lot of unrelated whitespace changes, I cannot commit this patch as is and makes this much harder to review.

ShaunDychko’s picture

I have updated the patch to show only non-trivial changes. Unfortunately, this introduces a new error message.

When adding a new view mode for files, if you deselect Images, Documents, and Audio, leaving only Video selected, you will get the error message:

Notice: Undefined index: default in _field_ui_add_default_view_mode_settings() (line 1429 of .../modules/field_ui/field_ui.admin.inc).

The error message does not appear if you leave all media types selected.

Should we open a new issue for this?

hargobind’s picture

@anandps, great job on these edits, and thank you @ShaunDychko for creating a clean patch. I've tested and verify that it is working.

A little bit of cleanup needs to be done in the merged file -- the capitalization of some of the new comments, spacing fixes on line 113 ($is_new =...) and 131 (array('machine_name'...), and the TRUE/FALSE values at the end of line 112 are unnecessary since isset() returns boolean.

Apart from these little details, I think the patch in #9 is good to go to address the original issue.

The issue that Shaun brought up about view modes for files isn't specific to the original topic, but perhaps @DaveReid can make the decision about whether to open a new issue for it.

rooby’s picture

I can confirm that the patch in #9 fixes the bug in the original post.

However I can also confirm the new bug:

Notice: Undefined index: default in _field_ui_add_default_view_mode_settings() (line 1429 of /var/www/mysite/modules/field_ui/field_ui.admin.inc).

Which happens whenever you create a view mode for the file entity.
(I am using file_entity 7.x-2.x-dev as of today).

All other entity types I have tried seem ok (user, node, comment, taxonomy, bean).

Here are some nit-picky code reviews (I have not done a technical review).

+++ b/entity_view_mode.module
@@ -74,7 +74,16 @@ function entity_view_mode_menu() {
+  // retrieve all Viewmodes
   $view_modes = variable_get('entity_view_modes', array());
+  // convenience assignment of the requested Entity's requested View Mode
+  $current_view_mode =& $view_modes[$entity_type][$machine_name];
+  // checks to ensure that information was found
+  if ($current_view_mode && is_array($current_view_mode)) {
+    // both hook_entity_view_mode_update & hook_entity_view_mode_delete
+    // expect that the returned value have the machine_name as one of the array keys
+    $current_view_mode['machine_name'] = $machine_name;

Comments should be in sentance case and have full stops.

Lines should also should not be longer than 80 characters.

+++ b/entity_view_mode.module
@@ -100,25 +109,34 @@ function entity_view_mode_save($entity_type, $view_mode) {
+
+  // Check if the view mode was already there (meaning this is an update not save) and if so, unset it.
+  if (isset($view_modes[$entity_type][$view_mode_machine_name])) {
...
+
+  // Prepare the new View Mode settings array for saving, merging values provided by modules implementing hook_entity_view_mode_presave()
   $view_modes[$entity_type][$view_mode_name] = array_intersect_key($view_mode, drupal_map_assoc(array('label', 'custom settings')));

Comment lines should not be longer than 80 characters and end with full stops.

+++ b/entity_view_mode.module
@@ -184,13 +202,12 @@ function field_entity_view_mode_update($view_mode, $entity_type) {
-        // Initialize the newly customized view mode with the display settings
-        // from the default view mode.
+        // Initialize the newly customized view mode with the display settings from the default view mode.
         _field_ui_add_default_view_mode_settings($entity_type, $bundle, $view_mode_name, $bundle_settings);

This is unnecessary and breaks the 80 character comment line rule.

kaizerking’s picture

The test_view_mode Node test_node view mode now uses custom display settings. You might want to configure them. clicking on the configure them redirects to a new page.
it should be on the same page

Dave Reid’s picture

Version: 7.x-1.0-beta3 » 7.x-1.x-dev
Status: Needs work » Needs review
FileSize
1.49 KB

I'm not seeing a whole lot why the patch in #9 is necessary. It looks like this can be fixed with just a few small things?

Dave Reid’s picture

Status: Needs review » Fixed

These PHP notices were fixed with #1900686: Write functional tests. I credited people in this issue with that issues' commit message. Marking as fixed.

Status: Fixed » Closed (fixed)

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

Summit’s picture

Status: Closed (fixed) » Active

Hi, sorry to possible open this closed issue, but using entity_view_mode and DS together I got these errors;

Notice: Undefined index: #bundle in ds_contextual_links_view_alter() (line 1301 of /sites/all/modules/ds/ds.module).
Notice: Undefined index: in _field_ui_bundle_admin_path() (line 325 of /modules/field_ui/field_ui.module).

I think they are related with this issue right? Otherwise sorry for reopening issue.
i use latest .dev

greetings, Martijn

Dave Reid’s picture

Status: Active » Closed (fixed)

I would file an issue in display suite first. None of those errors lead me to believe it's a bug caused by entity_view_mode. But if they can track it down further and trace it back I'd be happy to have a look.

rajmataj’s picture

Version: 7.x-1.x-dev » 7.x-1.0-rc1
Priority: Minor » Normal
Status: Closed (fixed) » Active

I am getting this error after recently installing entity_view_mode 7.x-1.0-rc1 on a Drupal 7.23 site. I was attempted to create a new view mode for the Media module, to have a custom image size. Note, I do not have Display Suite installed.

Notice: Undefined index: default in _field_ui_add_default_view_mode_settings() (line 1429 of /[...]/[...]/[...]/modules/field_ui/field_ui.admin.inc).

bkosborne’s picture

Also received this notice after creating a new view mode. Do not have Display Suite enabled. Noteable modules that I do have enabled are Media (7.x-2.0-alpha2) and File Entity (7.x-2.0-alpha2)

bkosborne’s picture

Issue summary: View changes

updated with on delete error

Jason2014’s picture

Issue summary: View changes

I am having the same issue. I also have the Media 7.x-1.4 and File Entity 7.x-1.4 modules installed. I installed entity_view_mode 7.x-1.0-rc1. Im on a Drupal 7.26 site. When I created a new view. I received the same message:

Notice: Undefined index: default in _field_ui_add_default_view_mode_settings() (line 1429 of /home/xxxxx/public_html/modules/field_ui/field_ui.admin.inc).