Chris@0
|
1 <?php
|
Chris@0
|
2
|
Chris@0
|
3 namespace Drupal\Core\Block;
|
Chris@0
|
4
|
Chris@0
|
5 use Drupal\Core\Access\AccessResult;
|
Chris@0
|
6 use Drupal\Core\Form\FormStateInterface;
|
Chris@17
|
7 use Drupal\Core\Messenger\MessengerTrait;
|
Chris@0
|
8 use Drupal\Core\Plugin\ContextAwarePluginAssignmentTrait;
|
Chris@0
|
9 use Drupal\Core\Plugin\ContextAwarePluginBase;
|
Chris@0
|
10 use Drupal\Component\Utility\NestedArray;
|
Chris@0
|
11 use Drupal\Core\Language\LanguageInterface;
|
Chris@0
|
12 use Drupal\Core\Plugin\PluginWithFormsInterface;
|
Chris@0
|
13 use Drupal\Core\Plugin\PluginWithFormsTrait;
|
Chris@17
|
14 use Drupal\Core\Render\PreviewFallbackInterface;
|
Chris@0
|
15 use Drupal\Core\Session\AccountInterface;
|
Chris@0
|
16 use Drupal\Component\Transliteration\TransliterationInterface;
|
Chris@0
|
17
|
Chris@0
|
18 /**
|
Chris@0
|
19 * Defines a base block implementation that most blocks plugins will extend.
|
Chris@0
|
20 *
|
Chris@0
|
21 * This abstract class provides the generic block configuration form, default
|
Chris@0
|
22 * block settings, and handling for general user-defined block visibility
|
Chris@0
|
23 * settings.
|
Chris@0
|
24 *
|
Chris@0
|
25 * @ingroup block_api
|
Chris@0
|
26 */
|
Chris@17
|
27 abstract class BlockBase extends ContextAwarePluginBase implements BlockPluginInterface, PluginWithFormsInterface, PreviewFallbackInterface {
|
Chris@0
|
28
|
Chris@0
|
29 use ContextAwarePluginAssignmentTrait;
|
Chris@17
|
30 use MessengerTrait;
|
Chris@0
|
31 use PluginWithFormsTrait;
|
Chris@0
|
32
|
Chris@0
|
33 /**
|
Chris@0
|
34 * The transliteration service.
|
Chris@0
|
35 *
|
Chris@0
|
36 * @var \Drupal\Component\Transliteration\TransliterationInterface
|
Chris@0
|
37 */
|
Chris@0
|
38 protected $transliteration;
|
Chris@0
|
39
|
Chris@0
|
40 /**
|
Chris@0
|
41 * {@inheritdoc}
|
Chris@0
|
42 */
|
Chris@0
|
43 public function label() {
|
Chris@0
|
44 if (!empty($this->configuration['label'])) {
|
Chris@0
|
45 return $this->configuration['label'];
|
Chris@0
|
46 }
|
Chris@0
|
47
|
Chris@0
|
48 $definition = $this->getPluginDefinition();
|
Chris@0
|
49 // Cast the admin label to a string since it is an object.
|
Chris@0
|
50 // @see \Drupal\Core\StringTranslation\TranslatableMarkup
|
Chris@0
|
51 return (string) $definition['admin_label'];
|
Chris@0
|
52 }
|
Chris@0
|
53
|
Chris@0
|
54 /**
|
Chris@0
|
55 * {@inheritdoc}
|
Chris@0
|
56 */
|
Chris@0
|
57 public function __construct(array $configuration, $plugin_id, $plugin_definition) {
|
Chris@0
|
58 parent::__construct($configuration, $plugin_id, $plugin_definition);
|
Chris@0
|
59 $this->setConfiguration($configuration);
|
Chris@0
|
60 }
|
Chris@0
|
61
|
Chris@0
|
62 /**
|
Chris@0
|
63 * {@inheritdoc}
|
Chris@0
|
64 */
|
Chris@0
|
65 public function getConfiguration() {
|
Chris@0
|
66 return $this->configuration;
|
Chris@0
|
67 }
|
Chris@0
|
68
|
Chris@0
|
69 /**
|
Chris@0
|
70 * {@inheritdoc}
|
Chris@0
|
71 */
|
Chris@0
|
72 public function setConfiguration(array $configuration) {
|
Chris@0
|
73 $this->configuration = NestedArray::mergeDeep(
|
Chris@0
|
74 $this->baseConfigurationDefaults(),
|
Chris@0
|
75 $this->defaultConfiguration(),
|
Chris@0
|
76 $configuration
|
Chris@0
|
77 );
|
Chris@0
|
78 }
|
Chris@0
|
79
|
Chris@0
|
80 /**
|
Chris@0
|
81 * Returns generic default configuration for block plugins.
|
Chris@0
|
82 *
|
Chris@0
|
83 * @return array
|
Chris@0
|
84 * An associative array with the default configuration.
|
Chris@0
|
85 */
|
Chris@0
|
86 protected function baseConfigurationDefaults() {
|
Chris@0
|
87 return [
|
Chris@0
|
88 'id' => $this->getPluginId(),
|
Chris@0
|
89 'label' => '',
|
Chris@0
|
90 'provider' => $this->pluginDefinition['provider'],
|
Chris@0
|
91 'label_display' => static::BLOCK_LABEL_VISIBLE,
|
Chris@0
|
92 ];
|
Chris@0
|
93 }
|
Chris@0
|
94
|
Chris@0
|
95 /**
|
Chris@0
|
96 * {@inheritdoc}
|
Chris@0
|
97 */
|
Chris@0
|
98 public function defaultConfiguration() {
|
Chris@0
|
99 return [];
|
Chris@0
|
100 }
|
Chris@0
|
101
|
Chris@0
|
102 /**
|
Chris@0
|
103 * {@inheritdoc}
|
Chris@0
|
104 */
|
Chris@0
|
105 public function setConfigurationValue($key, $value) {
|
Chris@0
|
106 $this->configuration[$key] = $value;
|
Chris@0
|
107 }
|
Chris@0
|
108
|
Chris@0
|
109 /**
|
Chris@0
|
110 * {@inheritdoc}
|
Chris@0
|
111 */
|
Chris@0
|
112 public function calculateDependencies() {
|
Chris@0
|
113 return [];
|
Chris@0
|
114 }
|
Chris@0
|
115
|
Chris@0
|
116 /**
|
Chris@0
|
117 * {@inheritdoc}
|
Chris@0
|
118 */
|
Chris@0
|
119 public function access(AccountInterface $account, $return_as_object = FALSE) {
|
Chris@0
|
120 $access = $this->blockAccess($account);
|
Chris@0
|
121 return $return_as_object ? $access : $access->isAllowed();
|
Chris@0
|
122 }
|
Chris@0
|
123
|
Chris@0
|
124 /**
|
Chris@0
|
125 * Indicates whether the block should be shown.
|
Chris@0
|
126 *
|
Chris@0
|
127 * Blocks with specific access checking should override this method rather
|
Chris@0
|
128 * than access(), in order to avoid repeating the handling of the
|
Chris@0
|
129 * $return_as_object argument.
|
Chris@0
|
130 *
|
Chris@0
|
131 * @param \Drupal\Core\Session\AccountInterface $account
|
Chris@0
|
132 * The user session for which to check access.
|
Chris@0
|
133 *
|
Chris@0
|
134 * @return \Drupal\Core\Access\AccessResult
|
Chris@0
|
135 * The access result.
|
Chris@0
|
136 *
|
Chris@0
|
137 * @see self::access()
|
Chris@0
|
138 */
|
Chris@0
|
139 protected function blockAccess(AccountInterface $account) {
|
Chris@0
|
140 // By default, the block is visible.
|
Chris@0
|
141 return AccessResult::allowed();
|
Chris@0
|
142 }
|
Chris@0
|
143
|
Chris@0
|
144 /**
|
Chris@0
|
145 * {@inheritdoc}
|
Chris@0
|
146 *
|
Chris@0
|
147 * Creates a generic configuration form for all block types. Individual
|
Chris@0
|
148 * block plugins can add elements to this form by overriding
|
Chris@0
|
149 * BlockBase::blockForm(). Most block plugins should not override this
|
Chris@0
|
150 * method unless they need to alter the generic form elements.
|
Chris@0
|
151 *
|
Chris@0
|
152 * @see \Drupal\Core\Block\BlockBase::blockForm()
|
Chris@0
|
153 */
|
Chris@0
|
154 public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
|
Chris@0
|
155 $definition = $this->getPluginDefinition();
|
Chris@0
|
156 $form['provider'] = [
|
Chris@0
|
157 '#type' => 'value',
|
Chris@0
|
158 '#value' => $definition['provider'],
|
Chris@0
|
159 ];
|
Chris@0
|
160
|
Chris@0
|
161 $form['admin_label'] = [
|
Chris@0
|
162 '#type' => 'item',
|
Chris@0
|
163 '#title' => $this->t('Block description'),
|
Chris@0
|
164 '#plain_text' => $definition['admin_label'],
|
Chris@0
|
165 ];
|
Chris@0
|
166 $form['label'] = [
|
Chris@0
|
167 '#type' => 'textfield',
|
Chris@0
|
168 '#title' => $this->t('Title'),
|
Chris@0
|
169 '#maxlength' => 255,
|
Chris@0
|
170 '#default_value' => $this->label(),
|
Chris@0
|
171 '#required' => TRUE,
|
Chris@0
|
172 ];
|
Chris@0
|
173 $form['label_display'] = [
|
Chris@0
|
174 '#type' => 'checkbox',
|
Chris@0
|
175 '#title' => $this->t('Display title'),
|
Chris@0
|
176 '#default_value' => ($this->configuration['label_display'] === static::BLOCK_LABEL_VISIBLE),
|
Chris@0
|
177 '#return_value' => static::BLOCK_LABEL_VISIBLE,
|
Chris@0
|
178 ];
|
Chris@0
|
179
|
Chris@0
|
180 // Add context mapping UI form elements.
|
Chris@0
|
181 $contexts = $form_state->getTemporaryValue('gathered_contexts') ?: [];
|
Chris@0
|
182 $form['context_mapping'] = $this->addContextAssignmentElement($this, $contexts);
|
Chris@0
|
183 // Add plugin-specific settings for this block type.
|
Chris@0
|
184 $form += $this->blockForm($form, $form_state);
|
Chris@0
|
185 return $form;
|
Chris@0
|
186 }
|
Chris@0
|
187
|
Chris@0
|
188 /**
|
Chris@0
|
189 * {@inheritdoc}
|
Chris@0
|
190 */
|
Chris@0
|
191 public function blockForm($form, FormStateInterface $form_state) {
|
Chris@0
|
192 return [];
|
Chris@0
|
193 }
|
Chris@0
|
194
|
Chris@0
|
195 /**
|
Chris@0
|
196 * {@inheritdoc}
|
Chris@0
|
197 *
|
Chris@0
|
198 * Most block plugins should not override this method. To add validation
|
Chris@0
|
199 * for a specific block type, override BlockBase::blockValidate().
|
Chris@0
|
200 *
|
Chris@0
|
201 * @see \Drupal\Core\Block\BlockBase::blockValidate()
|
Chris@0
|
202 */
|
Chris@0
|
203 public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
|
Chris@0
|
204 // Remove the admin_label form item element value so it will not persist.
|
Chris@0
|
205 $form_state->unsetValue('admin_label');
|
Chris@0
|
206
|
Chris@0
|
207 $this->blockValidate($form, $form_state);
|
Chris@0
|
208 }
|
Chris@0
|
209
|
Chris@0
|
210 /**
|
Chris@0
|
211 * {@inheritdoc}
|
Chris@0
|
212 */
|
Chris@0
|
213 public function blockValidate($form, FormStateInterface $form_state) {}
|
Chris@0
|
214
|
Chris@0
|
215 /**
|
Chris@0
|
216 * {@inheritdoc}
|
Chris@0
|
217 *
|
Chris@0
|
218 * Most block plugins should not override this method. To add submission
|
Chris@0
|
219 * handling for a specific block type, override BlockBase::blockSubmit().
|
Chris@0
|
220 *
|
Chris@0
|
221 * @see \Drupal\Core\Block\BlockBase::blockSubmit()
|
Chris@0
|
222 */
|
Chris@0
|
223 public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
|
Chris@0
|
224 // Process the block's submission handling if no errors occurred only.
|
Chris@0
|
225 if (!$form_state->getErrors()) {
|
Chris@0
|
226 $this->configuration['label'] = $form_state->getValue('label');
|
Chris@0
|
227 $this->configuration['label_display'] = $form_state->getValue('label_display');
|
Chris@0
|
228 $this->configuration['provider'] = $form_state->getValue('provider');
|
Chris@0
|
229 $this->blockSubmit($form, $form_state);
|
Chris@0
|
230 }
|
Chris@0
|
231 }
|
Chris@0
|
232
|
Chris@0
|
233 /**
|
Chris@0
|
234 * {@inheritdoc}
|
Chris@0
|
235 */
|
Chris@0
|
236 public function blockSubmit($form, FormStateInterface $form_state) {}
|
Chris@0
|
237
|
Chris@0
|
238 /**
|
Chris@0
|
239 * {@inheritdoc}
|
Chris@0
|
240 */
|
Chris@0
|
241 public function getMachineNameSuggestion() {
|
Chris@0
|
242 $definition = $this->getPluginDefinition();
|
Chris@0
|
243 $admin_label = $definition['admin_label'];
|
Chris@0
|
244
|
Chris@0
|
245 // @todo This is basically the same as what is done in
|
Chris@0
|
246 // \Drupal\system\MachineNameController::transliterate(), so it might make
|
Chris@0
|
247 // sense to provide a common service for the two.
|
Chris@0
|
248 $transliterated = $this->transliteration()->transliterate($admin_label, LanguageInterface::LANGCODE_DEFAULT, '_');
|
Chris@17
|
249 $transliterated = mb_strtolower($transliterated);
|
Chris@0
|
250
|
Chris@0
|
251 $transliterated = preg_replace('@[^a-z0-9_.]+@', '', $transliterated);
|
Chris@0
|
252
|
Chris@0
|
253 return $transliterated;
|
Chris@0
|
254 }
|
Chris@0
|
255
|
Chris@0
|
256 /**
|
Chris@17
|
257 * {@inheritdoc}
|
Chris@17
|
258 */
|
Chris@17
|
259 public function getPreviewFallbackString() {
|
Chris@18
|
260 return $this->t('"@block" block', ['@block' => $this->label()]);
|
Chris@17
|
261 }
|
Chris@17
|
262
|
Chris@17
|
263 /**
|
Chris@0
|
264 * Wraps the transliteration service.
|
Chris@0
|
265 *
|
Chris@0
|
266 * @return \Drupal\Component\Transliteration\TransliterationInterface
|
Chris@0
|
267 */
|
Chris@0
|
268 protected function transliteration() {
|
Chris@0
|
269 if (!$this->transliteration) {
|
Chris@0
|
270 $this->transliteration = \Drupal::transliteration();
|
Chris@0
|
271 }
|
Chris@0
|
272 return $this->transliteration;
|
Chris@0
|
273 }
|
Chris@0
|
274
|
Chris@0
|
275 /**
|
Chris@0
|
276 * Sets the transliteration service.
|
Chris@0
|
277 *
|
Chris@0
|
278 * @param \Drupal\Component\Transliteration\TransliterationInterface $transliteration
|
Chris@0
|
279 * The transliteration service.
|
Chris@0
|
280 */
|
Chris@0
|
281 public function setTransliteration(TransliterationInterface $transliteration) {
|
Chris@0
|
282 $this->transliteration = $transliteration;
|
Chris@0
|
283 }
|
Chris@0
|
284
|
Chris@0
|
285 }
|