3 namespace Drupal\field_layout\Entity;
5 use Drupal\Core\Entity\EntityStorageInterface;
6 use Drupal\Core\Layout\LayoutInterface;
9 * Provides shared code for entity displays.
11 * Both EntityViewDisplay and EntityFormDisplay must maintain their parent
12 * hierarchy, while being identically enhanced by Field Layout. This trait
13 * contains the code they both share.
15 trait FieldLayoutEntityDisplayTrait {
18 * Gets a layout definition.
20 * @param string $layout_id
23 * @return \Drupal\Core\Layout\LayoutDefinition
24 * The layout definition.
26 protected function getLayoutDefinition($layout_id) {
27 return \Drupal::service('plugin.manager.core.layout')->getDefinition($layout_id);
31 * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::getLayoutId().
33 public function getLayoutId() {
34 return $this->getThirdPartySetting('field_layout', 'id');
38 * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::getLayoutSettings().
40 public function getLayoutSettings() {
41 return $this->getThirdPartySetting('field_layout', 'settings', []);
45 * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::setLayoutId().
47 public function setLayoutId($layout_id, array $layout_settings = []) {
48 if ($this->getLayoutId() !== $layout_id) {
49 // @todo Devise a mechanism for mapping old regions to new ones in
50 // https://www.drupal.org/node/2796877.
51 $layout_definition = $this->getLayoutDefinition($layout_id);
52 $new_region = $layout_definition->getDefaultRegion();
53 $layout_regions = $layout_definition->getRegions();
54 foreach ($this->getComponents() as $name => $component) {
55 if (isset($component['region']) && !isset($layout_regions[$component['region']])) {
56 $component['region'] = $new_region;
57 $this->setComponent($name, $component);
61 $this->setThirdPartySetting('field_layout', 'id', $layout_id);
62 // Instantiate the plugin and consult it for the updated plugin
63 // configuration. Once layouts are no longer stored as third party settings,
64 // this will be handled by the code in
65 // \Drupal\Core\Config\Entity\ConfigEntityBase::set() that handles
66 // \Drupal\Core\Entity\EntityWithPluginCollectionInterface.
67 $layout_settings = $this->doGetLayout($layout_id, $layout_settings)->getConfiguration();
68 $this->setThirdPartySetting('field_layout', 'settings', $layout_settings);
73 * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::setLayout().
75 public function setLayout(LayoutInterface $layout) {
76 $this->setLayoutId($layout->getPluginId(), $layout->getConfiguration());
81 * Implements \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface::getLayout().
83 public function getLayout() {
84 return $this->doGetLayout($this->getLayoutId(), $this->getLayoutSettings());
88 * Gets the layout plugin.
90 * @param string $layout_id
92 * @param array $layout_settings
93 * An array of settings.
95 * @return \Drupal\Core\Layout\LayoutInterface
98 protected function doGetLayout($layout_id, array $layout_settings) {
99 return \Drupal::service('plugin.manager.core.layout')->createInstance($layout_id, $layout_settings);
103 * Overrides \Drupal\Core\Entity\EntityDisplayBase::init().
105 protected function init() {
106 $this->ensureLayout();
111 * Overrides \Drupal\Core\Entity\EntityDisplayBase::preSave().
113 public function preSave(EntityStorageInterface $storage) {
114 parent::preSave($storage);
116 // Ensure the plugin configuration is updated. Once layouts are no longer
117 // stored as third party settings, this will be handled by the code in
118 // \Drupal\Core\Config\Entity\ConfigEntityBase::preSave() that handles
119 // \Drupal\Core\Entity\EntityWithPluginCollectionInterface.
120 if ($this->getLayoutId()) {
121 $this->setLayout($this->getLayout());
128 public function ensureLayout($default_layout_id = 'layout_onecol') {
129 if (!$this->getLayoutId()) {
130 $this->setLayoutId($default_layout_id);
137 * Overrides \Drupal\Core\Entity\EntityDisplayBase::calculateDependencies().
139 * Ensure the plugin dependencies are included. Once layouts are no longer
140 * stored as third party settings, this will be handled by the code in
141 * \Drupal\Core\Config\Entity\ConfigEntityBase::calculateDependencies() that
142 * handles \Drupal\Core\Entity\EntityWithPluginCollectionInterface.
144 public function calculateDependencies() {
145 parent::calculateDependencies();
147 // This can be called during uninstallation, so check for a valid ID first.
148 if ($this->getLayoutId()) {
149 $this->calculatePluginDependencies($this->getLayout());