Pull merge.
[yaffs-website] / web / core / modules / block / src / Entity / Block.php
1 <?php
2
3 namespace Drupal\block\Entity;
4
5 use Drupal\Core\Cache\Cache;
6 use Drupal\Core\Condition\ConditionPluginCollection;
7 use Drupal\Core\Config\Entity\ConfigEntityBase;
8 use Drupal\block\BlockPluginCollection;
9 use Drupal\block\BlockInterface;
10 use Drupal\Core\Config\Entity\ConfigEntityInterface;
11 use Drupal\Core\Entity\EntityWithPluginCollectionInterface;
12 use Drupal\Core\Entity\EntityStorageInterface;
13
14 /**
15  * Defines a Block configuration entity class.
16  *
17  * @ConfigEntityType(
18  *   id = "block",
19  *   label = @Translation("Block"),
20  *   label_collection = @Translation("Blocks"),
21  *   label_singular = @Translation("block"),
22  *   label_plural = @Translation("blocks"),
23  *   label_count = @PluralTranslation(
24  *     singular = "@count block",
25  *     plural = "@count blocks",
26  *   ),
27  *   handlers = {
28  *     "access" = "Drupal\block\BlockAccessControlHandler",
29  *     "view_builder" = "Drupal\block\BlockViewBuilder",
30  *     "list_builder" = "Drupal\block\BlockListBuilder",
31  *     "form" = {
32  *       "default" = "Drupal\block\BlockForm",
33  *       "delete" = "Drupal\block\Form\BlockDeleteForm"
34  *     }
35  *   },
36  *   admin_permission = "administer blocks",
37  *   entity_keys = {
38  *     "id" = "id",
39  *     "status" = "status"
40  *   },
41  *   links = {
42  *     "delete-form" = "/admin/structure/block/manage/{block}/delete",
43  *     "edit-form" = "/admin/structure/block/manage/{block}",
44  *     "enable" = "/admin/structure/block/manage/{block}/enable",
45  *     "disable" = "/admin/structure/block/manage/{block}/disable",
46  *   },
47  *   config_export = {
48  *     "id",
49  *     "theme",
50  *     "region",
51  *     "weight",
52  *     "provider",
53  *     "plugin",
54  *     "settings",
55  *     "visibility",
56  *   },
57  *   lookup_keys = {
58  *     "theme"
59  *   }
60  * )
61  */
62 class Block extends ConfigEntityBase implements BlockInterface, EntityWithPluginCollectionInterface {
63
64   /**
65    * The ID of the block.
66    *
67    * @var string
68    */
69   protected $id;
70
71   /**
72    * The plugin instance settings.
73    *
74    * @var array
75    */
76   protected $settings = [];
77
78   /**
79    * The region this block is placed in.
80    *
81    * @var string
82    */
83   protected $region;
84
85   /**
86    * The block weight.
87    *
88    * @var int
89    */
90   protected $weight;
91
92   /**
93    * The plugin instance ID.
94    *
95    * @var string
96    */
97   protected $plugin;
98
99   /**
100    * The visibility settings for this block.
101    *
102    * @var array
103    */
104   protected $visibility = [];
105
106   /**
107    * The plugin collection that holds the block plugin for this entity.
108    *
109    * @var \Drupal\block\BlockPluginCollection
110    */
111   protected $pluginCollection;
112
113   /**
114    * The available contexts for this block and its visibility conditions.
115    *
116    * @var array
117    */
118   protected $contexts = [];
119
120   /**
121    * The visibility collection.
122    *
123    * @var \Drupal\Core\Condition\ConditionPluginCollection
124    */
125   protected $visibilityCollection;
126
127   /**
128    * The condition plugin manager.
129    *
130    * @var \Drupal\Core\Executable\ExecutableManagerInterface
131    */
132   protected $conditionPluginManager;
133
134   /**
135    * The theme that includes the block plugin for this entity.
136    *
137    * @var string
138    */
139   protected $theme;
140
141   /**
142    * {@inheritdoc}
143    */
144   public function getPlugin() {
145     return $this->getPluginCollection()->get($this->plugin);
146   }
147
148   /**
149    * Encapsulates the creation of the block's LazyPluginCollection.
150    *
151    * @return \Drupal\Component\Plugin\LazyPluginCollection
152    *   The block's plugin collection.
153    */
154   protected function getPluginCollection() {
155     if (!$this->pluginCollection) {
156       $this->pluginCollection = new BlockPluginCollection(\Drupal::service('plugin.manager.block'), $this->plugin, $this->get('settings'), $this->id());
157     }
158     return $this->pluginCollection;
159   }
160
161   /**
162    * {@inheritdoc}
163    */
164   public function getPluginCollections() {
165     return [
166       'settings' => $this->getPluginCollection(),
167       'visibility' => $this->getVisibilityConditions(),
168     ];
169   }
170
171   /**
172    * {@inheritdoc}
173    */
174   public function getPluginId() {
175     return $this->plugin;
176   }
177
178   /**
179    * {@inheritdoc}
180    */
181   public function getRegion() {
182     return $this->region;
183   }
184
185   /**
186    * {@inheritdoc}
187    */
188   public function getTheme() {
189     return $this->theme;
190   }
191
192   /**
193    * {@inheritdoc}
194    */
195   public function getWeight() {
196     return $this->weight;
197   }
198
199   /**
200    * {@inheritdoc}
201    */
202   public function label() {
203     $settings = $this->get('settings');
204     if ($settings['label']) {
205       return $settings['label'];
206     }
207     else {
208       $definition = $this->getPlugin()->getPluginDefinition();
209       return $definition['admin_label'];
210     }
211   }
212
213   /**
214    * Sorts active blocks by weight; sorts inactive blocks by name.
215    */
216   public static function sort(ConfigEntityInterface $a, ConfigEntityInterface $b) {
217     // Separate enabled from disabled.
218     $status = (int) $b->status() - (int) $a->status();
219     if ($status !== 0) {
220       return $status;
221     }
222
223     // Sort by weight.
224     $weight = $a->getWeight() - $b->getWeight();
225     if ($weight) {
226       return $weight;
227     }
228
229     // Sort by label.
230     return strcmp($a->label(), $b->label());
231   }
232
233   /**
234    * {@inheritdoc}
235    */
236   public function calculateDependencies() {
237     parent::calculateDependencies();
238     $this->addDependency('theme', $this->theme);
239     return $this;
240   }
241
242   /**
243    * {@inheritdoc}
244    */
245   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
246     parent::postSave($storage, $update);
247
248     // Entity::postSave() calls Entity::invalidateTagsOnSave(), which only
249     // handles the regular cases. The Block entity has one special case: a
250     // newly created block may *also* appear on any page in the current theme,
251     // so we must invalidate the associated block's cache tag (which includes
252     // the theme cache tag).
253     if (!$update) {
254       Cache::invalidateTags($this->getCacheTagsToInvalidate());
255     }
256   }
257
258   /**
259    * {@inheritdoc}
260    */
261   public function getVisibility() {
262     return $this->getVisibilityConditions()->getConfiguration();
263   }
264
265   /**
266    * {@inheritdoc}
267    */
268   public function setVisibilityConfig($instance_id, array $configuration) {
269     $conditions = $this->getVisibilityConditions();
270     if (!$conditions->has($instance_id)) {
271       $configuration['id'] = $instance_id;
272       $conditions->addInstanceId($instance_id, $configuration);
273     }
274     else {
275       $conditions->setInstanceConfiguration($instance_id, $configuration);
276     }
277     return $this;
278   }
279
280   /**
281    * {@inheritdoc}
282    */
283   public function getVisibilityConditions() {
284     if (!isset($this->visibilityCollection)) {
285       $this->visibilityCollection = new ConditionPluginCollection($this->conditionPluginManager(), $this->get('visibility'));
286     }
287     return $this->visibilityCollection;
288   }
289
290   /**
291    * {@inheritdoc}
292    */
293   public function getVisibilityCondition($instance_id) {
294     return $this->getVisibilityConditions()->get($instance_id);
295   }
296
297   /**
298    * Gets the condition plugin manager.
299    *
300    * @return \Drupal\Core\Executable\ExecutableManagerInterface
301    *   The condition plugin manager.
302    */
303   protected function conditionPluginManager() {
304     if (!isset($this->conditionPluginManager)) {
305       $this->conditionPluginManager = \Drupal::service('plugin.manager.condition');
306     }
307     return $this->conditionPluginManager;
308   }
309
310   /**
311    * {@inheritdoc}
312    */
313   public function setRegion($region) {
314     $this->region = $region;
315     return $this;
316   }
317
318   /**
319    * {@inheritdoc}
320    */
321   public function setWeight($weight) {
322     $this->weight = $weight;
323     return $this;
324   }
325
326   /**
327    * {@inheritdoc}
328    */
329   public function createDuplicateBlock($new_id = NULL, $new_theme = NULL) {
330     $duplicate = parent::createDuplicate();
331     if (!empty($new_id)) {
332       $duplicate->id = $new_id;
333     }
334     if (!empty($new_theme)) {
335       $duplicate->theme = $new_theme;
336     }
337     return $duplicate;
338   }
339
340   /**
341    * {@inheritdoc}
342    */
343   public function preSave(EntityStorageInterface $storage) {
344     parent::preSave($storage);
345
346     // Ensure the region is valid to mirror the behavior of block_rebuild().
347     // This is done primarily for backwards compatibility support of
348     // \Drupal\block\BlockInterface::BLOCK_REGION_NONE.
349     $regions = system_region_list($this->theme);
350     if (!isset($regions[$this->region]) && $this->status()) {
351       $this
352         ->setRegion(system_default_region($this->theme))
353         ->disable();
354     }
355   }
356
357 }