/** * {@inheritdoc} * * Find the parent link GUID. */ public function transform($value, MigrateExecutableInterface $migrate_executable, Row $row, $destination_property) { $parent_id = array_shift($value); if (!$parent_id) { // Top level item. return ''; } try { $already_migrated_id = $this->migrationPlugin->transform($parent_id, $migrate_executable, $row, $destination_property); if ($already_migrated_id && ($link = $this->menuLinkStorage->load($already_migrated_id))) { return $link->getPluginId(); } } catch (MigrateSkipRowException $e) { } if (isset($value[1])) { list($menu_name, $parent_link_path) = $value; $url = Url::fromUserInput("/{$parent_link_path}"); if ($url->isRouted()) { $links = $this->menuLinkManager->loadLinksByRoute($url->getRouteName(), $url->getRouteParameters(), $menu_name); if (count($links) == 1) { /** @var \Drupal\Core\Menu\MenuLinkInterface $link */ $link = reset($links); return $link->getPluginId(); } } } throw new MigrateSkipRowException(); }
/** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { // Locked menus may not be deleted. if ($this->entity->isLocked()) { return; } // Delete all links to the overview page for this menu. // @todo Add a more generic helper function to the menu link plugin // manager to remove links to a entity or other ID used as a route // parameter that is being removed. Also, consider moving this to // menu_ui.module as part of a generic response to entity deletion. // https://www.drupal.org/node/2310329 $menu_links = $this->menuLinkManager->loadLinksByRoute('entity.menu.edit_form', array('menu' => $this->entity->id()), TRUE); foreach ($menu_links as $id => $link) { $this->menuLinkManager->removeDefinition($id); } parent::submitForm($form, $form_state); }
/** * Tests uninstalling a module providing default links. */ public function testModuleUninstalledMenuLinks() { \Drupal::moduleHandler()->install(array('menu_test')); \Drupal::service('router.builder')->rebuild(); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test'); $this->assertEqual(count($menu_links), 1); $menu_link = reset($menu_links); $this->assertEqual($menu_link->getPluginId(), 'menu_test'); // Uninstall the module and ensure the menu link got removed. \Drupal::moduleHandler()->uninstall(array('menu_test')); \Drupal::service('plugin.manager.menu.link')->rebuild(); $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_test.menu_test'); $this->assertEqual(count($menu_links), 0); }
/** * {@inheritdoc} */ public function getActiveLink($menu_name = NULL) { // Note: this is a very simple implementation. If you need more control // over the return value, such as matching a prioritized list of menu names, // you should substitute your own implementation for the 'menu.active_trail' // service in the container. // The menu links coming from the storage are already sorted by depth, // weight and ID. $found = NULL; $route_name = $this->routeMatch->getRouteName(); // On a default (not custom) 403 page the route name is NULL. On a custom // 403 page we will get the route name for that page, so we can consider // it a feature that a relevant menu tree may be displayed. if ($route_name) { $route_parameters = $this->routeMatch->getRawParameters()->all(); // Load links matching this route. $links = $this->menuLinkManager->loadLinksByRoute($route_name, $route_parameters, $menu_name); // Select the first matching link. if ($links) { $found = reset($links); } } return $found; }
/** * {@inheritdoc} */ public function submit(array $form, FormStateInterface $form_state) { $form_state->setRedirect('menu_ui.overview_page'); // Locked menus may not be deleted. if ($this->entity->isLocked()) { return; } // Delete all links to the overview page for this menu. // @todo Add a more generic helper function to the menu link plugin // manager to remove links to a entity or other ID used as a route // parameter that is being removed. Also, consider moving this to // menu_ui.module as part of a generic response to entity deletion. // https://www.drupal.org/node/2310329 $menu_links = $this->menuLinkManager->loadLinksByRoute('menu_ui.menu_edit', array('menu' => $this->entity->id()), TRUE); foreach ($menu_links as $id => $link) { $this->menuLinkManager->removeDefinition($id); } // Delete the custom menu and all its menu links. $this->entity->delete(); $t_args = array('%title' => $this->entity->label()); drupal_set_message(t('The custom menu %title has been deleted.', $t_args)); $this->logger('menu')->notice('Deleted custom menu %title and all its menu links.', $t_args); }
/** * Builds a table row for the system modules page. * * @param array $modules * The list existing modules. * @param \Drupal\Core\Extension\Extension $module * The module for which to build the form row. * @param $distribution * * @return array * The form row for the given module. */ protected function buildRow(array $modules, Extension $module, $distribution) { // Set the basic properties. $row['#required'] = array(); $row['#requires'] = array(); $row['#required_by'] = array(); $row['name']['#markup'] = $module->info['name']; $row['description']['#markup'] = $this->t($module->info['description']); $row['version']['#markup'] = $module->info['version']; // Generate link for module's help page, if there is one. $row['links']['help'] = array(); if ($this->moduleHandler->moduleExists('help') && $module->status && in_array($module->getName(), $this->moduleHandler->getImplementations('help'))) { if ($this->moduleHandler->invoke($module->getName(), 'help', array('help.page.' . $module->getName(), $this->routeMatch))) { $row['links']['help'] = array('#type' => 'link', '#title' => $this->t('Help'), '#url' => Url::fromRoute('help.page', ['name' => $module->getName()]), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-help'), 'title' => $this->t('Help')))); } } // Generate link for module's permission, if the user has access to it. $row['links']['permissions'] = array(); if ($module->status && \Drupal::currentUser()->hasPermission('administer permissions') && in_array($module->getName(), $this->moduleHandler->getImplementations('permission'))) { $row['links']['permissions'] = array('#type' => 'link', '#title' => $this->t('Permissions'), '#url' => Url::fromRoute('user.admin_permissions'), '#options' => array('fragment' => 'module-' . $module->getName(), 'attributes' => array('class' => array('module-link', 'module-link-permissions'), 'title' => $this->t('Configure permissions')))); } // Generate link for module's configuration page, if it has one. $row['links']['configure'] = array(); if ($module->status && isset($module->info['configure'])) { $route_parameters = isset($module->info['configure_parameters']) ? $module->info['configure_parameters'] : array(); if ($this->accessManager->checkNamedRoute($module->info['configure'], $route_parameters, $this->currentUser)) { $links = $this->menuLinkManager->loadLinksByRoute($module->info['configure']); /** @var \Drupal\Core\Menu\MenuLinkInterface $link */ $link = reset($links); // Most configure links have a corresponding menu link, though some just // have a route. if ($link) { $description = $link->getDescription(); } else { $request = new Request(); $request->attributes->set('_route_name', $module->info['configure']); $route_object = $this->routeProvider->getRouteByName($module->info['configure']); $request->attributes->set('_route', $route_object); $request->attributes->add($route_parameters); $description = $this->titleResolver->getTitle($request, $route_object); } $row['links']['configure'] = array('#type' => 'link', '#title' => $this->t('Configure'), '#url' => Url::fromRoute($module->info['configure'], $route_parameters), '#options' => array('attributes' => array('class' => array('module-link', 'module-link-configure'), 'title' => $description))); } } // Present a checkbox for installing and indicating the status of a module. $row['enable'] = array('#type' => 'checkbox', '#title' => $this->t('Install'), '#default_value' => (bool) $module->status, '#disabled' => (bool) $module->status); // Disable the checkbox for required modules. if (!empty($module->info['required'])) { // Used when displaying modules that are required by the installation profile $row['enable']['#disabled'] = TRUE; $row['#required_by'][] = $distribution . (!empty($module->info['explanation']) ? ' (' . $module->info['explanation'] . ')' : ''); } // Check the compatibilities. $compatible = TRUE; // Initialize an empty array of reasons why the module is incompatible. Add // each reason as a separate element of the array. $reasons = array(); // Check the core compatibility. if ($module->info['core'] != \Drupal::CORE_COMPATIBILITY) { $compatible = FALSE; $reasons[] = $this->t('This version is not compatible with Drupal !core_version and should be replaced.', array('!core_version' => \Drupal::CORE_COMPATIBILITY)); } // Ensure this module is compatible with the currently installed version of PHP. if (version_compare(phpversion(), $module->info['php']) < 0) { $compatible = FALSE; $required = $module->info['php'] . (substr_count($module->info['php'], '.') < 2 ? '.*' : ''); $reasons[] = $this->t('This module requires PHP version @php_required and is incompatible with PHP version !php_version.', array('@php_required' => $required, '!php_version' => phpversion())); } // If this module is not compatible, disable the checkbox. if (!$compatible) { $status = implode(' ', $reasons); $row['enable']['#disabled'] = TRUE; $row['description']['#markup'] = $status; $row['#attributes']['class'][] = 'incompatible'; } // If this module requires other modules, add them to the array. foreach ($module->requires as $dependency => $version) { if (!isset($modules[$dependency])) { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">missing</span>)', array('@module' => Unicode::ucfirst($dependency))); $row['enable']['#disabled'] = TRUE; } elseif (empty($modules[$dependency]->hidden)) { $name = $modules[$dependency]->info['name']; // Disable the module's checkbox if it is incompatible with the // dependency's version. if ($incompatible_version = drupal_check_incompatibility($version, str_replace(\Drupal::CORE_COMPATIBILITY . '-', '', $modules[$dependency]->info['version']))) { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> version @version)', array('@module' => $name . $incompatible_version, '@version' => $modules[$dependency]->info['version'])); $row['enable']['#disabled'] = TRUE; } elseif ($modules[$dependency]->info['core'] != \Drupal::CORE_COMPATIBILITY) { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-missing">incompatible with</span> this version of Drupal core)', array('@module' => $name)); $row['enable']['#disabled'] = TRUE; } elseif ($modules[$dependency]->status) { $row['#requires'][$dependency] = $this->t('@module', array('@module' => $name)); } else { $row['#requires'][$dependency] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $name)); } } } // If this module is required by other modules, list those, and then make it // impossible to disable this one. foreach ($module->required_by as $dependent => $version) { if (isset($modules[$dependent]) && empty($modules[$dependent]->info['hidden'])) { if ($modules[$dependent]->status == 1 && $module->status == 1) { $row['#required_by'][$dependent] = $this->t('@module', array('@module' => $modules[$dependent]->info['name'])); $row['enable']['#disabled'] = TRUE; } else { $row['#required_by'][$dependent] = $this->t('@module (<span class="admin-disabled">disabled</span>)', array('@module' => $modules[$dependent]->info['name'])); } } } return $row; }