You are here

class panels_allowed_layouts in Panels 6.2

Same name and namespace in other branches
  1. 5.2 includes/common.inc \panels_allowed_layouts
  2. 6.3 includes/common.inc \panels_allowed_layouts
  3. 7.3 includes/common.inc \panels_allowed_layouts

Class definition for the allowed layouts governing structure.

This class is designed to handle panels allowed layouts data from start to finish, and sees action at two times:\n

  • When a client module wants to generate a form allowing an admin to create or edit a set of allowed layouts. In this case, either a new panels_allowed_layouts object is created or one is retrieved from storage and panels_allowed_layouts::set_allowed() is called to generate the allowed layouts form. \n
  • When a client module is calling panels_edit_layout(), a saved instantiation of this object can be called up and passed in to the fourth parameter, and only the allowed layouts saved in that object will be displayed on the form. \n

Because the panels API does not impose a data structure on the allowed_layouts data, client modules can create as many of these objects as they want, and organize them around any concept: node types, date published, author roles...anything.

To call the settings form, instantiate this class - or, if your client module's needs are heavy-duty, extend this class and instantiate your subclass - assign values to any relevant desired members, and call panels_allowed_layouts::set_allowed(). See the documentation on that method for a sample implementation.

Note that when unserializing saved tokens of this class, you must run panels_load_include('common') before unserializing in order to ensure that the object is properly loaded.

Client modules extending this class should implement a save() method and use it for their custom data storage routine. You'll need to rewrite other class methods if you choose to go another route.

Hierarchy

Expanded class hierarchy of panels_allowed_layouts

See also

panels_edit_layout()

_panels_edit_layout()

Related topics

File

includes/common.inc, line 44
Functions used by more than one panels client module.

View source
class panels_allowed_layouts {

  /**
   *  Specifies whether newly-added layouts (as in, new .inc files) should be automatically
   *  allowed (TRUE) or disallowed (FALSE) for $this. Defaults to TRUE, which is more
   *  permissive but less of an administrative hassle if/when you add new layouts. Note
   *  that this parameter will be derived from $allowed_layouts if a value is passed in.
   */
  var $allow_new = TRUE;

  /**
   *  Optional member. If provided, the Panels API will generate a drupal variable using
   *  variable_set($module_name . 'allowed_layouts', serialize($this)), thereby handling the
   *  storage of this object entirely within the Panels API. This object will be
   *  called and rebuilt by panels_edit_layout() if the same $module_name string is passed in
   *  for the $allowed_types parameter. \n
   *  This is primarily intended for convenience - client modules doing heavy-duty implementations
   *  of the Panels API will probably want to create their own storage method.
   * @see panels_edit_layout()
   */
  var $module_name = NULL;

  /**
   *  An associative array of all available layouts, keyed by layout name (as defined
   *  in the corresponding layout plugin definition), with value = 1 if the layout is
   *  allowed, and value = 0 if the layout is not allowed.
   *  Calling array_filter(panels_allowed_layouts::$allowed_layout_settings) will return an associative array
   *  containing only the allowed layouts, and wrapping that in array_keys() will
   *  return an indexed version of that array.
   */
  var $allowed_layout_settings = array();

  /**
   * Hack-imitation of D6's $form_state. Used by the panels_common_set_allowed_types()
   * form to indicate whether the returned value is in its 'render', 'failed-validate',
   * or 'submit' stage.
   */
  var $form_state;

  /**
   * Constructor function; loads the $allowed_layout_settings array with initial values according
   * to $start_allowed
   *
   * @param bool $start_allowed
   *  $start_allowed determines whether all available layouts will be marked
   *  as allowed or not allowed on the initial call to panels_allowed_layouts::set_allowed()
   *
   */
  function panels_allowed_layouts($start_allowed = TRUE) {

    // TODO would be nice if there was a way to just fetch the names easily
    foreach ($this
      ->list_layouts() as $layout_name) {
      $this->allowed_layout_settings[$layout_name] = $start_allowed ? 1 : 0;
    }
  }

  /**
   * Manage panels_common_set_allowed_layouts(), the FAPI code for selecting allowed layouts.
   *
   * MAKE SURE to set panels_allowed_layouts::allow_new before calling this method. If you want the panels API
   * to handle saving these allowed layout settings, panels_allowed_layouts::module_name must also be set.
   *
   * Below is a sample implementation; refer to the rest of the class documentation to understand all the
   * specific pieces. Values that are intended to be replaced are wrapped with <>.
   *
   * \n @code
   *  function docdemo_allowed_layouts() {
   *    panels_load_include('common');
   *    if (!is_a($allowed_layouts = unserialize(variable_get('panels_common_allowed_layouts', serialize(''))), 'panels_allowed_layouts')) {
   *     $allowed_layouts = new panels_allowed_layouts();
   *      $allowed_layouts->allow_new = TRUE;
   *      $allowed_layouts->module_name = '<client_module_name>';
   *    }
   *    $result = $allowed_layouts->set_allowed('<Desired client module form title>');
   *    if (in_array($allowed_layouts->form_state, array('failed-validate', 'render'))) {
   *     return $result;
   *    }
   *    elseif ($allowed_layouts->form_state == 'submit') {
   *      drupal_goto('</path/to/desired/redirect>');
   *    }
   *  }
   * @endcode \n
   *
   * If $allowed_layouts->form_state == 'failed-validate' || 'render', then you'll need to return
   * $result as it contains the structured form HTML generated by drupal_render_form() and is ready
   * to be passed through index.php's call to theme('page', ...).
   *
   * However, if $allowed_layouts->form_state == 'submit', then the form has been submitted and we should
   * react. It's really up to your client module how you handle the rest; panels_allowed_layouts::save() (or
   * panels_allowed_layouts::api_save(), if that's the route you're going) will have already been called,
   * so if those methods handle your save routine, then all there is left to do is handle redirects, if you
   * want. The current implementation of the allowed layouts form currently never redirects, so it's up to
   * you to control where the user ends up next.
   *
   * @param string $title
   *  Used to set the title of the allowed layouts form. If no value is given, defaults to
   *  'Panels: Allowed Layouts'.
   *
   * @return mixed $result
   *  - On the first passthrough when the form is being rendered, $result is the form's structured
   *    HTML, ready to be pushed to the screen with a call to theme('page', ...).
   *  - A successful second passthrough indicates a successful submit, and
   *    $result === panels_allowed_layouts::allowed_layout_settings. Returning it is simply for convenience.
   */
  function set_allowed($title = 'Panels: Allowed Layouts') {
    $this
      ->sync_with_available();
    $form_id = 'panels_common_set_allowed_layouts';

    // TODO switch to drupal_build_form(); need to pass by ref
    $form = drupal_retrieve_form($form_id, $this, $title);
    if ($result = drupal_process_form($form_id, $form)) {

      // successful submit
      $this->form_state = 'submit';
      return $result;
    }
    $this->form_state = isset($_POST['op']) ? 'failed-validate' : 'render';
    $result = drupal_render_form($form_id, $form);
    return $result;
  }

  /**
   * Checks for newly-added layouts and deleted layouts. If any are found, updates panels_allowed_layouts::allowed_layout_settings;
   * new additions are made according to panels_allowed_layouts::allow_new, while deletions are unset().
   *
   * Note that any changes made by this function are not saved in any permanent location.
   */
  function sync_with_available() {
    $layouts = $this
      ->list_layouts();
    foreach (array_diff($layouts, array_keys($this->allowed_layout_settings)) as $new_layout) {
      $this->allowed_layout_settings[$new_layout] = $this->allow_new ? 1 : 0;
    }
    foreach (array_diff(array_keys($this->allowed_layout_settings), $layouts) as $deleted_layout) {
      unset($this->allowed_layout_settings[$deleted_layout]);
    }
  }

  /**
   * Use panels_allowed_layouts::module_name to generate a variable for variable_set(), in which
   * a serialized version of $this will be stored.
   *
   * Does nothing if panels_allowed_layouts::module_name is not set.
   *
   * IMPORTANT NOTE: if you use variable_get() in a custom client module save() method, you MUST
   * wrap $this in serialize(), then unserialize() what you get from variable_get(). Failure to
   * do so will result in an incomplete object. The following code will work:
   * @code
   *  $allowed_layouts = unserialize(variable_get('your_variable_name', serialize(''));
   * @endcode
   *
   * If you don't serialize the second parameter of variable_get() and the variable name you provide
   * can't be found, an E_STRICT warning will be generated for trying to unserialize an entity
   * that has not been serialized.
   *
   */
  function api_save() {
    if (!is_null($this->module_name)) {
      variable_set($this->module_name . "_allowed_layouts", serialize($this));
    }
  }

  /**
   * Snag a list of the current layouts for internal use.
   *
   * Data is not saved in a class member in order to ensure that it's
   * fresh.
   *
   * @return array $layouts
   *  An indexed array of the system names for all currently available layouts.
   */
  function list_layouts() {
    static $layouts = array();
    if (empty($layouts)) {
      panels_load_include('plugins');
      $layouts = array_keys(panels_get_layouts());
    }
    return $layouts;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
panels_allowed_layouts::$allowed_layout_settings property An associative array of all available layouts, keyed by layout name (as defined in the corresponding layout plugin definition), with value = 1 if the layout is allowed, and value = 0 if the layout is not allowed. Calling…
panels_allowed_layouts::$allow_new property Specifies whether newly-added layouts (as in, new .inc files) should be automatically allowed (TRUE) or disallowed (FALSE) for $this. Defaults to TRUE, which is more permissive but less of an administrative hassle if/when you add new layouts.…
panels_allowed_layouts::$form_state property Hack-imitation of D6's $form_state. Used by the panels_common_set_allowed_types() form to indicate whether the returned value is in its 'render', 'failed-validate', or 'submit' stage.
panels_allowed_layouts::$module_name property Optional member. If provided, the Panels API will generate a drupal variable using variable_set($module_name . 'allowed_layouts', serialize($this)), thereby handling the storage of this object entirely within the Panels API. This object will…
panels_allowed_layouts::api_save function Use panels_allowed_layouts::module_name to generate a variable for variable_set(), in which a serialized version of $this will be stored.
panels_allowed_layouts::list_layouts function Snag a list of the current layouts for internal use.
panels_allowed_layouts::panels_allowed_layouts function Constructor function; loads the $allowed_layout_settings array with initial values according to $start_allowed
panels_allowed_layouts::set_allowed function Manage panels_common_set_allowed_layouts(), the FAPI code for selecting allowed layouts.
panels_allowed_layouts::sync_with_available function Checks for newly-added layouts and deleted layouts. If any are found, updates panels_allowed_layouts::allowed_layout_settings; new additions are made according to panels_allowed_layouts::allow_new, while deletions are unset().