Chris@0: configFactory = $config_factory; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the configuration object when needed. Chris@0: * Chris@0: * Since this service is injected into all static menu link objects, but Chris@0: * only used when updating one, avoid actually loading the config when it's Chris@0: * not needed. Chris@0: */ Chris@0: protected function getConfig() { Chris@0: if (empty($this->config)) { Chris@0: // Get an override free and editable configuration object. Chris@0: $this->config = $this->configFactory->getEditable($this->configName); Chris@0: } Chris@0: return $this->config; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function reload() { Chris@0: $this->config = NULL; Chris@0: $this->configFactory->reset($this->configName); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function loadOverride($id) { Chris@0: $all_overrides = $this->getConfig()->get('definitions'); Chris@0: $id = static::encodeId($id); Chris@0: return $id && isset($all_overrides[$id]) ? $all_overrides[$id] : []; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function deleteMultipleOverrides(array $ids) { Chris@0: $all_overrides = $this->getConfig()->get('definitions'); Chris@0: $save = FALSE; Chris@0: foreach ($ids as $id) { Chris@0: $id = static::encodeId($id); Chris@0: if (isset($all_overrides[$id])) { Chris@0: unset($all_overrides[$id]); Chris@0: $save = TRUE; Chris@0: } Chris@0: } Chris@0: if ($save) { Chris@0: $this->getConfig()->set('definitions', $all_overrides)->save(); Chris@0: } Chris@0: return $save; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function deleteOverride($id) { Chris@0: return $this->deleteMultipleOverrides([$id]); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function loadMultipleOverrides(array $ids) { Chris@0: $result = []; Chris@0: if ($ids) { Chris@0: $all_overrides = $this->getConfig()->get('definitions') ?: []; Chris@0: foreach ($ids as $id) { Chris@0: $encoded_id = static::encodeId($id); Chris@0: if (isset($all_overrides[$encoded_id])) { Chris@0: $result[$id] = $all_overrides[$encoded_id]; Chris@0: } Chris@0: } Chris@0: } Chris@0: return $result; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function saveOverride($id, array $definition) { Chris@0: // Only allow to override a specific subset of the keys. Chris@0: $expected = [ Chris@0: 'menu_name' => '', Chris@0: 'parent' => '', Chris@0: 'weight' => 0, Chris@0: 'expanded' => FALSE, Chris@0: 'enabled' => FALSE, Chris@0: ]; Chris@0: // Filter the overrides to only those that are expected. Chris@0: $definition = array_intersect_key($definition, $expected); Chris@0: // Ensure all values are set. Chris@0: $definition = $definition + $expected; Chris@0: if ($definition) { Chris@0: // Cast keys to avoid config schema during save. Chris@0: $definition['menu_name'] = (string) $definition['menu_name']; Chris@0: $definition['parent'] = (string) $definition['parent']; Chris@0: $definition['weight'] = (int) $definition['weight']; Chris@0: $definition['expanded'] = (bool) $definition['expanded']; Chris@0: $definition['enabled'] = (bool) $definition['enabled']; Chris@0: Chris@0: $id = static::encodeId($id); Chris@0: $all_overrides = $this->getConfig()->get('definitions'); Chris@0: // Combine with any existing data. Chris@0: $all_overrides[$id] = $definition + $this->loadOverride($id); Chris@0: $this->getConfig()->set('definitions', $all_overrides)->save(TRUE); Chris@0: } Chris@0: return array_keys($definition); Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function getCacheTags() { Chris@0: return $this->getConfig()->getCacheTags(); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Encodes the ID by replacing dots with double underscores. Chris@0: * Chris@0: * This is done because config schema uses dots for its internal type Chris@0: * hierarchy. Double underscores are converted to triple underscores to Chris@0: * avoid accidental conflicts. Chris@0: * Chris@0: * @param string $id Chris@0: * The menu plugin ID. Chris@0: * Chris@0: * @return string Chris@0: * The menu plugin ID with double underscore instead of dots. Chris@0: */ Chris@0: protected static function encodeId($id) { Chris@0: return strtr($id, ['.' => '__', '__' => '___']); Chris@0: } Chris@0: Chris@0: }