1.20.x layout.class.inc Layout::save()

Save a layout to config.

File

modules/layout/includes/layout.class.inc, line 264
Class for loading, modifying, and executing a layout.

Class

Layout
@file Class for loading, modifying, and executing a layout.

Code

function save() {
  if ($this->storage === LAYOUT_STORAGE_DEFAULT) {
    $this->storage = LAYOUT_STORAGE_OVERRIDE;
  }
  $is_new = !empty($this->is_new);

  // Don't save path based contexts as these are generated on the fly.
  foreach ($this->contexts as $key => $context) {
    if (!$context->storage) {
      unset($this->contexts[$key]);
    }
  }

  // Allow modules to act on layout data before saving.
  foreach (module_implements('layout_presave') as $module) {
    $function = $module . '_layout_presave';
    $function($this);
  }

  $data = array(
    'path' => $this->path,
    'name' => $this->name,
    'title' => $this->title,
    'description' => $this->description,
    'renderer_name' => $this->renderer_name,
    'module' => $this->module,
    'weight' => $this->weight,
    'storage' => $this->storage,
    'layout_template' => $this->layout_template,
    'disabled' => $this->disabled,
    'settings' => $this->settings,
    'positions' => $this->positions,
    'contexts' => $this->contexts,
    'relationships' => $this->relationships,
  );

  // Basic validation to prevent data corruption.
  if (empty($this->name)) {
    throw new LayoutSaveException(t('The layout must have a name specified to save.'));
  }

  // Convert all stored conditions to arrays.
  // @todo: Save per-layout contexts and relationships.
  $sub_parts = array(
    'content',
    'conditions',
    'contexts',
    'relationships',
  );
  foreach ($sub_parts as $config_type) {
    foreach ($this->$config_type as $config_type_key => $config_type_data) {
      unset($config_type_data->is_new);
      $data[$config_type][$config_type_key] = array(
        'plugin' => $config_type_data->plugin,
        'data' => $config_type_data->toArray(),
      );
    }
  }

  if (isset($this->original_name) && $this->original_name != $this->name) {
    config('layout.layout.' . $this->original_name)->delete();
  }
  config('layout.layout.' . $this->name)
    ->setData($data)
    ->save();

  // Parse each BlockText block for file IDs.
  $fids = array();
  foreach ($this->content as $content) {
    if (is_a($content, 'BlockText')) {
      $block_content = $content->settings['content'];
      $block_fids = filter_parse_file_fids($block_content);
      if (isset($block_fids)) {
        $fids = array_merge($fids, $block_fids);
      }
    }
  }
  $files = file_load_multiple($fids);
  foreach ($files as $fid => $file) {
    if ((int) ($file && $file->status) !== FILE_STATUS_PERMANENT) {
      // This makes the file "self-referencing", so it will never be deleted.
      // File usages are not removed for text blocks currently.
      // See https://github.com/backdrop/backdrop-issues/issues/2137.
      file_usage_add($file, 'file', 'file', $file->fid);
    }
  }

  // If this layout overrides an existing module path, reassign or delete
  // the layout menu item.
  if ((layout_provides_path($this->path) === FALSE) && menu_get_item($this->path)) {
    if ($this->menu_item) {
      $this->menu_item->delete();
    }
  }
  // If not overriding an existing module path, ensure that the layout always
  // has a layout menu item at the same path.
  else {
    if ($this->menu_item) {
      // If an existing menu item exists but this layout's path has changed,
      // reassign/delete the existing menu item, then create a new one.
      if ($this->menu_item->path !== $this->path) {
        $new_menu_item = clone($this->menu_item);
        $new_menu_item->path = $this->path;
        $new_menu_item->name = $this->name;
        $new_menu_item->is_new = TRUE;
        $this->menu_item->reassign();
        $this->menu_item = $new_menu_item;
        $this->menu_item->save();
      }
      else {
        if (isset($this->original_name) && $this->original_name !== $this->name && $this->menu_item->name === $this->original_name) {
          config('layout.menu_item.' . $this->original_name)->delete();
        }
        $this->menu_item->save();
      }
    }
  }
  layout_reset_caches();

  $new_this = layout_load($this->name);
  if ($is_new) {
    $new_this->invokeHook('insert');
  }
  else {
    $new_this->invokeHook('update');
  }
}