<?php
/**
 * @file
 * ESI cache plugin.  Substitutes esi-tags for a panel-pane's content.
 */

// Plugin definition
$plugin = array(
  'title' => t('ESI'),
  'description' => t('ESI caching is a proxy-based cache. Panes are replaced by <esi> tags and requested separately by the proxy.'),
  'cache get' => 'esi_panels_esi_cache_get_cache',
  'cache set' => 'esi_panels_esi_cache_set_cache',
  'cache clear' => 'esi_panels_esi_cache_clear_cache',
  'settings form' => 'esi_panels_esi_cache_settings_form',
  'settings form submit' => 'esi_panels_esi_cache_settings_form_submit',
  'defaults' => array(
    // @TODO: review settings.
    'ttl' => (int) variable_get('esi_panels_esi_default_ttl', ESI_DEFAULT_TTL),
    'granularity' => 0,
    'esi_override_context' => FALSE,
  ),
);

/**
 * Set cached content.
 */
function esi_panels_esi_cache_set_cache($conf, $content, $display, $args, $contexts, $pane = NULL) {
  // $content will be a panels_cache_object; $content->content is the actual
  // content.
  // DO NOTHING!
}

/**
 * Get cached content.
 */
function esi_panels_esi_cache_get_cache($conf, $display, $args, $contexts, $pane = NULL) {
  // If this 'cache get' function returns FALSE, panels will invoke and render
  // the pane in the normal way.
  return FALSE;


  // @TODO: is this necessary now?
  // // Check that the pane is indeed meant to be served by ESI.
  // if (empty($pane) || empty($pane->cache['method']) || $pane->cache['method'] != 'esi') {
  //   return FALSE;
  // }
  // 
  // // Panels expects a cache-handler to return an object similar to the object
  // // returned by cache_get().  Faking a cached object allows us to return a
  // // simple ESI tag instead.
  // 
  // // Fake the cached object.
  // $cache = new stdClass;
  // $cache->data = new panels_cache_object();
  // $cache->data->content = new stdClass;
  // $cache->data->head = NULL;
  // $cache->data->css = array();
  // $cache->data->js = array();
  // $cache->data->tokens = array();
  // $cache->data->ready = TRUE;
  // 
  // // Fill in the content with the ESI code
  // $cache->data->content->content = 'This is my content, tell me yours.';
  // 
  // // Add in extras if missing.
  // if (!isset($cache->data->content->module)) {
  //   $cache->data->content->module = isset($pane->type) ? $pane->type : 'esi_panels';
  // }
  // if (!isset($cache->data->content->delta)) {
  //   $cache->data->content->delta = isset($pane->subtype) ? $pane->subtype : 'esi';
  // }
  // 
  // // Return the cache object.
  // return $cache->data;
}


/**
 * Admin-settings form for configuring the ESI cache on panel panes.
 */
function esi_panels_esi_cache_settings_form($conf, $display, $pid) {
  // Use the TTL from the config if provided, or a suitable default.
  $esi_ttl = isset($conf['esi_ttl']) ? $conf['esi_ttl'] : (int) variable_get('esi_panels_esi_default_ttl', ESI_DEFAULT_TTL);

  $pane = (isset($display->content[$pid])) ? $display->content[$pid] : FALSE;
  // Load up the pane information to examine the context.

  $form['esi_ttl'] = array(
    '#title' => t('Cache Maximum Age (TTL)'),
    '#type' => 'select',
    '#options' => esi_max_age_options($esi_ttl),
    '#default_value' => $esi_ttl,
    '#description' => t('External page caches (proxy/browser) will not deliver cached paged older than this setting; time to live in short.'),
  );

  $form['override_context'] = array(
    '#title' => t('Override cache context'),
    '#type' => 'fieldset',
    '#description' => t('The context requested by the pane (and provided by the parent panel) will be used by default to create separate versions of the pane for each context.'),
    '#collapsible' => TRUE,
    '#collapsed' => empty($conf['override_context']['esi_override_context']),
  );

  // Describe the current panels context: placeholder if there is no context.
  $form['override_context']['pane_context'] = array(
    '#type' => 'item',
    '#title' => t('Current panels context'),
    '#prefix' => '<div class="current_context">',
    '#suffix' => '</div>',
    '#markup' => t("This pane doesn't use panels context."),
  );

  // If there is context, add to the placeholder.
  if (!empty($pane->configuration['context'])) {
    // The context is a simple identifier - e.g. "argument_entity_id:node_1".
    // The description of this context - e.g. "Node being viewed" - is
    // generated by the task handler.
    $context_id = $pane->configuration['context'];
    $context = $display->context[$context_id];
    $form['override_context']['pane_context']['#markup'] = t($context->identifier);
  }

  $form['override_context']['esi_override_context'] = array(
    '#title' => t('Override cache context'),
    '#type' => 'checkbox',
    '#default_value' => !empty($conf['override_context']['esi_override_context']),
  );

  $form['override_context']['esi_overridden_context__pane_context'] = array(
    '#title' => t('Cache per pane-context'),
    '#description' => t("The contents of this pane changes depending on the pane context provided by the panel."),
    '#type' => 'checkbox',
    '#default_value' => !empty($conf['override_context']['esi_overridden_context__pane_context']),
    // If this pane doesn't provide context, this option isn't applicable.
    '#disabled' => empty($pane->configuration['context']),
    // @TODO: use states (once control of radios through states is patched).
    // '#states' => array(
    //   'disabled' => array(   // override_context to take.
    //     ':input[name="settings[override_context][esi_override_context]"]' => array('unchecked' => TRUE),
    //   ),
    // ),
  );

  $form['override_context']['esi_overridden_context__page'] = array(
    '#title' => t('Cache per page'),
    '#description' => t("The contents of this pane changes depending on the page on which it's displayed."),
    '#type' => 'checkbox',
    '#default_value' => !empty($conf['override_context']['esi_overridden_context__page']),
    // @TODO: use states (once control of radios through states is patched).
    // '#states' => array(
    //   'disabled' => array(   // override_context to take.
    //     ':input[name="settings[override_context][esi_override_context]"]' => array('unchecked' => TRUE),
    //   ),
    // ),
  );

  $form['override_context']['esi_overridden_context__user'] = array(
    '#title' => t('User context'),
    '#description' => t("How a user or their roles affect the pane."),
    '#type' => 'radios',
    '#options' => array(
      DRUPAL_CACHE_GLOBAL => t('Pane is shared by all users'),
      DRUPAL_CACHE_PER_ROLE => t("Pane changes according to the current user's roles"),
      DRUPAL_CACHE_PER_USER => ('Pane changes according to the current user'),
    ),
    '#default_value' => isset($conf['override_context']['esi_overridden_context__user']) ? $conf['override_context']['esi_overridden_context__user'] : DRUPAL_CACHE_PER_ROLE,
    // @TODO: use states (once control of radios through states is patched).
    // '#states' => array(
    //   'disabled' => array(   // override_context to take.
    //     ':input[name="settings[override_context][esi_override_context]"]' => array('unchecked' => TRUE),
    //   ),
    // ),
  );

  return $form;
}
