You are here

function panels_save_display in Panels 8.3

Same name and namespace in other branches
  1. 5.2 panels.module \panels_save_display()
  2. 6.3 panels.module \panels_save_display()
  3. 6.2 panels.module \panels_save_display()
  4. 7.3 panels.module \panels_save_display()

Save a display object.

Note that a new $display only receives a real did once it is run through this function, and likewise for the pid of any new pane.

Until then, a new display uses a string placeholder, 'new', in place of a real did, and a new pane (whether on a new $display or not) appends a universally-unique identifier (which is stored permanently in the 'uuid' field). This format is also used in place of the real pid for exports.

Parameters

object $display instanceof panels_display \n: The display object to be saved. Passed by reference so the caller need not use the return value for any reason except convenience.

Return value

object $display instanceof panels_display \n

Related topics

File

./panels.module, line 631
panels.module

Code

function panels_save_display(&$display) {
  $update = isset($display->did) && is_numeric($display->did) ? array(
    'did',
  ) : array();
  if (empty($display->uuid) || !ctools_uuid_is_valid($display->uuid)) {
    $display->uuid = ctools_uuid_generate();
  }
  drupal_write_record('panels_display', $display, $update);
  $pids = array();
  if ($update) {

    // Get a list of all panes currently in the database for this display so we can know if there
    // are panes that need to be deleted. (i.e, aren't currently in our list of panes).
    $result = db_query("SELECT pid FROM {panels_pane} WHERE did = :did", array(
      ':did' => $display->did,
    ));
    foreach ($result as $pane) {
      $pids[$pane->pid] = $pane->pid;
    }
  }

  // update all the panes
  ctools_include('plugins', 'panels');
  ctools_include('content');
  foreach ($display->panels as $id => $panes) {
    $position = 0;
    $new_panes = array();
    foreach ((array) $panes as $pid) {
      if (!isset($display->content[$pid])) {
        continue;
      }
      $pane = $display->content[$pid];
      $type = ctools_get_content_type($pane->type);
      $pane->position = $position++;
      $pane->did = $display->did;
      $old_pid = $pane->pid;
      if (empty($pane->uuid) || !ctools_uuid_is_valid($pane->uuid)) {
        $pane->uuid = ctools_uuid_generate();
      }
      drupal_write_record('panels_pane', $pane, is_numeric($pid) ? array(
        'pid',
      ) : array());

      // Allow other modules to take action after a pane is saved.
      if ($pane->pid == $old_pid) {
        module_invoke_all('panels_pane_update', $pane);
      }
      else {
        module_invoke_all('panels_pane_insert', $pane);
      }
      if ($pane->pid != $old_pid) {

        // Remove the old new-* entry from the displays content.
        unset($display->content[$pid]);

        // and put it back so our pids and positions can be used.
        $display->content[$pane->pid] = $pane;

        // If the title pane was one of our panes that just got its ID changed,
        // we need to change it in the database, too.
        if (isset($display->title_pane) && $display->title_pane == $old_pid) {
          $display->title_pane = $pane->pid;

          // Do a simple update query to write it so we don't have to rewrite
          // the whole record. We can't just save writing the whole record here
          // because it was needed to get the did. Chicken, egg, more chicken.
          db_update('panels_display')
            ->fields(array(
            'title_pane' => $pane->pid,
          ))
            ->condition('did', $display->did)
            ->execute();
        }
      }

      // re-add this to the list of content for this panel.
      $new_panes[] = $pane->pid;

      // Remove this from the list of panes scheduled for deletion.
      if (isset($pids[$pane->pid])) {
        unset($pids[$pane->pid]);
      }
    }
    $display->panels[$id] = $new_panes;
  }
  if (!empty($pids)) {

    // Allow other modules to take action before a panes are deleted.
    module_invoke_all('panels_pane_delete', $pids);
    db_delete('panels_pane')
      ->condition('pid', $pids)
      ->execute();
  }

  // Clear any cached content for this display.
  panels_clear_cached_content($display);

  // Allow other modules to take action when a display is saved.
  module_invoke_all('panels_display_save', $display);

  // Log the change to watchdog, using the same style as node.module
  $watchdog_args = array(
    '%did' => $display->did,
  );
  if (!empty($display->title)) {
    $watchdog_args['%title'] = $display->title;
    watchdog('content', 'Panels: saved display "%title" with display id %did', $watchdog_args, WATCHDOG_NOTICE);
  }
  else {
    watchdog('content', 'Panels: saved display with id %did', $watchdog_args, WATCHDOG_NOTICE);
  }

  // to be nice, even tho we have a reference.
  return $display;
}