Hi,

When visiting my admin/content/<entity>/% path, I get a E_WARNING level error, along with a WSOD because the function entity_ui_entity_page_view() cannot be found.
I am using the new EntityBundleableUIController controller class in my hook_entity_info implementation. Here is my 'admin ui' snippet:

    'admin ui' => array(
      'path' => 'admin/content/benchmark',
      'file' => 'benchmark.admin.inc',
      // Use a general wildcard loader, instead of a per-bundle one.
      'menu wildcard' => '%benchmark',
      // EntityDefaultUIController
      'controller class' => 'EntityBundleableUIController',
    ),

and here is the error message:
call_user_func_array() expects parameter 1 to be a valid callback, function 'entity_ui_entity_page_view' not found or invalid function name

What does this mean? Does it mean that when using EntityBundleableUIController (which is very nice btw, thanks!) we have to extend the UI Controller class in order to implement our own entity_ui_entity_page_view()? If I commented out the file parameter, then Entity API is not able to find the entity forms (i.e., benchmark_form). I don't know if this is a bug or if I'm missing some parameter that goes along the new UI Controller on the hook entity info.

Thank you.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Alexander Allen’s picture

Unlike most of the menu callbacks defined in the UI controllers' hook_menu, $this->path . '/' . $wildcard on EntityContentUIController::hook_menu() does not try to figure out the 'page callback' dynamically - i.e., like entity_ui_get_form() does.

Adding 'file' and 'file path' to the menu item fixed the WSOD:

   // entity/includes/entity.ui.inc, EntityContentUIController::hook_menu
    ...  
  
    // Add view, edit and delete menu items for content entities.
    $items[$this->path . '/' . $wildcard] = array(
      'title callback' => 'entity_ui_get_page_title',
      'title arguments' => array('view', $this->entityType, $this->id_count),
      'page callback' => 'entity_ui_entity_page_view',
      'page arguments' => array($this->id_count),
      'load arguments' => array($this->entityType),
      'access callback' => 'entity_access',
      'access arguments' => array('view', $this->entityType, $this->id_count),
      'file' => 'entity.ui.inc',
      'file path' => 'sites/all/modules/contrib/entity/includes',
    ) + $defaults;
    ...

After clearing the caches and verifying the menu_router table, entity_ui_entity_page_view() is the only callback pointing to sites/all/modules/contrib/entity/includes/entity.ui.inc, which would be the expected effect:

// SELECT path, page_callback, include_file FROM  menu_router;

admin/content/benchmark/%	entity_ui_entity_page_view	sites/all/modules/contrib/entity/includes/entity.ui.inc
admin/content/benchmark/%/delete	drupal_get_form	sites/all/modules/code_review/complexity/benchmark.admin.inc
admin/content/benchmark/%/edit	entity_ui_get_form	sites/all/modules/code_review/complexity/benchmark.admin.inc
admin/content/benchmark/%/view	entity_ui_entity_page_view	sites/all/modules/code_review/complexity/benchmark.admin.inc
admin/content/benchmark/add	entity_ui_bundle_add_page	sites/all/modules/code_review/complexity/benchmark.admin.inc
admin/content/benchmark/add/%	entity_ui_get_bundle_add_form	sites/all/modules/code_review/complexity/benchmark.admin.inc
admin/content/benchmark/list	drupal_get_form	modules/node/node.admin.inc

On the negative side, this solution may feel too hardcoded to me (when compared to entity_ui_get_form)...
On the plus side however, the developer implementing an entity can still override the ::view() method on his current entity controller:

  // entity/includes/entity.ui.inc, Entity::view

  /**
   * Override this method on your controller if needed...
   * Generate an array for rendering the entity.
   *
   * @see entity_view()
   */
  public function view($view_mode = 'full', $langcode = NULL, $page = NULL) {
    return entity_get_controller($this->entityType)->view(array($this), $view_mode, $langcode, $page);
  }

I'm pretty sure there's better ways to do this, but at least for now that's what I did to solve this issue.

Alexander Allen’s picture

Now that I've posted a temporary fix for myself, just thinking out loud - why can Drupal find entity_ui_get_form() without any issues, but it cannot find entity_ui_entity_page_view() ?

...
UPDATE: Answering myself: functions such as entity_ui_bundle_add_page() and entity_ui_get_form() - which are the ones used by the other default ::hook_menu() items - reside in entity.module. The functions there are available to other modules.

entity_ui_entity_page_view() on the other hand resides in entity.ui.inc, which is not automatically loaded - hence why I get the WSOD. Both entity_ui_get_form() and entity_ui_bundle_add_page() do a form_load_include($form_state, 'inc', 'entity', 'includes/entity.ui'), which is why they work - even when the 'file' parameter in the custom entity's 'admin ui' property and database menu router items point to the entity's *.admin.inc include file.

If entity_ui_entity_page_view() is moved to entity.module, this issue should be fixed.

Alexander Allen’s picture

Status: Active » Needs review
FileSize
3.13 KB

Attached patch for comment #2 -

Moved entity_ui_entity_page_view() and entity_ui_get_page_title() to entity.module. Added a module_load_include() to both functions. Hope this works :)

Status: Needs review » Needs work

The last submitted patch, issue-2076393_comment-7804087-2.patch, failed testing.

Alexander Allen’s picture

Submitted the last patch using an absolute path, using relative now.

Alexander Allen’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, issue-2076393_comment-7804087-3.patch, failed testing.

Alexander Allen’s picture

Status: Needs work » Needs review
FileSize
3.06 KB

Looks like a missing line at the end may cause the patch to fail.

Alexander Allen’s picture

Added patch metadata. Let me know if you want me to do something else.

Thanks

Alexander Allen’s picture

FYI,

Screenshot of a test on a admin/content/[entityType]/% path path.

I didn't see any notices on watchdog.

fago’s picture

Title: Function 'entity_ui_entity_page_view' not found » Function 'entity_ui_entity_page_view' not found when EntityBundleableUIController is used
Status: Needs review » Fixed

Indeed - thanks for figuring this out. It was working for the while module only coincidentally (the while module specifieds a custom UI include file which triggers loading of entity.ui.inc via class auto-loading).

Committed.

Status: Fixed » Closed (fixed)

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

Anonymous’s picture

Issue summary: View changes

Add step to reproduce error.