Code Coverage
 
Classes and Traits
Functions and Methods
Lines
Total
0.00% covered (danger)
0.00%
0 / 1
90.00% covered (success)
90.00%
9 / 10
CRAP
97.83% covered (success)
97.83%
45 / 46
StaticMenuLinkOverrides
0.00% covered (danger)
0.00%
0 / 1
90.00% covered (success)
90.00%
9 / 10
21
97.83% covered (success)
97.83%
45 / 46
 __construct
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
2 / 2
 getConfig
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
3 / 3
 reload
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
3 / 3
 loadOverride
100.00% covered (success)
100.00%
1 / 1
3
100.00% covered (success)
100.00%
3 / 3
 deleteMultipleOverrides
100.00% covered (success)
100.00%
1 / 1
4
100.00% covered (success)
100.00%
10 / 10
 deleteOverride
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
 loadMultipleOverrides
100.00% covered (success)
100.00%
1 / 1
5
100.00% covered (success)
100.00%
8 / 8
 saveOverride
100.00% covered (success)
100.00%
1 / 1
2
100.00% covered (success)
100.00%
14 / 14
 getCacheTags
0.00% covered (danger)
0.00%
0 / 1
2
0.00% covered (danger)
0.00%
0 / 1
 encodeId
100.00% covered (success)
100.00%
1 / 1
1
100.00% covered (success)
100.00%
1 / 1
<?php
/**
 * @file
 * Contains \Drupal\Core\Menu\StaticMenuLinkOverrides.
 */
namespace Drupal\Core\Menu;
use Drupal\Core\Config\ConfigFactoryInterface;
/**
 * Defines an implementation of the menu link override using a config file.
 */
class StaticMenuLinkOverrides implements StaticMenuLinkOverridesInterface {
  /**
   * The config name used to store the overrides.
   *
   * This configuration can not be overridden by configuration overrides because
   * menu links and these overrides are cached in a way that is not override
   * aware.
   *
   * @var string
   */
  protected $configName = 'core.menu.static_menu_link_overrides';
  /**
   * The menu link overrides config object.
   *
   * @var \Drupal\Core\Config\Config
   */
  protected $config;
  /**
   * The config factory object.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;
  /**
   * Constructs a StaticMenuLinkOverrides object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   A configuration factory instance.
   */
  public function __construct(ConfigFactoryInterface $config_factory) {
    $this->configFactory = $config_factory;
  }
  /**
   * Gets the configuration object when needed.
   *
   * Since this service is injected into all static menu link objects, but
   * only used when updating one, avoid actually loading the config when it's
   * not needed.
   */
  protected function getConfig() {
    if (empty($this->config)) {
      // Get an override free and editable configuration object.
      $this->config = $this->configFactory->getEditable($this->configName);
    }
    return $this->config;
  }
  /**
   * {@inheritdoc}
   */
  public function reload() {
    $this->config = NULL;
    $this->configFactory->reset($this->configName);
  }
  /**
   * {@inheritdoc}
   */
  public function loadOverride($id) {
    $all_overrides = $this->getConfig()->get('definitions');
    $id = static::encodeId($id);
    return $id && isset($all_overrides[$id]) ? $all_overrides[$id] : array();
  }
  /**
   * {@inheritdoc}
   */
  public function deleteMultipleOverrides(array $ids) {
    $all_overrides = $this->getConfig()->get('definitions');
    $save = FALSE;
    foreach ($ids as $id) {
      $id = static::encodeId($id);
      if (isset($all_overrides[$id])) {
        unset($all_overrides[$id]);
        $save = TRUE;
      }
    }
    if ($save) {
      $this->getConfig()->set('definitions', $all_overrides)->save();
    }
    return $save;
  }
  /**
   * {@inheritdoc}
   */
  public function deleteOverride($id) {
    return $this->deleteMultipleOverrides(array($id));
  }
  /**
   * {@inheritdoc}
   */
  public function loadMultipleOverrides(array $ids) {
    $result = array();
    if ($ids) {
      $all_overrides = $this->getConfig()->get('definitions') ?: array();
      foreach ($ids as $id) {
        $encoded_id = static::encodeId($id);
        if (isset($all_overrides[$encoded_id])) {
          $result[$id] = $all_overrides[$encoded_id];
        }
      }
    }
    return $result;
  }
  /**
   * {@inheritdoc}
   */
  public function saveOverride($id, array $definition) {
    // Only allow to override a specific subset of the keys.
    $expected = array(
      'menu_name' => '',
      'parent' => '',
      'weight' => 0,
      'expanded' => FALSE,
      'enabled' => FALSE,
    );
    // Filter the overrides to only those that are expected.
    $definition = array_intersect_key($definition, $expected);
    // Ensure all values are set.
    $definition = $definition + $expected;
    if ($definition) {
      // Cast keys to avoid config schema during save.
      $definition['menu_name'] = (string) $definition['menu_name'];
      $definition['parent'] = (string) $definition['parent'];
      $definition['weight'] = (int) $definition['weight'];
      $definition['expanded'] = (bool) $definition['expanded'];
      $definition['enabled'] = (bool) $definition['enabled'];
      $id = static::encodeId($id);
      $all_overrides = $this->getConfig()->get('definitions');
      // Combine with any existing data.
      $all_overrides[$id] = $definition + $this->loadOverride($id);
      $this->getConfig()->set('definitions', $all_overrides)->save(TRUE);
    }
    return array_keys($definition);
  }
  /**
   * {@inheritdoc}
   */
  public function getCacheTags() {
    return $this->getConfig()->getCacheTags();
  }
  /**
   * Encodes the ID by replacing dots with double underscores.
   *
   * This is done because config schema uses dots for its internal type
   * hierarchy. Double underscores are converted to triple underscores to
   * avoid accidental conflicts.
   *
   * @param string $id
   *   The menu plugin ID.
   *
   * @return string
   *   The menu plugin ID with double underscore instead of dots.
   */
  protected static function encodeId($id) {
    return strtr($id, array('.' => '__', '__' => '___'));
  }
}