/**
  * Render the interior contents of a single pane.
  *
  * This method retrieves pane content and produces a ready-to-render content
  * object. It also manages pane-specific caching.
  *
  * @param stdClass $pane
  *   A Panels pane object, as loaded from the database.
  * @return stdClass $content
  *   A renderable object, containing a subject, content, etc. Based on the
  *   renderable objects used by the block system.
  */
 function render_pane_content(&$pane)
 {
     ctools_include('context');
     // TODO finally safe to remove this check?
     if (!is_array($this->display->context)) {
         watchdog('panels', 'renderer::render_pane_content() hit with a non-array for the context', $this->display, WATCHDOG_DEBUG);
         $this->display->context = array();
     }
     $caching = !empty($pane->cache['method']) && empty($this->display->skip_cache);
     if ($caching && ($cache = panels_get_cached_content($this->display, $this->display->args, $this->display->context, $pane))) {
         $content = $cache->content;
     } else {
         if ($caching) {
             // This is created before rendering so that calls to drupal_add_js
             // and drupal_add_css will be captured.
             $cache = new panels_cache_object();
         }
         $content = ctools_content_render($pane->type, $pane->subtype, $pane->configuration, array(), $this->display->args, $this->display->context);
         foreach (module_implements('panels_pane_content_alter') as $module) {
             $function = $module . '_panels_pane_content_alter';
             $function($content, $pane, $this->display->args, $this->display->context, $this, $this->display);
         }
         if ($caching && isset($cache)) {
             $cache->set_content($content);
             panels_set_cached_content($cache, $this->display, $this->display->args, $this->display->context, $pane);
             $content = $cache->content;
         }
     }
     // If there's content, check if we've css configuration to add.
     if (!empty($content)) {
         // Pass long the css_id that is usually available.
         if (!empty($pane->css['css_id'])) {
             $id = ctools_context_keyword_substitute($pane->css['css_id'], array(), $this->display->context);
             $content->css_id = drupal_html_id($id);
         }
         // Pass long the css_class that is usually available.
         if (!empty($pane->css['css_class'])) {
             $class = ctools_context_keyword_substitute($pane->css['css_class'], array(), $this->display->context, array('css safe' => TRUE));
             $content->css_class = check_plain(drupal_strtolower($class));
         }
     }
     return $content;
 }
 /**
  * Render the panels display for a given panelizer entity.
  *
  * @param stdClass $entity
  *   A fully-loaded entity object controlled by panelizer.
  * @param array $args
  *   Optional array of arguments to pass to the panels display.
  * @param string $address
  *   An optional address to send to the renderer to use for addressable
  *   content.
  * @param array $extra_contexts
  *   An optional array of extra context objects that will be added to the
  *   display.
  *
  * @return array
  *   If the entity isn't panelized, this returns NULL. Otherwise, it returns an
  *   associative array as meant for use with CTools with the following keys:
  *   - 'content': String containing the rendered panels display output.
  *   - 'no_blocks': Boolean defining if the panels display wants to hide core
  *      blocks or not when being rendered.
  */
 function render_entity($entity, $view_mode, $langcode = NULL, $args = array(), $address = NULL, $extra_contexts = array())
 {
     if (empty($entity->panelizer[$view_mode]) || empty($entity->panelizer[$view_mode]->display)) {
         return FALSE;
     }
     list($entity_id, $revision_id, $bundle) = entity_extract_ids($this->entity_type, $entity);
     $panelizer = $entity->panelizer[$view_mode];
     $display = $panelizer->display;
     $display->context = $this->get_contexts($panelizer, $entity) + $extra_contexts;
     $display->args = $args;
     $display->css_id = $panelizer->css_id;
     // This means the IPE will use our cache which means it will get appropriate
     // allowed content should it be selected.
     $display->cache_key = implode(':', array_filter(array('panelizer', $this->entity_type, $entity_id, $view_mode, $revision_id)));
     // Check to see if there is any CSS.
     if (!empty($panelizer->css)) {
         ctools_include('css');
         $filename = ctools_css_retrieve($display->cache_key);
         if (!$filename) {
             $filename = ctools_css_store($display->cache_key, $panelizer->css);
         }
         drupal_add_css($filename, array('group' => CSS_THEME));
     }
     if ($view_mode == 'page_manager') {
         // We think this is handled as a page, so set the current page display.
         panels_get_current_page_display($display);
     }
     // Allow applications to alter the panelizer and the display before rendering them.
     drupal_alter('panelizer_pre_render', $panelizer, $display, $entity);
     ctools_include('plugins', 'panels');
     $renderer = panels_get_renderer($panelizer->pipeline, $display);
     // If the IPE is enabled, but the user does not have access to edit
     // the entity, load the standard renderer instead.
     // Use class_parents so we don't try to autoload the class we are testing.
     $parents = class_parents($renderer);
     if (!empty($parents['panels_renderer_editor']) && (!$this->panelizer_access('content', $entity, $view_mode) && !$this->entity_access('update', $entity))) {
         $renderer = panels_get_renderer_handler('standard', $display);
     }
     $renderer->address = $address;
     $info = array('title' => $panelizer->display->get_title(), 'content' => panels_render_display($display, $renderer), 'no_blocks' => !empty($panelizer->no_blocks));
     $info['classes_array'] = array();
     if (!empty($panelizer->css_class)) {
         foreach (explode(' ', $panelizer->css_class) as $class) {
             $class = ctools_context_keyword_substitute($class, array(), $display->context);
             if ($class) {
                 $info['classes_array'][] = drupal_html_class($class);
             }
         }
     }
     if (!empty($parents['panels_renderer_editor'])) {
         $path = drupal_get_path('module', 'panelizer');
         ctools_add_js('panelizer-ipe', 'panelizer');
         drupal_add_js($path . "/js/panelizer-ipe.js", array('group' => JS_LIBRARY));
         drupal_add_css($path . "/css/panelizer-ipe.css");
     }
     return $info;
 }
 /**
  * Render the panels display for a given panelizer entity.
  *
  * @param stdClass $entity
  *   A fully-loaded entity object controlled by panelizer.
  * @param array $args
  *   Optional array of arguments to pass to the panels display.
  * @param string $address
  *   An optional address to send to the renderer to use for addressable
  *   content.
  *
  * @return array
  *   If the entity isn't panelized, this returns NULL. Otherwise, it returns an
  *   associative array as meant for use with CTools with the following keys:
  *   - 'content': String containing the rendered panels display output.
  *   - 'no_blocks': Boolean defining if the panels display wants to hide core
  *      blocks or not when being rendered.
  */
 function render_entity($entity, $view_mode, $langcode = NULL, $args = array(), $address = NULL)
 {
     if (empty($entity->panelizer[$view_mode]) || empty($entity->panelizer[$view_mode]->display)) {
         return FALSE;
     }
     list($entity_id, $revision_id, $bundle) = entity_extract_ids($this->entity_type, $entity);
     $panelizer = $entity->panelizer[$view_mode];
     $display = $panelizer->display;
     $display->context = $this->get_contexts($panelizer, $entity);
     $display->args = $args;
     $display->css_id = $panelizer->css_id;
     // This means the IPE will use our cache which means it will get appropriate
     // allowed content should it be selected.
     $display->cache_key = implode(':', array('panelizer', $this->entity_type, $entity_id, $view_mode));
     // Check to see if there is any CSS.
     if (!empty($panelizer->css)) {
         ctools_include('css');
         $filename = ctools_css_retrieve($display->cache_key);
         if (!$filename) {
             $filename = ctools_css_store($display->cache_key, $panelizer->css);
         }
         drupal_add_css($filename, array('group' => CSS_THEME));
     }
     if ($view_mode == 'page_manager') {
         // We think this is handled as a page, so set the current page display.
         panels_get_current_page_display($display);
     }
     ctools_include('plugins', 'panels');
     $renderer = panels_get_renderer($panelizer->pipeline, $display);
     $renderer->address = $address;
     $info = array('content' => panels_render_display($display, $renderer), 'no_blocks' => !empty($panelizer->no_blocks));
     $info['classes_array'] = array();
     if (!empty($panelizer->css_class)) {
         ctools_include('cleanstring');
         foreach (explode(' ', $panelizer->css_class) as $class) {
             $class = ctools_context_keyword_substitute($class, array(), $display->context);
             if ($class) {
                 $info['classes_array'][] = ctools_cleanstring($class);
             }
         }
     }
     $info['title'] = $display->get_title();
     return $info;
 }