"Fossies" - the Fresh Open Source Software Archive

Member "drupal-8.9.10/core/modules/menu_link_content/src/Entity/MenuLinkContent.php" (26 Nov 2020, 13900 Bytes) of package /linux/www/drupal-8.9.10.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) PHP source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "MenuLinkContent.php" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 9.0.8_vs_9.1.0-rc1.

    1 <?php
    2 
    3 namespace Drupal\menu_link_content\Entity;
    4 
    5 use Drupal\Core\Entity\EditorialContentEntityBase;
    6 use Drupal\Core\Entity\EntityStorageInterface;
    7 use Drupal\Core\Entity\EntityTypeInterface;
    8 use Drupal\Core\Field\BaseFieldDefinition;
    9 use Drupal\link\LinkItemInterface;
   10 use Drupal\menu_link_content\MenuLinkContentInterface;
   11 
   12 /**
   13  * Defines the menu link content entity class.
   14  *
   15  * @property \Drupal\link\LinkItemInterface link
   16  * @property \Drupal\Core\Field\FieldItemList rediscover
   17  *
   18  * @ContentEntityType(
   19  *   id = "menu_link_content",
   20  *   label = @Translation("Custom menu link"),
   21  *   label_collection = @Translation("Custom menu links"),
   22  *   label_singular = @Translation("custom menu link"),
   23  *   label_plural = @Translation("custom menu links"),
   24  *   label_count = @PluralTranslation(
   25  *     singular = "@count custom menu link",
   26  *     plural = "@count custom menu links",
   27  *   ),
   28  *   handlers = {
   29  *     "storage" = "\Drupal\menu_link_content\MenuLinkContentStorage",
   30  *     "storage_schema" = "Drupal\menu_link_content\MenuLinkContentStorageSchema",
   31  *     "access" = "Drupal\menu_link_content\MenuLinkContentAccessControlHandler",
   32  *     "form" = {
   33  *       "default" = "Drupal\menu_link_content\Form\MenuLinkContentForm",
   34  *       "delete" = "Drupal\menu_link_content\Form\MenuLinkContentDeleteForm"
   35  *     }
   36  *   },
   37  *   admin_permission = "administer menu",
   38  *   base_table = "menu_link_content",
   39  *   data_table = "menu_link_content_data",
   40  *   revision_table = "menu_link_content_revision",
   41  *   revision_data_table = "menu_link_content_field_revision",
   42  *   translatable = TRUE,
   43  *   entity_keys = {
   44  *     "id" = "id",
   45  *     "revision" = "revision_id",
   46  *     "label" = "title",
   47  *     "langcode" = "langcode",
   48  *     "uuid" = "uuid",
   49  *     "bundle" = "bundle",
   50  *     "published" = "enabled",
   51  *   },
   52  *   revision_metadata_keys = {
   53  *     "revision_user" = "revision_user",
   54  *     "revision_created" = "revision_created",
   55  *     "revision_log_message" = "revision_log_message",
   56  *   },
   57  *   links = {
   58  *     "canonical" = "/admin/structure/menu/item/{menu_link_content}/edit",
   59  *     "edit-form" = "/admin/structure/menu/item/{menu_link_content}/edit",
   60  *     "delete-form" = "/admin/structure/menu/item/{menu_link_content}/delete",
   61  *   },
   62  *   constraints = {
   63  *     "MenuTreeHierarchy" = {}
   64  *   },
   65  * )
   66  */
   67 class MenuLinkContent extends EditorialContentEntityBase implements MenuLinkContentInterface {
   68 
   69   /**
   70    * A flag for whether this entity is wrapped in a plugin instance.
   71    *
   72    * @var bool
   73    */
   74   protected $insidePlugin = FALSE;
   75 
   76   /**
   77    * {@inheritdoc}
   78    */
   79   public function setInsidePlugin() {
   80     $this->insidePlugin = TRUE;
   81   }
   82 
   83   /**
   84    * {@inheritdoc}
   85    */
   86   public function getTitle() {
   87     return $this->get('title')->value;
   88   }
   89 
   90   /**
   91    * {@inheritdoc}
   92    */
   93   public function getUrlObject() {
   94     return $this->link->first()->getUrl();
   95   }
   96 
   97   /**
   98    * {@inheritdoc}
   99    */
  100   public function getMenuName() {
  101     return $this->get('menu_name')->value;
  102   }
  103 
  104   /**
  105    * {@inheritdoc}
  106    */
  107   public function getDescription() {
  108     return $this->get('description')->value;
  109   }
  110 
  111   /**
  112    * {@inheritdoc}
  113    */
  114   public function getPluginId() {
  115     return 'menu_link_content:' . $this->uuid();
  116   }
  117 
  118   /**
  119    * {@inheritdoc}
  120    */
  121   public function isEnabled() {
  122     return (bool) $this->get('enabled')->value;
  123   }
  124 
  125   /**
  126    * {@inheritdoc}
  127    */
  128   public function isExpanded() {
  129     return (bool) $this->get('expanded')->value;
  130   }
  131 
  132   /**
  133    * {@inheritdoc}
  134    */
  135   public function getParentId() {
  136     // Cast the parent ID to a string, only an empty string means no parent,
  137     // NULL keeps the existing parent.
  138     return (string) $this->get('parent')->value;
  139   }
  140 
  141   /**
  142    * {@inheritdoc}
  143    */
  144   public function getWeight() {
  145     return (int) $this->get('weight')->value;
  146   }
  147 
  148   /**
  149    * {@inheritdoc}
  150    */
  151   public function getPluginDefinition() {
  152     $definition = [];
  153     $definition['class'] = 'Drupal\menu_link_content\Plugin\Menu\MenuLinkContent';
  154     $definition['menu_name'] = $this->getMenuName();
  155 
  156     if ($url_object = $this->getUrlObject()) {
  157       $definition['url'] = NULL;
  158       $definition['route_name'] = NULL;
  159       $definition['route_parameters'] = [];
  160       if (!$url_object->isRouted()) {
  161         $definition['url'] = $url_object->getUri();
  162       }
  163       else {
  164         $definition['route_name'] = $url_object->getRouteName();
  165         $definition['route_parameters'] = $url_object->getRouteParameters();
  166       }
  167       $definition['options'] = $url_object->getOptions();
  168     }
  169 
  170     $definition['title'] = $this->getTitle();
  171     $definition['description'] = $this->getDescription();
  172     $definition['weight'] = $this->getWeight();
  173     $definition['id'] = $this->getPluginId();
  174     $definition['metadata'] = ['entity_id' => $this->id()];
  175     $definition['form_class'] = '\Drupal\menu_link_content\Form\MenuLinkContentForm';
  176     $definition['enabled'] = $this->isEnabled() ? 1 : 0;
  177     $definition['expanded'] = $this->isExpanded() ? 1 : 0;
  178     $definition['provider'] = 'menu_link_content';
  179     $definition['discovered'] = 0;
  180     $definition['parent'] = $this->getParentId();
  181 
  182     return $definition;
  183   }
  184 
  185   /**
  186    * {@inheritdoc}
  187    */
  188   public static function preCreate(EntityStorageInterface $storage, array &$values) {
  189     $values += ['bundle' => 'menu_link_content'];
  190   }
  191 
  192   /**
  193    * {@inheritdoc}
  194    */
  195   public function preSave(EntityStorageInterface $storage) {
  196     parent::preSave($storage);
  197 
  198     if (parse_url($this->link->uri, PHP_URL_SCHEME) === 'internal') {
  199       $this->setRequiresRediscovery(TRUE);
  200     }
  201     else {
  202       $this->setRequiresRediscovery(FALSE);
  203     }
  204   }
  205 
  206   /**
  207    * {@inheritdoc}
  208    */
  209   public function postSave(EntityStorageInterface $storage, $update = TRUE) {
  210     parent::postSave($storage, $update);
  211 
  212     // Don't update the menu tree if a pending revision was saved.
  213     if (!$this->isDefaultRevision()) {
  214       return;
  215     }
  216 
  217     /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
  218     $menu_link_manager = \Drupal::service('plugin.manager.menu.link');
  219 
  220     // The menu link can just be updated if there is already an menu link entry
  221     // on both entity and menu link plugin level.
  222     $definition = $this->getPluginDefinition();
  223     // Even when $update is FALSE, for top level links it is possible the link
  224     // already is in the storage because of the getPluginDefinition() call
  225     // above, see https://www.drupal.org/node/2605684#comment-10515450 for the
  226     // call chain. Because of this the $update flag is ignored and only the
  227     // existence of the definition (equals to being in the tree storage) is
  228     // checked.
  229     if ($menu_link_manager->getDefinition($this->getPluginId(), FALSE)) {
  230       // When the entity is saved via a plugin instance, we should not call
  231       // the menu tree manager to update the definition a second time.
  232       if (!$this->insidePlugin) {
  233         $menu_link_manager->updateDefinition($this->getPluginId(), $definition, FALSE);
  234       }
  235     }
  236     else {
  237       $menu_link_manager->addDefinition($this->getPluginId(), $definition);
  238     }
  239   }
  240 
  241   /**
  242    * {@inheritdoc}
  243    */
  244   public static function preDelete(EntityStorageInterface $storage, array $entities) {
  245     parent::preDelete($storage, $entities);
  246 
  247     /** @var \Drupal\Core\Menu\MenuLinkManagerInterface $menu_link_manager */
  248     $menu_link_manager = \Drupal::service('plugin.manager.menu.link');
  249 
  250     foreach ($entities as $menu_link) {
  251       /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $menu_link */
  252       $menu_link_manager->removeDefinition($menu_link->getPluginId(), FALSE);
  253 
  254       // Children get re-attached to the menu link's parent.
  255       $parent_plugin_id = $menu_link->getParentId();
  256       $children = $storage->loadByProperties(['parent' => $menu_link->getPluginId()]);
  257       foreach ($children as $child) {
  258         /** @var \Drupal\menu_link_content\Entity\MenuLinkContent $child */
  259         $child->set('parent', $parent_plugin_id)->save();
  260       }
  261     }
  262   }
  263 
  264   /**
  265    * {@inheritdoc}
  266    */
  267   public static function baseFieldDefinitions(EntityTypeInterface $entity_type) {
  268     /** @var \Drupal\Core\Field\BaseFieldDefinition[] $fields */
  269     $fields = parent::baseFieldDefinitions($entity_type);
  270 
  271     // Add the publishing status field.
  272     $fields += static::publishedBaseFieldDefinitions($entity_type);
  273 
  274     $fields['id']->setLabel(t('Entity ID'))
  275       ->setDescription(t('The entity ID for this menu link content entity.'));
  276 
  277     $fields['uuid']->setDescription(t('The content menu link UUID.'));
  278 
  279     $fields['langcode']->setDescription(t('The menu link language code.'));
  280 
  281     $fields['bundle']
  282       ->setDescription(t('The content menu link bundle.'))
  283       ->setSetting('max_length', EntityTypeInterface::BUNDLE_MAX_LENGTH)
  284       ->setSetting('is_ascii', TRUE);
  285 
  286     $fields['title'] = BaseFieldDefinition::create('string')
  287       ->setLabel(t('Menu link title'))
  288       ->setDescription(t('The text to be used for this link in the menu.'))
  289       ->setRequired(TRUE)
  290       ->setTranslatable(TRUE)
  291       ->setRevisionable(TRUE)
  292       ->setSetting('max_length', 255)
  293       ->setDisplayOptions('view', [
  294         'label' => 'hidden',
  295         'type' => 'string',
  296         'weight' => -5,
  297       ])
  298       ->setDisplayOptions('form', [
  299         'type' => 'string_textfield',
  300         'weight' => -5,
  301       ])
  302       ->setDisplayConfigurable('form', TRUE);
  303 
  304     $fields['description'] = BaseFieldDefinition::create('string')
  305       ->setLabel(t('Description'))
  306       ->setDescription(t('Shown when hovering over the menu link.'))
  307       ->setTranslatable(TRUE)
  308       ->setRevisionable(TRUE)
  309       ->setSetting('max_length', 255)
  310       ->setDisplayOptions('view', [
  311         'label' => 'hidden',
  312         'type' => 'string',
  313         'weight' => 0,
  314       ])
  315       ->setDisplayOptions('form', [
  316         'type' => 'string_textfield',
  317         'weight' => 0,
  318       ]);
  319 
  320     $fields['menu_name'] = BaseFieldDefinition::create('string')
  321       ->setLabel(t('Menu name'))
  322       ->setDescription(t('The menu name. All links with the same menu name (such as "tools") are part of the same menu.'))
  323       ->setDefaultValue('tools')
  324       ->setSetting('is_ascii', TRUE);
  325 
  326     $fields['link'] = BaseFieldDefinition::create('link')
  327       ->setLabel(t('Link'))
  328       ->setDescription(t('The location this menu link points to.'))
  329       ->setRevisionable(TRUE)
  330       ->setRequired(TRUE)
  331       ->setSettings([
  332         'link_type' => LinkItemInterface::LINK_GENERIC,
  333         'title' => DRUPAL_DISABLED,
  334       ])
  335       ->setDisplayOptions('form', [
  336         'type' => 'link_default',
  337         'weight' => -2,
  338       ]);
  339 
  340     $fields['external'] = BaseFieldDefinition::create('boolean')
  341       ->setLabel(t('External'))
  342       ->setDescription(t('A flag to indicate if the link points to a full URL starting with a protocol, like http:// (1 = external, 0 = internal).'))
  343       ->setDefaultValue(FALSE)
  344       ->setRevisionable(TRUE);
  345 
  346     $fields['rediscover'] = BaseFieldDefinition::create('boolean')
  347       ->setLabel(t('Indicates whether the menu link should be rediscovered'))
  348       ->setDefaultValue(FALSE);
  349 
  350     $fields['weight'] = BaseFieldDefinition::create('integer')
  351       ->setLabel(t('Weight'))
  352       ->setDescription(t('Link weight among links in the same menu at the same depth. In the menu, the links with high weight will sink and links with a low weight will be positioned nearer the top.'))
  353       ->setDefaultValue(0)
  354       ->setDisplayOptions('view', [
  355         'label' => 'hidden',
  356         'type' => 'number_integer',
  357         'weight' => 0,
  358       ])
  359       ->setDisplayOptions('form', [
  360         'type' => 'number',
  361         'weight' => 20,
  362       ]);
  363 
  364     $fields['expanded'] = BaseFieldDefinition::create('boolean')
  365       ->setLabel(t('Show as expanded'))
  366       ->setDescription(t('If selected and this menu link has children, the menu will always appear expanded. This option may be overridden for the entire menu tree when placing a menu block.'))
  367       ->setDefaultValue(FALSE)
  368       ->setDisplayOptions('view', [
  369         'label' => 'hidden',
  370         'type' => 'boolean',
  371         'weight' => 0,
  372       ])
  373       ->setDisplayOptions('form', [
  374         'settings' => ['display_label' => TRUE],
  375         'weight' => 0,
  376       ]);
  377 
  378     // Override some properties of the published field added by
  379     // \Drupal\Core\Entity\EntityPublishedTrait::publishedBaseFieldDefinitions().
  380     $fields['enabled']->setLabel(t('Enabled'));
  381     $fields['enabled']->setDescription(t('A flag for whether the link should be enabled in menus or hidden.'));
  382     $fields['enabled']->setTranslatable(FALSE);
  383     $fields['enabled']->setDisplayOptions('view', [
  384       'label' => 'hidden',
  385       'type' => 'boolean',
  386       'weight' => 0,
  387     ]);
  388     $fields['enabled']->setDisplayOptions('form', [
  389       'settings' => ['display_label' => TRUE],
  390       'weight' => -1,
  391     ]);
  392 
  393     $fields['parent'] = BaseFieldDefinition::create('string')
  394       ->setLabel(t('Parent plugin ID'))
  395       ->setDescription(t('The ID of the parent menu link plugin, or empty string when at the top level of the hierarchy.'));
  396 
  397     $fields['changed'] = BaseFieldDefinition::create('changed')
  398       ->setLabel(t('Changed'))
  399       ->setDescription(t('The time that the menu link was last edited.'))
  400       ->setTranslatable(TRUE)
  401       ->setRevisionable(TRUE);
  402 
  403     // @todo Keep this field hidden until we have a revision UI for menu links.
  404     //   @see https://www.drupal.org/project/drupal/issues/2350939
  405     $fields['revision_log_message']->setDisplayOptions('form', [
  406       'region' => 'hidden',
  407     ]);
  408 
  409     return $fields;
  410   }
  411 
  412   /**
  413    * {@inheritdoc}
  414    */
  415   public function requiresRediscovery() {
  416     return $this->get('rediscover')->value;
  417   }
  418 
  419   /**
  420    * {@inheritdoc}
  421    */
  422   public function setRequiresRediscovery($rediscovery) {
  423     $this->set('rediscover', $rediscovery);
  424     return $this;
  425   }
  426 
  427 }