You are here

panelizer.module in Panelizer 7.2

The Panelizer module attaches panels to entities, providing default panels and allowing each panel to be configured independently by privileged users.

File

panelizer.module
View source
<?php

/**
 * @file
 * The Panelizer module attaches panels to entities, providing default
 * panels and allowing each panel to be configured independently by
 * privileged users.
 */

// -----------------------------------------------------------------------
// Drupal core hooks

/**
 * Implements hook_permission().
 */
function panelizer_permission() {
  $items = array(
    'administer panelizer' => array(
      'title' => t('administer panelizer'),
      'description' => t('Fully administer panelizer and all panelizer settings.'),
    ),
  );

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('permission') as $handler) {
    $handler
      ->hook_permission($items);
  }
  return $items;
}

/**
 * Implements hook_theme().
 */
function panelizer_theme() {
  $items = array();
  $items['panelizer_settings_page_table'] = array(
    'render element' => 'element',
    'file' => 'includes/admin.inc',
  );

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('theme') as $handler) {
    $handler
      ->hook_theme($items);
  }
  return $items;
}

/**
 * Implements hook_menu().
 */
function panelizer_menu() {
  $items = array();

  // Delegate admin menu stuff to admin.inc
  ctools_include('admin', 'panelizer');
  panelizer_admin_hook_menu($items);

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('menu') as $handler) {
    $handler
      ->hook_menu($items);
  }
  return $items;
}

/**
 * Implements hook_menu_alter().
 */
function panelizer_menu_alter(&$items) {

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('menu_alter') as $handler) {
    $handler
      ->hook_menu_alter($items);
  }
}

/**
 * Implements hook_admin_paths().
 */
function panelizer_admin_paths() {
  $items = array();

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('admin_paths') as $handler) {
    $handler
      ->hook_admin_paths($items);
  }
  return $items;
}

/**
 * Implements hook_form_alter().
 */
function panelizer_form_alter(&$form, &$form_state, $form_id) {

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('form_alter') as $handler) {
    $handler
      ->hook_form_alter($form, $form_state, $form_id);
  }
}

/**
 * Implements hook_page_alter().
 */
function panelizer_page_alter(&$page) {

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('page_alter') as $handler) {
    $handler
      ->hook_page_alter($page);
  }
}

/**
 * Implements hook_entity_load().
 */
function panelizer_entity_load(&$entities, $entity_type) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_entity_load($entities);
  }
}

/**
 * Implements hook_entity_update().
 */
function panelizer_entity_update($entity, $entity_type) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_entity_update($entity);
  }
}

/**
 * Implements hook_entity_insert().
 */
function panelizer_entity_insert($entity, $entity_type) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_entity_insert($entity);
  }
}

/**
 * Implements hook_entity_delete().
 */
function panelizer_entity_delete($entity, $entity_type) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_entity_delete($entity);
  }
}

/**
 * Implements hook_field_attach_delete_revision().
 */
function panelizer_field_attach_delete_revision($entity_type, $entity) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_field_attach_delete_revision($entity);
  }
}
function panelizer_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_field_attach_form($entity, $form, $form_state, $langcode);
  }
}
function panelizer_field_attach_submit($entity_type, $entity, &$form, &$form_state) {

  // Delegate to the handler.
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $handler
      ->hook_field_attach_submit($entity, $form, $form_state);
  }
}

// -----------------------------------------------------------------------
// Panels and CTools hooks

/**
 * Implements hook_ctools_plugin_type()
 */
function panelizer_ctools_plugin_type() {
  $items['entity'] = array(
    'cache' => FALSE,
    'process' => array(
      'function' => 'panelizer_entity_plugin_process',
    ),
    'classes' => array(
      'handler',
    ),
  );
  return $items;
}

/**
 * Implements hook_ctools_plugin_directory()
 */
function panelizer_ctools_plugin_directory($module, $plugin) {
  if (in_array($module, array(
    'panelizer',
    'ctools',
    'page_manager',
  ))) {
    return 'plugins/' . $plugin;
  }
}

/**
 * Implements hook_ctools_plugin_api().
 */
function panelizer_ctools_plugin_api($module, $api) {
  if ($module == 'page_manager' && $api == 'pages_default' || $module == 'panelizer') {
    return array(
      'version' => 1,
      'path' => drupal_get_path('module', 'panelizer') . '/includes',
    );
  }
}

/**
 * Implements hook_features_api().
 */
function panelizer_features_api() {
  $api = array();
  $api['panelizer_defaults'] = _ctools_features_get_info('panelizer_defaults');
  $api['panelizer_defaults']['alter_type'] = FEATURES_ALTER_TYPE_NONE;
  return $api;
}

/**
 * Implementation of hook_views_api().
 */
function panelizer_views_api() {
  return array(
    'api' => 2.0,
    'path' => drupal_get_path('module', 'panelizer') . '/plugins/views',
  );
}

/**
 * Implements hook_panelizer_defaults_alter().
 */
function panelizer_panelizer_defaults_alter(&$items) {

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('panelizer_defaults') as $handler) {
    $handler
      ->hook_panelizer_defaults($items);
  }
}

/**
 * Implements hook_default_page_manager_handlers().
 */
function panelizer_default_page_manager_handlers() {
  $items = array();

  // Delegate.
  foreach (panelizer_get_plugins_with_hook('default_page_manager_handlers') as $handler) {
    $handler
      ->hook_default_page_manager_handlers($items);
  }
  return $items;
}

/**
 * Implement CTools access form caching callback: get.
 */
function panelizer_ctools_access_get($argument) {
  list($entity_type, $bundle, $name) = explode(':', $argument);
  $handler = panelizer_entity_plugin_get_handler($entity_type);
  $panelizer = $handler
    ->get_default_panelizer_object($bundle, $name);
  if (empty($panelizer)) {
    return;
  }
  if (!$handler
    ->access_default_panelizer_object($panelizer)) {
    return;
  }

  // First, see if there's a cache
  ctools_include('object-cache');
  $access = ctools_object_cache_get('panelizer_access', $argument);
  if (!$access) {
    $access = $panelizer->access;
  }
  $context = $handler
    ->get_contexts($panelizer);
  return array(
    $access,
    $context,
  );
}

/**
 * Implement CTools access form caching callback: set.
 */
function panelizer_ctools_access_set($argument, $access) {
  list($entity_type, $bundle, $name) = explode(':', $argument);
  $handler = panelizer_entity_plugin_get_handler($entity_type);
  $panelizer = $handler
    ->get_default_panelizer_object($bundle, $name);
  if (empty($panelizer)) {
    return;
  }
  if (!$handler
    ->access_default_panelizer_object($panelizer)) {
    return;
  }
  ctools_include('object-cache');
  ctools_object_cache_set('panelizer_access', $argument, $access);
}

/**
 * Implement CTools access form caching callback: get.
 */
function panelizer_ctools_access_clear($argument) {
  list($entity_type, $bundle, $name) = explode(':', $argument);
  $handler = panelizer_entity_plugin_get_handler($entity_type);
  $panelizer = $handler
    ->get_default_panelizer_object($bundle, $name);
  if (empty($panelizer)) {
    return;
  }
  if (!$handler
    ->access_default_panelizer_object($panelizer)) {
    return;
  }
  ctools_include('object-cache');
  ctools_object_cache_clear('panelizer', $argument);
}

// -----------------------------------------------------------------------
// CTools entity plugin support code

/**
 * CTools process callback for an entity plugin.
 *
 * This adds configuration data to the plugin so that we know what
 * bundles it is enabled for.
 */
function panelizer_entity_plugin_process(&$plugin, $info) {
  $entity_type = $plugin['name'];
  $entity_info = entity_get_info($entity_type);
  $plugin['bundles'] = array();
  if ($entity_info) {
    foreach ($entity_info['bundles'] as $bundle => $label) {
      if ($settings = variable_get('panelizer_defaults_' . $entity_type . '_' . $bundle, array())) {
        $plugin['bundles'][$bundle] = $settings;
      }
    }
  }
  drupal_alter('panelizer_entity_plugin_process', $plugin, $info);
}

/**
 * Fetch a single entity plugin.
 */
function panelizer_get_entity_plugin($entity_type) {
  ctools_include('plugins');
  return ctools_get_plugins('panelizer', 'entity', $entity_type);
}

/**
 * Fetch all entity plugin.
 */
function panelizer_get_entity_plugins() {
  ctools_include('plugins');
  return ctools_get_plugins('panelizer', 'entity');
}

/**
 * Get the class to handle custom code for a given entity type plugin.
 *
 * If a plugin does not define a class at all, then the default class
 *
 * @return
 *   Either the instantiated handler or FALSE if one could not be had.
 */
function panelizer_entity_plugin_get_handler($plugin) {

  // The default plugin handler is abstract and cannot be loaded.
  if ($plugin == 'default') {
    return;
  }
  $cache =& drupal_static(__FUNCTION__, array());

  // If a string was passed, turn it into a plugin.
  if (is_string($plugin)) {
    $plugin = panelizer_get_entity_plugin($plugin);
    if (!$plugin) {
      return FALSE;
    }
  }

  // Get the class name from the 'handler' property if we have not already
  // cached a handler.
  if (is_object($plugin)) {
    vpr_trace();
    exit;
  }
  if (empty($cache[$plugin['name']]) && ($class = ctools_plugin_get_class($plugin, 'handler'))) {

    // @todo is there a good reason to use ->init instead of __construct?
    $cache[$plugin['name']] = new $class();
    $cache[$plugin['name']]
      ->init($plugin);
  }
  return !empty($cache[$plugin['name']]) ? $cache[$plugin['name']] : FALSE;
}

/**
 * Load handler to get a plugin as a menu callback.
 */
function panelizer_handler_load($entity_type) {
  return panelizer_entity_plugin_get_handler($entity_type);
}

/**
 * Fetch handler objects for all plugins that implement the named hook.
 *
 * These plugins must set $plugin['hooks'][$hook] = TRUE in order to
 * be instantiated.
 *
 * This is only called for system wide hooks such as hook_menu and
 * hook_menu_alter; entity specific hooks will always be called.
 */
function panelizer_get_plugins_with_hook($hook) {
  $objects = array();
  $plugins = panelizer_get_entity_plugins();
  foreach ($plugins as $entity_type => $plugin) {
    if (!empty($plugin['hooks'][$hook])) {
      if ($handler = panelizer_entity_plugin_get_handler($plugin)) {
        $objects[$entity_type] = $handler;
      }
    }
  }
  return $objects;
}

/**
 * Page callback for entity menu callbacks.
 *
 * This function is to be used as a menu callback for menu items that
 * are to be handled by a method on the handler object. It loads the object
 * defined in the plugin and hands it off to a method based upon the name
 * of the operation in use.
 *
 * For example, if the 'op' is 'revision' then the callback method will be
 * 'page_revisions', with all of the arguments *except* the $op and the
 * plugin name.
 */
function panelizer_entity_plugin_switcher_page($entity_type, $op) {
  $args = func_get_args();
  $js = !empty($_REQUEST['js']);

  // Load the $plugin information
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $method = 'page_' . $op;
    if (method_exists($handler, $method)) {

      // replace the first two arguments:
      $args[0] = $js;
      $args[1] = $_POST;
      return call_user_func_array(array(
        $handler,
        $method,
      ), $args);
    }
  }
  else {
    return t('Configuration error. No handler found.');
  }
}

/**
 * Callback used for switching callbacks into the proper plugin.
 */
function panelizer_entity_plugin_callback_switcher($entity_type, $switcher_type, $op) {
  $args = func_get_args();
  if (count($args) < 3) {
    return FALSE;
  }
  $entity_type = array_shift($args);
  $switcher_type = array_shift($args);
  $op = array_shift($args);

  // Load the $plugin information
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    $method = $switcher_type . '_' . $op;
    if (method_exists($handler, $method)) {
      return call_user_func_array(array(
        $handler,
        $method,
      ), $args);
    }
  }
  else {
    return FALSE;
  }
}

/**
 * Specialized version of ctools_export_ui_switcher_page()
 *
 * This one is designed to set our entity handler and bundle on the
 * object so we can refer to it later without having to override
 * all of the entry points.
 */
function panelizer_export_ui_switcher_page($entity_handler, $bundle, $plugin_name, $op) {
  $args = func_get_args();

  // Remove the handler and the bundle.
  array_shift($args);
  array_shift($args);
  $js = !empty($_REQUEST['js']);

  // Load the $plugin information
  $plugin = ctools_get_export_ui($plugin_name);
  $handler = ctools_export_ui_get_handler($plugin);
  if ($handler) {
    if (is_string($entity_handler)) {
      $entity_handler = panelizer_entity_plugin_get_handler($entity_handler);
    }
    $handler->entity_handler = $entity_handler;
    $handler->entity_bundle = $bundle;
    if (empty($entity_handler->entity_admin_root) || substr($_GET['q'], 30) == 'admin/config/content/panelizer') {
      $handler->plugin['menu']['menu prefix'] = 'admin/config/content/panelizer/' . $entity_handler->entity_type;
      $handler->plugin['menu']['menu item'] = $bundle;
    }
    else {
      $base_path = $entity_handler->entity_admin_root . '/panelizer';
      if (is_numeric($entity_handler->entity_admin_bundle)) {
        $bits = explode('/', $base_path);
        $bits[$entity_handler->entity_admin_bundle] = $bundle;
        $base_path = implode('/', $bits);
      }
      $handler->plugin['menu']['menu prefix'] = dirname($base_path);
      $handler->plugin['menu']['menu item'] = basename($base_path);
    }
    $path = $handler->plugin['menu']['menu prefix'] . '/' . $handler->plugin['menu']['menu item'];
    foreach ($handler->plugin['redirect'] as $key => $old_path) {
      if ($key == 'add') {
        $handler->plugin['redirect'][$key] = $path . '/list/%ctools_export_ui/settings';
      }
      else {
        $handler->plugin['redirect'][$key] = $path . '/list';
      }
    }
    $method = $op . '_page';
    if (method_exists($handler, $method)) {

      // replace the first two arguments:
      $args[0] = $js;
      $args[1] = $_POST;
      return call_user_func_array(array(
        $handler,
        $method,
      ), $args);
    }
  }
  else {
    return t('Configuration error. No handler found.');
  }
}

// ---------------------------------------------------------------------------
// Menu callbacks

/**
 * Title callback to properly set the tile when editing panelizer defaults.
 */
function panelizer_default_title_callback($handler, $bundle) {
  if (is_string($handler)) {
    $handler = panelizer_entity_plugin_get_handler($handler);
  }
  if (!$handler) {
    return '';
  }
  $title = $handler
    ->get_bundle_title($bundle);
  return $title;
}

/**
 * Menu callback to determine if a type has a choice of defaults.
 *
 * We use this to make sure the right tabs appear.
 */
function panelizer_has_choice_callback($handler, $bundle, $name = NULL) {
  if (is_string($handler)) {
    $handler = panelizer_entity_plugin_get_handler($handler);
  }
  if (!$handler) {
    return FALSE;
  }
  if (!panelizer_administer_entity_bundle($handler, $bundle)) {
    return FALSE;
  }

  // Check to see if $name is valid
  if ($name && !$handler
    ->get_default_panelizer_object($bundle, $name)) {
    return FALSE;
  }
  return $handler
    ->has_panel_choice($bundle);
}

/**
 * Menu callback to determine if a type has a choice of defaults.
 *
 * We use this to make sure the right tabs appear.
 */
function panelizer_has_no_choice_callback($handler, $bundle) {
  if (is_string($handler)) {
    $handler = panelizer_entity_plugin_get_handler($handler);
  }
  if (!$handler) {
    return FALSE;
  }
  if (!panelizer_administer_entity_bundle($handler, $bundle)) {
    return FALSE;
  }
  return $handler
    ->has_default_panel($bundle) && !$handler
    ->has_panel_choice($bundle);
}

/**
 * Menu callback to determine if a type has a choice of defaults.
 *
 * We use this to make sure the right tabs appear.
 */
function panelizer_is_panelized($handler, $bundle) {
  if (is_string($handler)) {
    $handler = panelizer_entity_plugin_get_handler($handler);
  }
  if (!$handler) {
    return FALSE;
  }
  if (!panelizer_administer_entity_bundle($handler, $bundle)) {
    return FALSE;
  }
  return $handler
    ->is_panelized($bundle);
}

/**
 * Access callback to see if a user can administer a particular bundle.
 */
function panelizer_administer_entity_bundle($handler, $bundle) {
  if (is_string($handler)) {
    $handler = panelizer_entity_plugin_get_handler($handler);
  }
  return user_access('administer panelizer') || user_access("administer panelizer {$handler->entity_type} {$bundle} defaults");
}

/**
 * Access callback to see if a user can administer a particular panelizer default.
 */
function panelizer_administer_panelizer_default($handler, $bundle, $name) {
  if (is_string($handler)) {
    $handler = panelizer_entity_plugin_get_handler($handler);
  }
  $panelizer = $handler
    ->get_default_panelizer_object($bundle, $name);
  if (!$panelizer) {
    return FALSE;
  }
  return $handler
    ->access_default_panelizer_object($panelizer);
}

/**
 * Menu load callback to scrub a node bundle from the URL safe equivalent.
 */
function panelizer_node_type_load($name) {
  if ($type = node_type_get_type(strtr($name, array(
    '-' => '_',
  )))) {
    return $type->type;
  }
}

// ---------------------------------------------------------------------------
// export.inc callbacks to handle proper in/out of our defaults

/**
 * export.inc callback to properly save a panelizer default.
 */
function panelizer_export_save_callback(&$object) {
  if (!empty($object->display)) {

    // First write the display
    panels_save_display($object->display);

    // Make sure we have the did.
    $object->did = $object->display->did;
  }

  // Then write the default
  if ($object->export_type & EXPORT_IN_DATABASE) {

    // Existing record.
    $update = array(
      'pnid',
    );
  }
  else {

    // New record.
    $update = array();
    $object->export_type = EXPORT_IN_DATABASE;
  }
  return drupal_write_record('panelizer_defaults', $object, $update);
}

/**
 * export.inc callback to properly export a panelizer default.
 */
function panelizer_export_export_callback($object, $indent) {
  $object->did = NULL;
  $output = ctools_export_object('panelizer_defaults', $object, $indent);
  $output .= panels_export_display($object->display, $indent);
  $output .= $indent . '$panelizer->display = $display;' . "\n";
  return $output;
}

/**
 * export.inc callback to properly delete a panelizer default.
 */
function panelizer_export_delete_callback($object) {
  if (!empty($object->did)) {
    panels_delete_display($object->did);
  }
  db_delete('panelizer_defaults')
    ->condition('name', $object->name)
    ->execute();
}

/**
 * export.inc callback to load sub records for an object.
 */
function panelizer_export_delete_callback_subrecords($objects) {
  $dids = array();
  foreach ($objects as $panelizer) {
    if (!empty($panelizer->did)) {
      $dids[$panelizer->did] = $panelizer->did;
    }
  }
  if ($dids) {
    $displays = panels_load_displays($dids);
    foreach ($objects as $panelizer) {
      if (!empty($panelizer->did) && !empty($displays[$panelizer->did])) {
        $panelizer->display = $displays[$panelizer->did];
      }
    }
  }
}

// ---------------------------------------------------------------------------
// Context cache callbacks -- this really needs a less lame system someday.

/**
 * Fetch the panelizer object from the object cache.
 *
 * CTools clumsy context editing system requires caching. This lets us
 * do it reasonably.
 *
 * @param $entity_type
 *   Can be something like 'node' or 'user' or 'default'.
 * @param $key
 *   Depends on the $entity_type. Can be a nid, a uid or a default key.
 */
function panelizer_context_cache_get($entity_type, $key) {
  ctools_include('object-cache');
  $cache = ctools_object_cache_get('panelizer_context_cache', $entity_type . ':' . $key);
  if (!empty($cache)) {
    $cache->cached = TRUE;
    return $cache;
  }
  if ($entity_type == 'default') {
    list($entity_type, $bundle, $name) = @explode(':', $key, 3);
    $get_default = TRUE;
  }
  if ($handler = panelizer_entity_plugin_get_handler($entity_type)) {
    if (!empty($get_default)) {
      $panelizer = $handler
        ->get_default_panelizer_object($bundle, $name);
      $panelizer->base_contexts = $handler
        ->get_base_contexts();
      return $panelizer;
    }
    else {
      $entities = entity_load($entity_type, array(
        $key,
      ));
      if ($entities[$key] && $entities[$key]->panelizer) {
        $panelizer = $entities[$key]->panelizer;
        $panelizer->base_contexts = $handler
          ->get_base_contexts($entities[$key]);
        return $panelizer;
      }
    }
  }
}

/**
 * Store the panelizer object in the object cache.
 *
 * CTools clumsy context editing system requires caching. This lets us
 * do it reasonably.
 *
 * @param $entity_type
 *   Can be something like 'node' or 'user' or 'default'.
 * @param $key
 *   Either the node type or the nid.
 * @param $object
 *   The cached object.
 */
function panelizer_context_cache_set($entity_type, $key, $object) {
  ctools_include('object-cache');
  ctools_object_cache_set('panelizer_context_cache', $entity_type . ':' . $key, $object);
}

/**
 * Clear the panelizer object in the object cache.
 *
 * CTools clumsy context editing system requires caching. This lets us
 * do it reasonably.
 *
 * @param $entity_type
 *   Can be something like 'node' or 'user' or 'default'.
 * @param $key
 *   Either the node type or the nid.
 */
function panelizer_context_cache_clear($entity_type, $key) {
  ctools_include('object-cache');
  ctools_object_cache_clear('panelizer_context_cache', $entity_type . ':' . $key);
}

// --------------------------------------------------------------------------
// Panels edit cache contexts.

/**
 * Get display edit cache for a panel being edited.
 *
 * The key is the second half of the key in this form:
 * panelizer:TYPE:KEY;
 */
function panelizer_panels_cache_get($argument) {
  ctools_include('object-cache');
  list($entity_type, $key) = explode(':', $argument, 2);
  $cache = ctools_object_cache_get('panelizer_display_cache', $entity_type . ':' . $key);

  // Keep $type because $entity_type can be 'default' which is not actually an
  // entity type in that case.
  $type = $entity_type;
  if ($entity_type == 'default') {
    list($entity_type, $bundle, $name) = @explode(':', $key, 3);
    $get_default = TRUE;
  }
  $handler = panelizer_entity_plugin_get_handler($entity_type);
  if (!$handler) {
    return;
  }

  // If it's already cached, we still need to restore our contexts.
  if (!empty($cache)) {
    $cache->cached = TRUE;
    if (!empty($get_default)) {
      $panelizer = $handler
        ->get_default_panelizer_object($bundle, $name);
      $cache->display->context = $handler
        ->get_contexts($panelizer);
    }
    else {
      $entities = entity_load($entity_type, array(
        $key,
      ));
      if ($entities[$key] && $entities[$key]->panelizer) {
        $panelizer = $entities[$key]->panelizer;
        $cache->display->context = $handler
          ->get_contexts($panelizer, $entities[$key]);
      }
    }
    return $cache;
  }
  $cache = new stdClass();

  // If it wasn't cached, create a new cache.
  if (!empty($get_default)) {
    $panelizer = $handler
      ->get_default_panelizer_object($bundle, $name);
    $cache->display = $panelizer->display;
    $cache->display->context = $handler
      ->get_contexts($panelizer);
  }
  else {
    $entities = entity_load($entity_type, array(
      $key,
    ));
    if (empty($entities[$key]) || empty($entities[$key]->panelizer)) {
      return $cache;
    }
    list($entity_id, $revision_id, $bundle) = entity_extract_ids($entity_type, $entities[$key]);
    $panelizer = $entities[$key]->panelizer;
    $cache->display = $panelizer->display;
    $cache->display->context = $handler
      ->get_contexts($panelizer, $entities[$key]);
  }
  ctools_include('common', 'panels');
  $cache->display->cache_key = "panelizer:{$type}:{$key}";
  $cache->content_types = panels_common_get_allowed_types('panelizer_' . $type . ':' . $bundle, $cache->display->context);
  return $cache;
}

/**
 * Store a display edit in progress in the page cache.
 */
function panelizer_panels_cache_set($argument, $cache) {
  list($type, $key) = explode(':', $argument, 2);
  ctools_include('object-cache');
  ctools_object_cache_set('panelizer_display_cache', $type . ':' . $key, $cache);
}

/**
 * Save all changes made to a display using the Page Manager page cache.
 */
function panelizer_panels_cache_clear($argument, $cache) {
  list($type, $key) = explode(':', $argument, 2);
  ctools_include('object-cache');
  ctools_object_cache_clear('panelizer_display_cache', $type . ':' . $key);
}

/**
 * Save all changes made to a display using the Page Manager page cache.
 */
function panelizer_panels_cache_save($argument, $cache) {
  list($entity_type, $key) = explode(':', $argument, 2);
  $type = $entity_type;
  if ($entity_type == 'default') {
    list($entity_type, $bundle, $name) = @explode(':', $key, 3);
    $get_default = TRUE;
  }
  $handler = panelizer_entity_plugin_get_handler($entity_type);
  if (!$handler) {
    return;
  }
  if (!empty($get_default)) {
    $panelizer = $handler
      ->get_default_panelizer_object($bundle, $name);
    $panelizer->display = $cache->display;
    ctools_include('export');
    ctools_export_crud_save('panelizer_defaults', $panelizer);
  }
  else {
    $entities = entity_load($entity_type, array(
      $key,
    ));
    if ($entities[$key] && $entities[$key]->panelizer) {
      $entities[$key]->panelizer->display = $cache->display;
      $entities[$key]->panelizer->display_is_modified = TRUE;
      $handler
        ->entity_save($entities[$key]);
    }
  }
  panelizer_panels_cache_clear($argument, $cache);
}

// ---------------------------------------------------------------------------
// Contrib module hooks to provide needed functionality.

/**
 * Implements hook_export_node_alter().
 *
 * Integrate with export.module for saving panel_nodes into code.
 */
function panelizer_export_node_alter(&$node, $original_node, $method) {

  // @todo
}

/**
 * Implements hook_panelizer_defaults_alter().
 *
 * Remove the panels node because there is no point to panelizing it.
 */
function panelizer_panelizer_default_types_alter(&$bundles, $entity_type) {
  switch ($entity_type) {
    case 'node':

      // Disallow the panel node type, since it's already a panel.
      if (module_exists('panels_node') && !empty($bundles['panel'])) {
        unset($bundles['panel']);
      }
      break;
    case 'user':
  }
}

/**
 * Implements hook_features_export_alter().
 */
function panelizer_features_export_alter(&$export, $module_name) {
  if (!empty($export['features']['panelizer_defaults'])) {
    foreach ($export['features']['panelizer_defaults'] as $machine_name) {
      list($entity_type, $bundle) = explode(':', $machine_name);
      $variables = array(
        'panelizer_defaults_' . $entity_type . '_' . $bundle,
        'panelizer_' . $entity_type . ':' . $bundle . '_allowed_layouts',
        'panelizer_' . $entity_type . ':' . $bundle . '_allowed_types',
        'panelizer_' . $entity_type . ':' . $bundle . '_default',
      );
      if (module_exists('strongarm')) {
        foreach ($variables as $key => $variable) {
          if (variable_get($variable) === NULL) {
            unset($variables[$key]);
          }
        }
        $variables = array_diff($variables, array_keys(strongarm_vars_load()));
      }
      foreach ($variables as $variable) {
        $export['features']['variable'][$variable] = $variable;
      }
    }
  }
  return array();
}

// -----------------------------------------------------------------------
// Drupal actions integration for VBO

/**
 * Implements hook_action_info().
 */
function panelizer_action_info() {
  return array(
    'panelizer_set_status_action' => array(
      'type' => 'entity',
      'label' => t('Set panelizer status'),
      'vbo_configurable' => TRUE,
      'behavior' => array(
        'changes_property',
      ),
      'configurable' => TRUE,
    ),
  );
}

/**
 * Executes the panelizer_set_status action.
 */
function panelizer_set_status_action($entity, $context) {
  list($entity_id, $revision_id, $bundle) = entity_extract_ids($context['entity_type'], $entity);
  if (isset($context['panelizer_default'])) {
    $entity->panelizer = $context['panelizer_default'];
    $entity->panelizer->did = NULL;

    // Ensure original values are maintained:
    $entity->panelizer->entity_id = $entity_id;
    $entity->panelizer->revision_id = $revision_id;
  }
  else {
    $entity->panelizer->name = NULL;
    $entity->panelizer->did = NULL;
  }
}

/**
 * Provides the panelizer_set_status_action form.
 */
function panelizer_set_status_action_form($context, &$form_state) {
  $form = array();
  $entity_info = entity_get_info($context['entity_type']);
  $entities = entity_load($context['entity_type'], $form_state['selection']);
  $bundles = array();

  // Collect our list of bundles.
  foreach ($entities as $entity) {
    list($entity_id, $revision_id, $bundle) = entity_extract_ids($context['entity_type'], $entity);
    $bundles[$bundle] = $bundle;
  }
  $conditions = array(
    'panelizer_type' => $context['entity_type'],
    'panelizer_key' => $bundles,
  );
  ctools_include('export');
  $defaults = ctools_export_load_object('panelizer_defaults', 'conditions', $conditions);
  foreach ($defaults as $name => $default) {
    if (empty($default->title)) {
      $default->title = t('Default');
    }
    $options[$name] = t('@bundle: @title', array(
      '@bundle' => $entity_info['bundles'][$default->panelizer_key]['label'],
      '@title' => $default->title,
    ));
  }
  natcasesort($options);
  $options = array(
    'not' => t('Not panelized'),
  ) + $options;
  $form['panelizer'] = array(
    '#type' => 'select',
    '#title' => t('Panelizer status'),
    '#options' => $options,
  );
  $form['#panelizer_defaults'] = $defaults;
  return $form;
}
function panelizer_set_status_action_submit($form, $form_state) {
  $retval = array(
    'panelizer' => $form_state['values']['panelizer'],
  );
  if ($form_state['values']['panelizer'] != 'not') {
    $retval['panelizer_default'] = $form['#panelizer_defaults'][$form_state['values']['panelizer']];
  }
  return $retval;
}

Functions

Namesort descending Description
panelizer_action_info Implements hook_action_info().
panelizer_administer_entity_bundle Access callback to see if a user can administer a particular bundle.
panelizer_administer_panelizer_default Access callback to see if a user can administer a particular panelizer default.
panelizer_admin_paths Implements hook_admin_paths().
panelizer_context_cache_clear Clear the panelizer object in the object cache.
panelizer_context_cache_get Fetch the panelizer object from the object cache.
panelizer_context_cache_set Store the panelizer object in the object cache.
panelizer_ctools_access_clear Implement CTools access form caching callback: get.
panelizer_ctools_access_get Implement CTools access form caching callback: get.
panelizer_ctools_access_set Implement CTools access form caching callback: set.
panelizer_ctools_plugin_api Implements hook_ctools_plugin_api().
panelizer_ctools_plugin_directory Implements hook_ctools_plugin_directory()
panelizer_ctools_plugin_type Implements hook_ctools_plugin_type()
panelizer_default_page_manager_handlers Implements hook_default_page_manager_handlers().
panelizer_default_title_callback Title callback to properly set the tile when editing panelizer defaults.
panelizer_entity_delete Implements hook_entity_delete().
panelizer_entity_insert Implements hook_entity_insert().
panelizer_entity_load Implements hook_entity_load().
panelizer_entity_plugin_callback_switcher Callback used for switching callbacks into the proper plugin.
panelizer_entity_plugin_get_handler Get the class to handle custom code for a given entity type plugin.
panelizer_entity_plugin_process CTools process callback for an entity plugin.
panelizer_entity_plugin_switcher_page Page callback for entity menu callbacks.
panelizer_entity_update Implements hook_entity_update().
panelizer_export_delete_callback export.inc callback to properly delete a panelizer default.
panelizer_export_delete_callback_subrecords export.inc callback to load sub records for an object.
panelizer_export_export_callback export.inc callback to properly export a panelizer default.
panelizer_export_node_alter Implements hook_export_node_alter().
panelizer_export_save_callback export.inc callback to properly save a panelizer default.
panelizer_export_ui_switcher_page Specialized version of ctools_export_ui_switcher_page()
panelizer_features_api Implements hook_features_api().
panelizer_features_export_alter Implements hook_features_export_alter().
panelizer_field_attach_delete_revision Implements hook_field_attach_delete_revision().
panelizer_field_attach_form
panelizer_field_attach_submit
panelizer_form_alter Implements hook_form_alter().
panelizer_get_entity_plugin Fetch a single entity plugin.
panelizer_get_entity_plugins Fetch all entity plugin.
panelizer_get_plugins_with_hook Fetch handler objects for all plugins that implement the named hook.
panelizer_handler_load Load handler to get a plugin as a menu callback.
panelizer_has_choice_callback Menu callback to determine if a type has a choice of defaults.
panelizer_has_no_choice_callback Menu callback to determine if a type has a choice of defaults.
panelizer_is_panelized Menu callback to determine if a type has a choice of defaults.
panelizer_menu Implements hook_menu().
panelizer_menu_alter Implements hook_menu_alter().
panelizer_node_type_load Menu load callback to scrub a node bundle from the URL safe equivalent.
panelizer_page_alter Implements hook_page_alter().
panelizer_panelizer_defaults_alter Implements hook_panelizer_defaults_alter().
panelizer_panelizer_default_types_alter Implements hook_panelizer_defaults_alter().
panelizer_panels_cache_clear Save all changes made to a display using the Page Manager page cache.
panelizer_panels_cache_get Get display edit cache for a panel being edited.
panelizer_panels_cache_save Save all changes made to a display using the Page Manager page cache.
panelizer_panels_cache_set Store a display edit in progress in the page cache.
panelizer_permission Implements hook_permission().
panelizer_set_status_action Executes the panelizer_set_status action.
panelizer_set_status_action_form Provides the panelizer_set_status_action form.
panelizer_set_status_action_submit
panelizer_theme Implements hook_theme().
panelizer_views_api Implementation of hook_views_api().