comparison core/lib/Drupal/Core/Menu/StaticMenuLinkOverrides.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:4c8ae668cc8c
1 <?php
2
3 namespace Drupal\Core\Menu;
4
5 use Drupal\Core\Config\ConfigFactoryInterface;
6
7 /**
8 * Defines an implementation of the menu link override using a config file.
9 */
10 class StaticMenuLinkOverrides implements StaticMenuLinkOverridesInterface {
11
12 /**
13 * The config name used to store the overrides.
14 *
15 * This configuration can not be overridden by configuration overrides because
16 * menu links and these overrides are cached in a way that is not override
17 * aware.
18 *
19 * @var string
20 */
21 protected $configName = 'core.menu.static_menu_link_overrides';
22
23 /**
24 * The menu link overrides config object.
25 *
26 * @var \Drupal\Core\Config\Config
27 */
28 protected $config;
29
30 /**
31 * The config factory object.
32 *
33 * @var \Drupal\Core\Config\ConfigFactoryInterface
34 */
35 protected $configFactory;
36
37 /**
38 * Constructs a StaticMenuLinkOverrides object.
39 *
40 * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
41 * A configuration factory instance.
42 */
43 public function __construct(ConfigFactoryInterface $config_factory) {
44 $this->configFactory = $config_factory;
45 }
46
47 /**
48 * Gets the configuration object when needed.
49 *
50 * Since this service is injected into all static menu link objects, but
51 * only used when updating one, avoid actually loading the config when it's
52 * not needed.
53 */
54 protected function getConfig() {
55 if (empty($this->config)) {
56 // Get an override free and editable configuration object.
57 $this->config = $this->configFactory->getEditable($this->configName);
58 }
59 return $this->config;
60 }
61
62 /**
63 * {@inheritdoc}
64 */
65 public function reload() {
66 $this->config = NULL;
67 $this->configFactory->reset($this->configName);
68 }
69
70 /**
71 * {@inheritdoc}
72 */
73 public function loadOverride($id) {
74 $all_overrides = $this->getConfig()->get('definitions');
75 $id = static::encodeId($id);
76 return $id && isset($all_overrides[$id]) ? $all_overrides[$id] : [];
77 }
78
79 /**
80 * {@inheritdoc}
81 */
82 public function deleteMultipleOverrides(array $ids) {
83 $all_overrides = $this->getConfig()->get('definitions');
84 $save = FALSE;
85 foreach ($ids as $id) {
86 $id = static::encodeId($id);
87 if (isset($all_overrides[$id])) {
88 unset($all_overrides[$id]);
89 $save = TRUE;
90 }
91 }
92 if ($save) {
93 $this->getConfig()->set('definitions', $all_overrides)->save();
94 }
95 return $save;
96 }
97
98 /**
99 * {@inheritdoc}
100 */
101 public function deleteOverride($id) {
102 return $this->deleteMultipleOverrides([$id]);
103 }
104
105 /**
106 * {@inheritdoc}
107 */
108 public function loadMultipleOverrides(array $ids) {
109 $result = [];
110 if ($ids) {
111 $all_overrides = $this->getConfig()->get('definitions') ?: [];
112 foreach ($ids as $id) {
113 $encoded_id = static::encodeId($id);
114 if (isset($all_overrides[$encoded_id])) {
115 $result[$id] = $all_overrides[$encoded_id];
116 }
117 }
118 }
119 return $result;
120 }
121
122 /**
123 * {@inheritdoc}
124 */
125 public function saveOverride($id, array $definition) {
126 // Only allow to override a specific subset of the keys.
127 $expected = [
128 'menu_name' => '',
129 'parent' => '',
130 'weight' => 0,
131 'expanded' => FALSE,
132 'enabled' => FALSE,
133 ];
134 // Filter the overrides to only those that are expected.
135 $definition = array_intersect_key($definition, $expected);
136 // Ensure all values are set.
137 $definition = $definition + $expected;
138 if ($definition) {
139 // Cast keys to avoid config schema during save.
140 $definition['menu_name'] = (string) $definition['menu_name'];
141 $definition['parent'] = (string) $definition['parent'];
142 $definition['weight'] = (int) $definition['weight'];
143 $definition['expanded'] = (bool) $definition['expanded'];
144 $definition['enabled'] = (bool) $definition['enabled'];
145
146 $id = static::encodeId($id);
147 $all_overrides = $this->getConfig()->get('definitions');
148 // Combine with any existing data.
149 $all_overrides[$id] = $definition + $this->loadOverride($id);
150 $this->getConfig()->set('definitions', $all_overrides)->save(TRUE);
151 }
152 return array_keys($definition);
153 }
154
155 /**
156 * {@inheritdoc}
157 */
158 public function getCacheTags() {
159 return $this->getConfig()->getCacheTags();
160 }
161
162 /**
163 * Encodes the ID by replacing dots with double underscores.
164 *
165 * This is done because config schema uses dots for its internal type
166 * hierarchy. Double underscores are converted to triple underscores to
167 * avoid accidental conflicts.
168 *
169 * @param string $id
170 * The menu plugin ID.
171 *
172 * @return string
173 * The menu plugin ID with double underscore instead of dots.
174 */
175 protected static function encodeId($id) {
176 return strtr($id, ['.' => '__', '__' => '___']);
177 }
178
179 }