diff --git a/core/lib/Drupal/Core/DrupalKernel.php b/core/lib/Drupal/Core/DrupalKernel.php index 0160119..8d6e28c 100644 --- a/core/lib/Drupal/Core/DrupalKernel.php +++ b/core/lib/Drupal/Core/DrupalKernel.php @@ -162,7 +162,7 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface { */ public function __construct($environment, ClassLoader $class_loader, $allow_dumping = TRUE) { $this->environment = $environment; - $this->booted = FALSE; + $this->booted = false; $this->classLoader = $class_loader; $this->allowDumping = $allow_dumping; } @@ -189,7 +189,7 @@ public function shutdown() { return; } $this->booted = FALSE; - $this->container = NULL; + $this->container = null; } /** @@ -274,7 +274,7 @@ public function terminate(Request $request, Response $response) { /** * {@inheritdoc} */ - public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = TRUE) { + public function handle(Request $request, $type = HttpKernelInterface::MASTER_REQUEST, $catch = true) { if (FALSE === $this->booted) { $this->boot(); } @@ -510,7 +510,7 @@ protected function buildContainer() { $path = DRUPAL_ROOT . '/core/lib/Drupal/' . $parent_directory; foreach (new \DirectoryIterator($path) as $component) { if (!$component->isDot() && is_dir($component->getPathname() . '/Plugin')) { - $namespaces['Drupal\\' . $parent_directory . '\\' . $component->getFilename()] = DRUPAL_ROOT . '/core/lib'; + $namespaces['Drupal\\' . $parent_directory .'\\' . $component->getFilename()] = DRUPAL_ROOT . '/core/lib'; } } } diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php index e2a2499..0acf4bc 100644 --- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php +++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php @@ -126,7 +126,7 @@ public function __construct(ControllerResolverInterface $controller_resolver, Re $this->accessManager = $access_manager; $this->account = $account; $this->alterInfo($module_handler, 'local_tasks'); - $this->setCacheBackend($cache, $language_manager, 'local_task_plugins', array('local_task' => TRUE)); + $this->setCacheBackend($cache, $language_manager, 'local_task_plugins', array('local_task' => 1)); } /** diff --git a/core/modules/book/book.module b/core/modules/book/book.module index 94c75b0..6f4e83b 100644 --- a/core/modules/book/book.module +++ b/core/modules/book/book.module @@ -306,8 +306,8 @@ function book_get_flat_menu($book_link) { $flat = &drupal_static(__FUNCTION__, array()); if (!isset($flat[$book_link['mlid']])) { - // Call bookTreeAllData() to take advantage of the menu system's caching. - $tree = \Drupal::service('book.manager')->bookTreeAllData($book_link['menu_name'], $book_link, $book_link['depth'] + 1); + // Call menu_tree_all_data() to take advantage of the menu system's caching. + $tree = menu_tree_all_data($book_link['menu_name'], $book_link, $book_link['depth'] + 1); $flat[$book_link['mlid']] = array(); _book_flatten_menu($tree, $flat[$book_link['mlid']]); } @@ -363,7 +363,7 @@ function book_prev($book_link) { // The previous page in the book may be a child of the previous visible link. if ($prev['depth'] == $book_link['depth'] && $prev['has_children']) { // The subtree will have only one link at the top level - get its data. - $tree = \Drupal::service('book.manager')->bookMenuSubtreeData($prev); + $tree = book_menu_subtree_data($prev); $data = array_shift($tree); // The link of interest is the last child - iterate to find the deepest one. while ($data['below']) { @@ -430,7 +430,7 @@ function book_children($book_link) { } if ($children) { - $elements = \Drupal::service('book.manager')->bookTreeOutput($children); + $elements = menu_tree_output($children); return drupal_render($elements); } return ''; @@ -474,6 +474,20 @@ function book_node_view(EntityInterface $node, EntityDisplay $display, $view_mod } /** + * Implements hook_page_alter(). + * + * Adds the book menu to the list of menus used to build the active trail when + * viewing a book page. + */ +function book_page_alter(&$page) { + if (($node = menu_get_object()) && !empty($node->book['bid'])) { + $active_menus = menu_get_active_menu_names(); + $active_menus[] = $node->book['menu_name']; + menu_set_active_menu_names($active_menus); + } +} + +/** * Implements hook_node_presave(). */ function book_node_presave(EntityInterface $node) { @@ -535,7 +549,6 @@ function book_node_predelete(EntityInterface $node) { \Drupal::service('book.manager')->updateOutline($child_node); } } - // @todo - remove this call when we change the schema. menu_link_delete($node->book['mlid']); db_delete('book') ->condition('mlid', $node->book['mlid']) @@ -813,6 +826,78 @@ function book_link_load($mlid) { } /** + * Gets the data representing a subtree of the book hierarchy. + * + * The root of the subtree will be the link passed as a parameter, so the + * returned tree will contain this item and all its descendents in the menu + * tree. + * + * @param $link + * A fully loaded menu link. + * + * @return + * A subtree of menu links in an array, in the order they should be rendered. + */ +function book_menu_subtree_data($link) { + $tree = &drupal_static(__FUNCTION__, array()); + + // Generate a cache ID (cid) specific for this $menu_name and $link. + $cid = 'links:' . $link['menu_name'] . ':subtree-cid:' . $link['mlid']; + + if (!isset($tree[$cid])) { + $cache = cache('menu')->get($cid); + + if ($cache && isset($cache->data)) { + // If the cache entry exists, it will just be the cid for the actual data. + // This avoids duplication of large amounts of data. + $cache = cache('menu')->get($cache->data); + + if ($cache && isset($cache->data)) { + $data = $cache->data; + } + } + + // If the subtree data was not in the cache, $data will be NULL. + if (!isset($data)) { + $query = db_select('menu_links', 'ml', array('fetch' => PDO::FETCH_ASSOC)); + $query->join('menu_router', 'm', 'm.path = ml.router_path'); + $query->join('book', 'b', 'ml.mlid = b.mlid'); + $query->fields('b'); + $query->fields('m', array('load_functions', 'to_arg_functions', 'access_callback', 'access_arguments', 'page_callback', 'page_arguments', 'title', 'title_callback', 'title_arguments', 'type')); + $query->fields('ml'); + $query->condition('menu_name', $link['menu_name']); + for ($i = 1; $i <= MENU_MAX_DEPTH && $link["p$i"]; ++$i) { + $query->condition("p$i", $link["p$i"]); + } + for ($i = 1; $i <= MENU_MAX_DEPTH; ++$i) { + $query->orderBy("p$i"); + } + $links = array(); + foreach ($query->execute() as $item) { + $links[] = $item; + } + $data['tree'] = menu_tree_data($links, array(), $link['depth']); + $data['node_links'] = array(); + menu_tree_collect_node_links($data['tree'], $data['node_links']); + // Compute the real cid for book subtree data. + $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . hash('sha256', serialize($data)); + // Cache the data, if it is not already in the cache. + + if (!cache('menu')->get($tree_cid)) { + cache('menu')->set($tree_cid, $data); + } + // Cache the cid of the (shared) data using the menu and item-specific cid. + cache('menu')->set($cid, $tree_cid); + } + // Check access for the current user to each item in the tree. + menu_tree_check_access($data['tree'], $data['node_links']); + $tree[$cid] = $data['tree']; + } + + return $tree[$cid]; +} + +/** * Implements hook_library_info(). */ function book_library_info() { diff --git a/core/modules/book/lib/Drupal/book/BookExport.php b/core/modules/book/lib/Drupal/book/BookExport.php index c86e25c..78fb863 100644 --- a/core/modules/book/lib/Drupal/book/BookExport.php +++ b/core/modules/book/lib/Drupal/book/BookExport.php @@ -68,7 +68,7 @@ public function bookExportHtml(NodeInterface $node) { throw new \Exception(); } - $tree = \Drupal::service('book.manager')->bookMenuSubtreeData($node->book); + $tree = book_menu_subtree_data($node->book); $contents = $this->exportTraverse($tree, array($this, 'bookNodeExport')); return array( '#theme' => 'book_export_html', diff --git a/core/modules/book/lib/Drupal/book/BookManager.php b/core/modules/book/lib/Drupal/book/BookManager.php index 9b415a8..3bb4e8b 100644 --- a/core/modules/book/lib/Drupal/book/BookManager.php +++ b/core/modules/book/lib/Drupal/book/BookManager.php @@ -6,11 +6,9 @@ namespace Drupal\book; -use Drupal\Core\Cache\CacheBackendInterface; use Drupal\Core\Database\Connection; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; -use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslationInterface; use Drupal\Core\Config\ConfigFactory; @@ -151,29 +149,7 @@ public function getLinkDefaults($nid) { * The depth limit for items in the parent select. */ public function getParentDepthLimit(array $book_link) { - return MENU_MAX_DEPTH - 1 - (($book_link['mlid'] && $book_link['has_children']) ? $this->findChildrenRelativeDepth($book_link) : 0); - } - - /** - * {@inheritdoc} - */ - protected function findChildrenRelativeDepth(array $entity) { - $query = db_select('menu_links'); - $query->addField('menu_links', 'depth'); - $query->condition('menu_name', $entity['menu_name']); - $query->orderBy('depth', 'DESC'); - $query->range(0, 1); - - $i = 1; - $p = 'p1'; - while ($i <= MENU_MAX_DEPTH && $entity[$p]) { - $query->condition($p, $entity[$p]); - $p = 'p' . ++$i; - } - - $max_depth = $query->execute()->fetchField(); - - return ($max_depth > $entity['depth']) ? $max_depth - $entity['depth'] : 0; + return MENU_MAX_DEPTH - 1 - (($book_link['mlid'] && $book_link['has_children']) ? $this->entityManager->getStorageController('menu_link')->findChildrenRelativeDepth($book_link) : 0); } /** @@ -510,7 +486,7 @@ protected function recurseTableOfContents(array $tree, $indent, array &$toc, arr * book page. */ public function getTableOfContents($bid, $depth_limit, array $exclude = array()) { - $tree = $this->bookTreeAllData($this->createMenuName($bid)); + $tree = menu_tree_all_data($this->createMenuName($bid)); $toc = array(); $this->recurseTableOfContents($tree, '', $toc, $exclude, $depth_limit); @@ -529,517 +505,4 @@ public function deleteBook($nid) { ->execute(); } - /** - * Gets the data structure representing a named menu tree. - * - * Since this can be the full tree including hidden items, the data returned - * may be used for generating an an admin interface or a select. - * - * @param string $menu_name - * The named menu links to return - * @param $link - * A fully loaded menu link, or NULL. If a link is supplied, only the - * path to root will be included in the returned tree - as if this link - * represented the current page in a visible menu. - * @param int $max_depth - * Optional maximum depth of links to retrieve. Typically useful if only one - * or two levels of a sub tree are needed in conjunction with a non-NULL - * $link, in which case $max_depth should be greater than $link['depth']. - * - * @return array - * An tree of menu links in an array, in the order they should be rendered. - * - * Note: copied from menu_tree_all_data(). - */ - public function bookTreeAllData($menu_name, $link = NULL, $max_depth = NULL) { - $tree = &drupal_static('menu_tree_all_data', array()); - $language_interface = language(Language::TYPE_INTERFACE); - - // Use $mlid as a flag for whether the data being loaded is for the whole tree. - $mlid = isset($link['mlid']) ? $link['mlid'] : 0; - // Generate a cache ID (cid) specific for this $menu_name, $link, $language, and depth. - $cid = 'links:' . $menu_name . ':all:' . $mlid . ':' . $language_interface->id . ':' . (int) $max_depth; - - if (!isset($tree[$cid])) { - // If the static variable doesn't have the data, check {cache_menu}. - $cache = cache('menu')->get($cid); - if ($cache && isset($cache->data)) { - // If the cache entry exists, it contains the parameters for - // menu_build_tree(). - $tree_parameters = $cache->data; - } - // If the tree data was not in the cache, build $tree_parameters. - if (!isset($tree_parameters)) { - $tree_parameters = array( - 'min_depth' => 1, - 'max_depth' => $max_depth, - ); - if ($mlid) { - // The tree is for a single item, so we need to match the values in its - // p columns and 0 (the top level) with the plid values of other links. - $parents = array(0); - for ($i = 1; $i < MENU_MAX_DEPTH; $i++) { - if (!empty($link["p$i"])) { - $parents[] = $link["p$i"]; - } - } - $tree_parameters['expanded'] = $parents; - $tree_parameters['active_trail'] = $parents; - $tree_parameters['active_trail'][] = $mlid; - } - - // Cache the tree building parameters using the page-specific cid. - cache('menu')->set($cid, $tree_parameters, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name)); - } - - // Build the tree using the parameters; the resulting tree will be cached - // by _menu_build_tree()). - $tree[$cid] = $this->menu_build_tree($menu_name, $tree_parameters); - } - - return $tree[$cid]; - } - - /** - * Returns a rendered menu tree. - * - * The menu item's LI element is given one of the following classes: - * - expanded: The menu item is showing its submenu. - * - collapsed: The menu item has a submenu which is not shown. - * - leaf: The menu item has no submenu. - * - * @param array $tree - * A data structure representing the tree as returned from menu_tree_data. - * - * @return array - * A structured array to be rendered by drupal_render(). - * - * Note: copied from menu_tree_output() but some hacky code using - * menu_get_item() was removed. - */ - public function bookTreeOutput(array $tree) { - $build = array(); - $items = array(); - - // Pull out just the menu links we are going to render so that we - // get an accurate count for the first/last classes. - foreach ($tree as $data) { - if ($data['link']['access'] && !$data['link']['hidden']) { - $items[] = $data; - } - } - - $num_items = count($items); - foreach ($items as $i => $data) { - $class = array(); - if ($i == 0) { - $class[] = 'first'; - } - if ($i == $num_items - 1) { - $class[] = 'last'; - } - // Set a class for the
  • -tag. Since $data['below'] may contain local - // tasks, only set 'expanded' class if the link also has children within - // the current menu. - if ($data['link']['has_children'] && $data['below']) { - $class[] = 'expanded'; - } - elseif ($data['link']['has_children']) { - $class[] = 'collapsed'; - } - else { - $class[] = 'leaf'; - } - // Set a class if the link is in the active trail. - if ($data['link']['in_active_trail']) { - $class[] = 'active-trail'; - $data['link']['localized_options']['attributes']['class'][] = 'active-trail'; - } - - // Allow menu-specific theme overrides. - $element['#theme'] = 'menu_link__' . strtr($data['link']['menu_name'], '-', '_'); - $element['#attributes']['class'] = $class; - $element['#title'] = $data['link']['title']; - $element['#href'] = $data['link']['href']; - $element['#localized_options'] = !empty($data['link']['localized_options']) ? $data['link']['localized_options'] : array(); - $element['#below'] = $data['below'] ? $this->bookTreeOutput($data['below']) : $data['below']; - $element['#original_link'] = $data['link']; - // Index using the link's unique mlid. - $build[$data['link']['mlid']] = $element; - } - if ($build) { - // Make sure drupal_render() does not re-order the links. - $build['#sorted'] = TRUE; - // Add the theme wrapper for outer markup. - // Allow menu-specific theme overrides. - $build['#theme_wrappers'][] = 'menu_tree__' . strtr($data['link']['menu_name'], '-', '_'); - } - - return $build; - } - - /** - * Builds a menu tree, translates links, and checks access. - * - * @param string $menu_name - * The name of the menu. - * @param array $parameters - * (optional) An associative array of build parameters. Possible keys: - * - expanded: An array of parent link ids to return only menu links that are - * children of one of the plids in this list. If empty, the whole menu tree - * is built, unless 'only_active_trail' is TRUE. - * - active_trail: An array of mlids, representing the coordinates of the - * currently active menu link. - * - only_active_trail: Whether to only return links that are in the active - * trail. This option is ignored, if 'expanded' is non-empty. - * - min_depth: The minimum depth of menu links in the resulting tree. - * Defaults to 1, which is the default to build a whole tree for a menu - * (excluding menu container itself). - * - max_depth: The maximum depth of menu links in the resulting tree. - * - conditions: An associative array of custom database select query - * condition key/value pairs; see _menu_build_tree() for the actual query. - * - * @return array - * A fully built menu tree. - */ - protected function menu_build_tree($menu_name, array $parameters = array()) { - // Build the menu tree. - $data = $this->_menu_build_tree($menu_name, $parameters); - // Check access for the current user to each item in the tree. - menu_tree_check_access($data['tree'], $data['node_links']); - return $data['tree']; - } - - /** - * Builds a menu tree. - * - * This function may be used build the data for a menu tree only, for example - * to further massage the data manually before further processing happens. - * menu_tree_check_access() needs to be invoked afterwards. - * - * @see menu_build_tree() - */ - protected function _menu_build_tree($menu_name, array $parameters = array()) { - // Static cache of already built menu trees. - $trees = &drupal_static('menu_build_tree', array()); - $language_interface = language(Language::TYPE_INTERFACE); - - // Build the cache id; sort parents to prevent duplicate storage and remove - // default parameter values. - if (isset($parameters['expanded'])) { - sort($parameters['expanded']); - } - $tree_cid = 'links:' . $menu_name . ':tree-data:' . $language_interface->id . ':' . hash('sha256', serialize($parameters)); - - // If we do not have this tree in the static cache, check {cache_menu}. - if (!isset($trees[$tree_cid])) { - $cache = cache('menu')->get($tree_cid); - if ($cache && isset($cache->data)) { - $trees[$tree_cid] = $cache->data; - } - } - - if (!isset($trees[$tree_cid])) { - $query = \Drupal::entityQuery('menu_link'); - for ($i = 1; $i <= MENU_MAX_DEPTH; $i++) { - $query->sort('p' . $i, 'ASC'); - } - $query->condition('menu_name', $menu_name); - if (!empty($parameters['expanded'])) { - $query->condition('plid', $parameters['expanded'], 'IN'); - } - elseif (!empty($parameters['only_active_trail'])) { - $query->condition('mlid', $parameters['active_trail'], 'IN'); - } - $min_depth = (isset($parameters['min_depth']) ? $parameters['min_depth'] : 1); - if ($min_depth != 1) { - $query->condition('depth', $min_depth, '>='); - } - if (isset($parameters['max_depth'])) { - $query->condition('depth', $parameters['max_depth'], '<='); - } - // Add custom query conditions, if any were passed. - if (isset($parameters['conditions'])) { - foreach ($parameters['conditions'] as $column => $value) { - $query->condition($column, $value); - } - } - - // Build an ordered array of links using the query result object. - $links = array(); - if ($result = $query->execute()) { - $links = menu_link_load_multiple($result); - } - $active_trail = (isset($parameters['active_trail']) ? $parameters['active_trail'] : array()); - $data['tree'] = $this->menu_tree_data($links, $active_trail, $min_depth); - $data['node_links'] = array(); - $this->bookTreeCollectNodeLinks($data['tree'], $data['node_links']); - - // Cache the data, if it is not already in the cache. - cache('menu')->set($tree_cid, $data, CacheBackendInterface::CACHE_PERMANENT, array('menu' => $menu_name)); - $trees[$tree_cid] = $data; - } - - return $trees[$tree_cid]; - } - - /** - * Collects node links from a given menu tree recursively. - * - * @param array $tree - * The menu tree you wish to collect node links from. - * @param array $node_links - * An array in which to store the collected node links. - */ - public function bookTreeCollectNodeLinks(&$tree, &$node_links) { - // All book links are nodes. - // @todo clean this up. - foreach ($tree as $key => $v) { - if (!is_array($v['link']['route_parameters'])) { - $v['link']['route_parameters'] = unserialize($v['link']['route_parameters']); - } - if ($v['link']['route_name'] == 'node.view' && isset($v['link']['route_parameters']['node'])) { - $nid = $v['link']['route_parameters']['node']; - $node_links[$nid][$tree[$key]['link']['mlid']] = &$tree[$key]['link']; - $tree[$key]['link']['access'] = FALSE; - } - if ($tree[$key]['below']) { - $this->bookTreeCollectNodeLinks($tree[$key]['below'], $node_links); - } - } - } - - /** - * Checks access and performs dynamic operations for each link in the tree. - * - * @param array $tree - * The menu tree you wish to operate on. - * @param array $node_links - * A collection of node link references generated from $tree by - * menu_tree_collect_node_links(). - */ - public function bookTreeCheckAccess(&$tree, $node_links = array()) { - if ($node_links) { - $nids = array_keys($node_links); - $select = db_select('node_field_data', 'n'); - $select->addField('n', 'nid'); - // @todo This should be actually filtering on the desired node status field - // language and just fall back to the default language. - $select->condition('n.status', 1); - - $select->condition('n.nid', $nids, 'IN'); - $select->addTag('node_access'); - $nids = $select->execute()->fetchCol(); - foreach ($nids as $nid) { - foreach ($node_links[$nid] as $mlid => $link) { - $node_links[$nid][$mlid]['access'] = TRUE; - } - } - } - $this->_menu_tree_check_access($tree); - } - - /** - * Sorts the menu tree and recursively checks access for each item. - */ - protected function _menu_tree_check_access(&$tree) { - $new_tree = array(); - foreach ($tree as $key => $v) { - $item = &$tree[$key]['link']; - $this->_menu_link_translate($item); - if ($item['access']) { - if ($tree[$key]['below']) { - $this->_menu_tree_check_access($tree[$key]['below']); - } - // The weights are made a uniform 5 digits by adding 50000 as an offset. - // After _menu_link_translate(), $item['title'] has the localized link title. - // Adding the mlid to the end of the index insures that it is unique. - $new_tree[(50000 + $item['weight']) . ' ' . $item['title'] . ' ' . $item['mlid']] = $tree[$key]; - } - } - // Sort siblings in the tree based on the weights and localized titles. - ksort($new_tree); - $tree = $new_tree; - } - - /** - * Provides menu link access control, translation, and argument handling. - * - * This function is similar to _menu_translate(), but it also does - * link-specific preparation (such as always calling to_arg() functions). - * - * @param $item - * A menu link. - * @param bool $translate - * (optional) Whether to try to translate a link containing dynamic path - * argument placeholders (%) based on the menu router item of the current - * path. Defaults to FALSE. Internally used for breadcrumbs. - * - * Note: copied from _menu_link_translate() in menu.inc, but reduced to the - * minimal code that's used. - */ - protected function _menu_link_translate(&$item, $translate = FALSE) { - if (!is_array($item['options'])) { - $item['options'] = unserialize($item['options']); - } - if (!is_array($item['route_parameters'])) { - $item['route_parameters'] = unserialize($item['route_parameters']); - } - $item['href'] = $item['link_path']; - // menu_tree_check_access() may set this ahead of time for links to nodes. - if (!isset($item['access'])) { - $item['access'] = \Drupal::service('access_manager')->checkNamedRoute('node.view', array('node' => $item['route_parameters']['node']), \Drupal::currentUser()); - } - // For performance, don't localize a link the user can't access. - if ($item['access']) { - // Inlined the code we use from _menu_item_localize(). - $item['localized_options'] = $item['options']; - // All 'class' attributes are assumed to be an array during rendering, but - // links stored in the database may use an old string value. - // @todo In order to remove this code we need to implement a database update - // including unserializing all existing link options and running this code - // on them, as well as adding validation to menu_link_save(). - if (isset($item['options']['attributes']['class']) && is_string($item['options']['attributes']['class'])) { - $item['localized_options']['attributes']['class'] = explode(' ', $item['options']['attributes']['class']); - } - $item['title'] = $item['link_title']; - } - } - - /** - * Sorts and returns the built data representing a menu tree. - * - * @param array $links - * A flat array of menu links that are part of the menu. Each array element - * is an associative array of information about the menu link, containing the - * fields from the {menu_links} table, and optionally additional information - * from the {menu_router} table, if the menu item appears in both tables. - * This array must be ordered depth-first. See _menu_build_tree() for a sample - * query. - * @param array $parents - * An array of the menu link ID values that are in the path from the current - * page to the root of the menu tree. - * @param int $depth - * The minimum depth to include in the returned menu tree. - * - * @return array - * An array of menu links in the form of a tree. Each item in the tree is an - * associative array containing: - * - link: The menu link item from $links, with additional element - * 'in_active_trail' (TRUE if the link ID was in $parents). - * - below: An array containing the sub-tree of this item, where each element - * is a tree item array with 'link' and 'below' elements. This array will be - * empty if the menu item has no items in its sub-tree having a depth - * greater than or equal to $depth. - */ - protected function menu_tree_data(array $links, array $parents = array(), $depth = 1) { - // Reverse the array so we can use the more efficient array_pop() function. - $links = array_reverse($links); - return $this->_menu_tree_data($links, $parents, $depth); - } - - /** - * Builds the data representing a menu tree. - * - * The function is a bit complex because the rendering of a link depends on - * the next menu link. - */ - protected function _menu_tree_data(&$links, $parents, $depth) { - $tree = array(); - while ($item = array_pop($links)) { - // We need to determine if we're on the path to root so we can later build - // the correct active trail. - $item['in_active_trail'] = in_array($item['mlid'], $parents); - // Add the current link to the tree. - $tree[$item['mlid']] = array( - 'link' => $item, - 'below' => array(), - ); - // Look ahead to the next link, but leave it on the array so it's available - // to other recursive function calls if we return or build a sub-tree. - $next = end($links); - // Check whether the next link is the first in a new sub-tree. - if ($next && $next['depth'] > $depth) { - // Recursively call _menu_tree_data to build the sub-tree. - $tree[$item['mlid']]['below'] = $this->_menu_tree_data($links, $parents, $next['depth']); - // Fetch next link after filling the sub-tree. - $next = end($links); - } - // Determine if we should exit the loop and return. - if (!$next || $next['depth'] < $depth) { - break; - } - } - return $tree; - } - - /** - * Gets the data representing a subtree of the book hierarchy. - * - * The root of the subtree will be the link passed as a parameter, so the - * returned tree will contain this item and all its descendents in the menu - * tree. - * - * @param $link - * A fully loaded menu link. - * - * @return - * A subtree of menu links in an array, in the order they should be rendered. - */ - public function bookMenuSubtreeData($link) { - $tree = &drupal_static(__FUNCTION__, array()); - - // Generate a cache ID (cid) specific for this $menu_name and $link. - $cid = 'links:' . $link['menu_name'] . ':subtree-cid:' . $link['mlid']; - - if (!isset($tree[$cid])) { - $cache = cache('menu')->get($cid); - - if ($cache && isset($cache->data)) { - // If the cache entry exists, it will just be the cid for the actual data. - // This avoids duplication of large amounts of data. - $cache = cache('menu')->get($cache->data); - - if ($cache && isset($cache->data)) { - $data = $cache->data; - } - } - - // If the subtree data was not in the cache, $data will be NULL. - if (!isset($data)) { - $query = db_select('menu_links', 'ml', array('fetch' => \PDO::FETCH_ASSOC)); - $query->join('book', 'b', 'ml.mlid = b.mlid'); - $query->fields('b'); - $query->fields('ml'); - $query->condition('menu_name', $link['menu_name']); - for ($i = 1; $i <= MENU_MAX_DEPTH && $link["p$i"]; ++$i) { - $query->condition("p$i", $link["p$i"]); - } - for ($i = 1; $i <= MENU_MAX_DEPTH; ++$i) { - $query->orderBy("p$i"); - } - $links = array(); - foreach ($query->execute() as $item) { - $links[] = $item; - } - $data['tree'] = $this->menu_tree_data($links, array(), $link['depth']); - $data['node_links'] = array(); - $this->bookTreeCollectNodeLinks($data['tree'], $data['node_links']); - // Compute the real cid for book subtree data. - $tree_cid = 'links:' . $item['menu_name'] . ':subtree-data:' . hash('sha256', serialize($data)); - // Cache the data, if it is not already in the cache. - - if (!cache('menu')->get($tree_cid)) { - cache('menu')->set($tree_cid, $data); - } - // Cache the cid of the (shared) data using the menu and item-specific cid. - cache('menu')->set($cid, $tree_cid); - } - // Check access for the current user to each item in the tree. - $this->bookTreeCheckAccess($data['tree'], $data['node_links']); - $tree[$cid] = $data['tree']; - } - - return $tree[$cid]; - } } diff --git a/core/modules/book/lib/Drupal/book/Form/BookAdminEditForm.php b/core/modules/book/lib/Drupal/book/Form/BookAdminEditForm.php index c516338..ddf49b0 100644 --- a/core/modules/book/lib/Drupal/book/Form/BookAdminEditForm.php +++ b/core/modules/book/lib/Drupal/book/Form/BookAdminEditForm.php @@ -163,7 +163,7 @@ protected function bookAdminTable(NodeInterface $node, array &$form) { '#tree' => TRUE, ); - $tree = \Drupal::service('book.manager')->bookMenuSubtreeData($node->book); + $tree = book_menu_subtree_data($node->book); // Do not include the book item itself. $tree = array_shift($tree); if ($tree['below']) { diff --git a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php index 4e794f1..ce32dca 100644 --- a/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php +++ b/core/modules/book/lib/Drupal/book/Plugin/Block/BookNavigationBlock.php @@ -73,8 +73,7 @@ public function build() { if ($book['bid'] == $current_bid) { // If the current page is a node associated with a book, the menu // needs to be retrieved. - $data = \Drupal::service('book.manager')->bookTreeAllData($node->book['menu_name'], $node->book); - $book_menus[$book_id] = \Drupal::service('book.manager')->bookTreeOutput($data); + $book_menus[$book_id] = menu_tree_output(menu_tree_all_data($node->book['menu_name'], $node->book)); } else { // Since we know we will only display a link to the top node, there @@ -84,7 +83,7 @@ public function build() { $book_node = node_load($book['nid']); $book['access'] = $book_node->access('view'); $pseudo_tree[0]['link'] = $book; - $book_menus[$book_id] = \Drupal::service('book.manager')->bookTreeOutput($pseudo_tree); + $book_menus[$book_id] = menu_tree_output($pseudo_tree); } } if ($book_menus) { @@ -102,10 +101,10 @@ public function build() { $nid = $select->execute()->fetchField(); // Only show the block if the user has view access for the top-level node. if ($nid) { - $tree = \Drupal::service('book.manager')->bookTreeAllData($node->book['menu_name'], $node->book); + $tree = menu_tree_all_data($node->book['menu_name'], $node->book); // There should only be one element at the top level. $data = array_shift($tree); - $below = \Drupal::service('book.manager')->bookTreeOutput($data['below']); + $below = menu_tree_output($data['below']); if (!empty($below)) { $book_title_link = array('#theme' => 'book_title_link', '#link' => $data['link']); return array( diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php index 6ca9540..1e12304 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/Comment.php @@ -23,13 +23,6 @@ class Comment extends FieldPluginBase { /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - /** * Overrides \Drupal\views\Plugin\views\field\FieldPluginBase::init(). * * Provide generic option to link to comment. diff --git a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php index edaaa00..3e36dff 100644 --- a/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php +++ b/core/modules/comment/lib/Drupal/comment/Plugin/views/field/NodeNewComments.php @@ -25,13 +25,6 @@ class NodeNewComments extends Numeric { /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - /** * Database Service Object. * * @var \Drupal\Core\Database\Connection diff --git a/core/modules/contact/contact.local_tasks.yml b/core/modules/contact/contact.local_tasks.yml index 2eee1ee..91bb65d 100644 --- a/core/modules/contact/contact.local_tasks.yml +++ b/core/modules/contact/contact.local_tasks.yml @@ -2,9 +2,3 @@ contact.category_edit: title: 'Edit' route_name: contact.category_edit tab_root_id: contact.category_edit - -contact.personal_page: - title: 'Contact' - route_name: contact.personal_page - weight: 2 - tab_root_id: user.view diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index ea616d8..58e343e 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -81,6 +81,12 @@ function contact_menu() { 'route_name' => 'contact.site_page_category', 'type' => MENU_VISIBLE_IN_BREADCRUMB, ); + $items['user/%user/contact'] = array( + 'title' => 'Contact', + 'route_name' => 'contact.personal_page', + 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + ); return $items; } diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 7f5074e..3951c1e 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -178,6 +178,20 @@ function content_translation_menu() { $item[str_replace('_', ' ', $key)] = $value; } + $items["$path/translations"] = array( + 'title' => 'Translate', + 'route_name' => $info['links']['drupal:content-translation-overview'], + 'type' => MENU_LOCAL_TASK, + 'context' => MENU_CONTEXT_PAGE, + 'weight' => 2, + ) + $item; + + $items["$path/translations/overview"] = array( + 'title' => 'Overview', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => 0, + ); + // Add translation callback. // @todo Add the access callback instead of replacing it as soon as the // routing system supports multiple callbacks. diff --git a/core/modules/contextual/lib/Drupal/contextual/Plugin/views/field/ContextualLinks.php b/core/modules/contextual/lib/Drupal/contextual/Plugin/views/field/ContextualLinks.php index 3a14cb1..ec7a3a6 100644 --- a/core/modules/contextual/lib/Drupal/contextual/Plugin/views/field/ContextualLinks.php +++ b/core/modules/contextual/lib/Drupal/contextual/Plugin/views/field/ContextualLinks.php @@ -20,13 +20,6 @@ */ class ContextualLinks extends FieldPluginBase { - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - protected function defineOptions() { $options = parent::defineOptions(); diff --git a/core/modules/entity/entity.local_tasks.yml b/core/modules/entity/entity.local_tasks.yml index 7c1778d..54895b4 100644 --- a/core/modules/entity/entity.local_tasks.yml +++ b/core/modules/entity/entity.local_tasks.yml @@ -7,13 +7,3 @@ entity.form_mode_edit: title: 'Edit' route_name: entity.form_mode_edit tab_root_id: entity.form_mode_edit - -entity.view_mode_list: - title: List - route_name: entity.view_mode_list - tab_root_id: entity.view_mode_list - -entity.form_mode_list: - title: List - route_name: entity.form_mode_list - tab_root_id: entity.form_mode_list diff --git a/core/modules/entity/entity.module b/core/modules/entity/entity.module index e838be5..9cd45d4 100644 --- a/core/modules/entity/entity.module +++ b/core/modules/entity/entity.module @@ -11,29 +11,6 @@ use Drupal\Core\Config\Entity\ConfigStorageController; /** - * Implements hook_help(). - */ -function entity_help($path, $arg) { - switch ($path) { - case 'admin/help#entity': - $output = ''; - $output .= '

    ' . t('About') . '

    '; - $output .= '

    ' . t('The Entity module manages various types of content and configuration for the website. This information is collectively know as "entities", which are grouped into "entity types" (such as the main site content, comments, custom blocks, taxonomy terms, user accounts, and views configuration). Some entity types are further grouped into sub-types (for example, you could have article and page content types within the main site content entity type, and tag and category vocabularies within the taxonomy term entity type); other entity types, such as user accounts, do not have sub-types.') . '

    '; - $output .= '

    ' . t('Content entity types store most of their text, file, and other information in fields. See the Field module help and the Field UI help pages for general information on fields and how to create and manage them.', array('!field' => \Drupal::url('help.page', array('name' => 'field')), '!field_ui' => \Drupal::url('help.page', array('name' => 'field_ui')))) . '

    '; - $output .= '

    ' . t('Configuration entity types are used to store configuration information for your site, such as individual views in the Views module, and settings for your main site content types. Configuration stored in this way can be exported, imported, and managed using the Configuration Manager module. See the Configuration Manager module help page for more information.', array('!config-help' => \Drupal::url('help.page', array('name' => 'config')))) . '

    '; - $output .= '

    ' . t('For more information, see the online documentation for the Entity module.', array('!entity_documentation' => 'https://drupal.org/documentation/modules/entity')) . '

    '; - $output .= '

    ' . t('Uses') . '

    '; - $output .= '
    '; - $output .= '
    ' . t('Managing view modes') . '
    '; - $output .= '
    ' . t('Each content entity can have various "modes" for viewing. For instance, a content item could be viewed in full content mode on its own page, teaser mode in a list, or RSS mode in a feed. You can create, edit the names of, and delete view modes on the View modes page. Once a view mode has been set up, you can choose and format fields for the view mode within each entity sub-type on the Manage display page. See the Field UI module help page for more information.', array('!view-modes' => \Drupal::url('entity.view_mode_list'), '!field_ui' => \Drupal::url('help.page', array('name' => 'field_ui')))) . '
    '; - $output .= '
    ' . t('Managing form modes') . '
    '; - $output .= '
    ' . t('Each content entity can have various editing forms appropriate for different situations, which are known as "form modes". For instance, you might want to define a quick editing mode that allows users to edit the most important fields, and a full editing mode that gives access to all the fields. You can create, edit the names of, and delete form modes on the Manage custom form modes page. Once a form mode has been set up, you can choose which fields are available on that form within each entity sub-type on the Manage form display page. See the Field UI module help page for more information.', array('!form-modes' => \Drupal::url('entity.form_mode_list'), '!field_ui' => \Drupal::url('help.page', array('name' => 'field_ui')))) . '
    '; - $output .= '
    '; - return $output; - } -} - -/** * Implements hook_permission(). */ function entity_permission() { @@ -62,6 +39,10 @@ function entity_menu() { 'description' => 'Manage custom view modes.', 'route_name' => 'entity.view_mode_list', ); + $items['admin/structure/display-modes/view/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); $items['admin/structure/display-modes/view/add'] = array( 'title' => 'Add view mode', 'route_name' => 'entity.view_mode_add', @@ -80,6 +61,10 @@ function entity_menu() { 'description' => 'Manage custom form modes.', 'route_name' => 'entity.form_mode_list', ); + $items['admin/structure/display-modes/form/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); $items['admin/structure/display-modes/form/add'] = array( 'title' => 'Add form mode', 'route_name' => 'entity.form_mode_add', diff --git a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php b/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php deleted file mode 100644 index 1d3d150..0000000 --- a/core/modules/field/tests/modules/field_test/lib/Drupal/field_test/Plugin/Field/FieldFormatter/TestFieldNoSettingsFormatter.php +++ /dev/null @@ -1,40 +0,0 @@ - $item) { - // This formatter only needs to output raw for testing. - $elements[$delta] = array('#markup' => $item->value); - } - - return $elements; - } - -} diff --git a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php index 31a08ec..06a4bdc 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/DisplayOverviewBase.php @@ -358,10 +358,7 @@ protected function buildFieldRow($field_id, FieldInstanceInterface $instance, En '#cell_attributes' => array('class' => array('field-plugin-summary-cell')), ); } - - // Check selected plugin settings to display edit link or not. - $plugin_definition = $plugin->getPluginDefinition(); - if ($plugin_definition['settings']) { + if ($plugin->getSettings()) { $field_row['settings_edit'] = $base_button + array( '#type' => 'image_button', '#name' => $field_id . '_settings_edit', diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php index b1fb656..ca31aae 100644 --- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php +++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageDisplayTest.php @@ -104,11 +104,6 @@ function testFormatterUI() { $edit = array($fieldname => 'non empty setting'); $this->drupalPostAjaxForm(NULL, $edit, "field_test_plugin_settings_update"); $this->assertText('Default empty setting now has a value.'); - - // Test the no settings form behavior. - $edit = array('fields[field_test][type]' => 'field_no_settings', 'refresh_rows' => 'field_test'); - $this->drupalPostAjaxForm(NULL, $edit, array('op' => t('Refresh'))); - $this->assertNoFieldByName('field_test_settings_edit'); } /** diff --git a/core/modules/filter/filter.local_tasks.yml b/core/modules/filter/filter.local_tasks.yml index 56cbb87..9f7e8e9 100644 --- a/core/modules/filter/filter.local_tasks.yml +++ b/core/modules/filter/filter.local_tasks.yml @@ -3,8 +3,3 @@ filter.format_edit_tab: title: 'Configure' tab_root_id: filter.format_edit_tab weight: -10 - -filter.admin_overview: - title: List - route_name: filter.admin_overview - tab_root_id: filter.admin_overview diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module index 4962044..922688d 100644 --- a/core/modules/filter/filter.module +++ b/core/modules/filter/filter.module @@ -136,6 +136,10 @@ function filter_menu() { 'description' => 'Configure how content input by users is filtered, including allowed HTML tags. Also allows enabling of module-provided filters.', 'route_name' => 'filter.admin_overview', ); + $items['admin/config/content/formats/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); $items['admin/config/content/formats/manage/%'] = array( 'title callback' => 'entity_page_label', 'title arguments' => array(5), diff --git a/core/modules/filter/tests/filter_test/config/filter.format.filter_test.yml b/core/modules/filter/tests/filter_test/config/filter.format.filter_test.yml index 61c97ea..8915bd2 100644 --- a/core/modules/filter/tests/filter_test/config/filter.format.filter_test.yml +++ b/core/modules/filter/tests/filter_test/config/filter.format.filter_test.yml @@ -1,6 +1,6 @@ format: filter_test name: 'Test format' -weight: 2 +weight: '2' roles: - anonymous - authenticated @@ -11,19 +11,19 @@ filters: filter_html_escape: id: filter_html_escape module: filter - status: true - weight: -10 + status: '1' + weight: '-10' settings: { } filter_autop: id: filter_autop module: filter - status: true - weight: 0 + status: '1' + weight: '0' settings: { } filter_url: id: filter_url module: filter - status: true - weight: 0 + status: '1' + weight: '0' settings: - filter_url_length: 72 + filter_url_length: '72' diff --git a/core/modules/history/lib/Drupal/history/Plugin/views/field/HistoryUserTimestamp.php b/core/modules/history/lib/Drupal/history/Plugin/views/field/HistoryUserTimestamp.php index 047e5f0..91db271 100644 --- a/core/modules/history/lib/Drupal/history/Plugin/views/field/HistoryUserTimestamp.php +++ b/core/modules/history/lib/Drupal/history/Plugin/views/field/HistoryUserTimestamp.php @@ -26,13 +26,6 @@ class HistoryUserTimestamp extends Node { /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - /** * Overrides \Drupal\node\Plugin\views\field\Node::init(). */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { diff --git a/core/modules/history/lib/Drupal/history/Plugin/views/filter/HistoryUserTimestamp.php b/core/modules/history/lib/Drupal/history/Plugin/views/filter/HistoryUserTimestamp.php index e89f491..20eaac4 100644 --- a/core/modules/history/lib/Drupal/history/Plugin/views/filter/HistoryUserTimestamp.php +++ b/core/modules/history/lib/Drupal/history/Plugin/views/filter/HistoryUserTimestamp.php @@ -25,13 +25,6 @@ class HistoryUserTimestamp extends FilterPluginBase { // Don't display empty space where the operator would be. var $no_operator = TRUE; - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - public function buildExposeForm(&$form, &$form_state) { parent::buildExposeForm($form, $form_state); // @todo There are better ways of excluding required and multiple (object flags) diff --git a/core/modules/image/image.local_tasks.yml b/core/modules/image/image.local_tasks.yml index 3bff783..3aeeebd 100644 --- a/core/modules/image/image.local_tasks.yml +++ b/core/modules/image/image.local_tasks.yml @@ -2,8 +2,3 @@ image.style_edit: title: 'Edit' route_name: image.style_edit tab_root_id: image.style_edit - -image.style_list: - title: List - route_name: image.style_list - tab_root_id: image.style_list diff --git a/core/modules/image/image.module b/core/modules/image/image.module index 5b0d9a3..23443ff 100644 --- a/core/modules/image/image.module +++ b/core/modules/image/image.module @@ -95,6 +95,11 @@ function image_menu() { 'description' => 'Configure styles that can be used for resizing or adjusting images on display.', 'route_name' => 'image.style_list', ); + $items['admin/config/media/image-styles/list'] = array( + 'title' => 'List', + 'description' => 'List the current image styles on the site.', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); $items['admin/config/media/image-styles/manage/%image_style'] = array( 'title' => 'Edit style', 'description' => 'Configure an image style.', diff --git a/core/modules/menu/menu.local_tasks.yml b/core/modules/menu/menu.local_tasks.yml index bcf4de8..3b2bf45 100644 --- a/core/modules/menu/menu.local_tasks.yml +++ b/core/modules/menu/menu.local_tasks.yml @@ -2,14 +2,3 @@ menu.menu_edit: title: 'Edit menu' route_name: menu.menu_edit tab_root_id: menu.menu_edit - -menu.overview_page: - title: 'List' - route_name: menu.overview_page - tab_root_id: menu.overview_page - -menu.settings: - title: 'Settings' - route_name: menu.settings - tab_root_id: menu.overview_page - weight: 100 diff --git a/core/modules/menu/menu.module b/core/modules/menu/menu.module index 3a30bfc..fc149ee 100644 --- a/core/modules/menu/menu.module +++ b/core/modules/menu/menu.module @@ -71,6 +71,16 @@ function menu_menu() { 'description' => 'Add new menus to your site, edit existing menus, and rename and reorganize menu links.', 'route_name' => 'menu.overview_page', ); + $items['admin/structure/menu/list'] = array( + 'title' => 'List menus', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/structure/menu/settings'] = array( + 'title' => 'Settings', + 'route_name' => 'menu.settings', + 'type' => MENU_LOCAL_TASK, + 'weight' => 100, + ); $items['admin/structure/menu/manage/%menu'] = array( 'title' => 'Edit menu', 'route_name' => 'menu.menu_edit', diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/DedupeBase.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/DedupeBase.php deleted file mode 100644 index 09ef9be..0000000 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/DedupeBase.php +++ /dev/null @@ -1,45 +0,0 @@ -configuration['postfix']) ? $this->configuration['postfix'] : ''; - $new_value = $value; - while ($this->exists($new_value)) { - $new_value = $value . $postfix . $i++; - } - return $new_value; - } - - /** - * This is a query checking the existence of some value. - * - * @return bool - */ - abstract protected function exists($value); - -} diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/DedupeEntity.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/DedupeEntity.php deleted file mode 100644 index 2c5b6a8..0000000 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/DedupeEntity.php +++ /dev/null @@ -1,41 +0,0 @@ -getEntityQuery()->condition($this->configuration['field'], $value)->count()->execute(); - } - - /** - * Returns an entity query object. - * - * @return \Drupal\Core\Entity\Query\QueryInterface - * The entity query object for the configured entity type. - */ - protected function getEntityQuery() { - if (!isset($this->entityQuery)) { - $this->entityQuery = \Drupal::entityQuery($this->configuration['entity_type']); - } - return $this->entityQuery; - } -} diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/Iterator.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/Iterator.php deleted file mode 100644 index 34206e6..0000000 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/Iterator.php +++ /dev/null @@ -1,59 +0,0 @@ - $new_value) { - $new_row = new Row($new_value, array()); - $migrate_executable->processRow($new_row, $this->configuration['process']); - $destination = $new_row->getDestination(); - if (array_key_exists('key', $this->configuration)) { - $key = $this->transformKey($key, $migrate_executable, $new_row); - } - $return[$key] = $destination; - } - return $return; - } - - /** - * Runs the process pipeline for the current key. - * - * @param string|int $key - * The current key. - * @param \Drupal\migrate\MigrateExecutable $migrate_executable - * The migrate executable helper class. - * @param \Drupal\migrate\Row $row - * The current row after processing. - * @return mixed - * The transformed key. - */ - protected function transformKey($key, MigrateExecutable $migrate_executable, Row $row) { - $process = array('key' => $this->configuration['key']); - $migrate_executable->processRow($row, $process, $key); - return $row->getDestinationProperty('key'); - } - -} diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/MachineName.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/MachineName.php deleted file mode 100644 index d6f8fb3..0000000 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/MachineName.php +++ /dev/null @@ -1,53 +0,0 @@ -getTransliteration()->transliterate($value, Language::LANGCODE_DEFAULT, '_'); - $new_value = strtolower($new_value); - $new_value = preg_replace('/[^a-z0-9_]+/', '_', $new_value); - return preg_replace('/_+/', '_', $new_value); - } - - /** - * @return \Drupal\Core\Transliteration\PHPTransliteration - */ - protected function getTransliteration() { - if (!isset($this->transliteration)) { - $this->transliteration = \Drupal::transliteration(); - } - return $this->transliteration; - } - -} - diff --git a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/StaticMap.php b/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/StaticMap.php deleted file mode 100644 index 863e41c..0000000 --- a/core/modules/migrate/lib/Drupal/migrate/Plugin/migrate/process/StaticMap.php +++ /dev/null @@ -1,44 +0,0 @@ -configuration['map'], $value, $key_exists); - if (!$key_exists) { - throw new MigrateException('Lookup failed.'); - } - return $new_value; - } - -} - diff --git a/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php b/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php deleted file mode 100644 index e4ccc75..0000000 --- a/core/modules/migrate/tests/Drupal/migrate/Tests/process/DedupeEntityTest.php +++ /dev/null @@ -1,131 +0,0 @@ - 'Dedupe entity process plugin', - 'description' => 'Tests the entity deduplication process plugin.', - 'group' => 'Migrate', - ); - } - - /** - * {@inheritdoc} - */ - public function setUp() { - $this->entityQuery = $this->getMockBuilder('Drupal\Core\Entity\Query\QueryInterface') - ->disableOriginalConstructor() - ->getMock(); - parent::setUp(); - } - - /** - * Tests the entity deduplication plugin when there is no duplication. - */ - public function testDedupeEntityNoDuplication() { - $configuration = array( - 'entity_type' => 'test_entity_type', - 'field' => 'test_field', - ); - $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array()); - $this->entityQueryExpects(0); - $plugin->setEntityQuery($this->entityQuery); - $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty'); - $this->assertSame($return, 'test'); - } - - /** - * Tests the entity deduplication plugin when there is duplication. - */ - public function testDedupeEntityDuplication() { - $configuration = array( - 'entity_type' => 'test_entity_type', - 'field' => 'test_field', - ); - $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array()); - $this->entityQueryExpects(3); - $plugin->setEntityQuery($this->entityQuery); - $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty'); - $this->assertSame($return, 'test3'); - } - - /** - * Tests the entity deduplication plugin when there is no duplication. - */ - public function testDedupeEntityNoDuplicationWithPostfix() { - $configuration = array( - 'entity_type' => 'test_entity_type', - 'field' => 'test_field', - 'postfix' => '_', - ); - $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array()); - $this->entityQueryExpects(0); - $plugin->setEntityQuery($this->entityQuery); - $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty'); - $this->assertSame($return, 'test'); - } - - /** - * Tests the entity deduplication plugin when there is duplication. - */ - public function testDedupeEntityDuplicationWithPostfix() { - $configuration = array( - 'entity_type' => 'test_entity_type', - 'field' => 'test_field', - 'postfix' => '_', - ); - $plugin = new TestDedupeEntity($configuration, 'dedupe_entity', array()); - $this->entityQueryExpects(2); - $plugin->setEntityQuery($this->entityQuery); - $return = $plugin->transform('test', $this->migrateExecutable, $this->row, 'testpropertty'); - $this->assertSame($return, 'test_2'); - } - - /** - * Helper function to add expectations to the mock entity query object. - * - * @param int $count - * The number of deduplications to be set up. - */ - protected function entityQueryExpects($count) { - $this->entityQuery->expects($this->exactly($count + 1)) - ->method('condition') - ->will($this->returnValue($this->entityQuery)); - $this->entityQuery->expects($this->exactly($count + 1)) - ->method('count') - ->will($this->returnValue($this->entityQuery)); - $this->entityQuery->expects($this->exactly($count + 1)) - ->method('execute') - ->will($this->returnCallback(function () use (&$count) { return $count--;})); - } -} - -class TestDedupeEntity extends DedupeEntity { - function setEntityQuery(QueryInterface $entity_query) { - $this->entityQuery = $entity_query; - } -} diff --git a/core/modules/migrate/tests/Drupal/migrate/Tests/process/IteratorTest.php b/core/modules/migrate/tests/Drupal/migrate/Tests/process/IteratorTest.php deleted file mode 100644 index 39aeb54..0000000 --- a/core/modules/migrate/tests/Drupal/migrate/Tests/process/IteratorTest.php +++ /dev/null @@ -1,101 +0,0 @@ - 'test', - ); - - /** - * @var bool - */ - protected $mapJoinable = FALSE; - - /** - * {@inheritdoc} - */ - public static function getInfo() { - return array( - 'name' => 'Iterator process plugin', - 'description' => 'Tests the iterator process plugin.', - 'group' => 'Migrate', - ); - } - - /** - * Tests the iterator process plugin. - */ - function testIterator() { - $migration = $this->getMigration(); - // Set up the properties for the iterator. - $configuration = array( - 'process' => array( - 'foo' => 'source_foo', - 'id' => 'source_id', - ), - 'key' => '@id', - ); - $plugin = new Iterator($configuration, 'iterator', array()); - // Manually create the plugins. Migration::getProcessPlugins does this - // normally but the plugin system is not available. - foreach ($configuration['process'] as $destination => $source) { - $iterator_plugins[$destination][] = new Get(array('source' => $source), 'get', array()); - } - $migration->expects($this->at(1)) - ->method('getProcessPlugins') - ->will($this->returnValue($iterator_plugins)); - // Set up the key plugins. - $key_plugin['key'][] = new Get(array('source' => '@id'), 'get', array()); - $migration->expects($this->at(2)) - ->method('getProcessPlugins') - ->will($this->returnValue($key_plugin)); - $migrate_executable = new MigrateExecutable($migration, $this->getMock('Drupal\migrate\MigrateMessageInterface')); - - // The current value of the pipeline. - $current_value = array( - array( - 'source_foo' => 'test', - 'source_id' => 42, - ), - ); - // This is not used but the interface requires it, so create an empty row. - $row = new Row(array(), array()); - - // After transformation, check to make sure that source_foo and source_id's - // values ended up in the proper destinations, and that the value of the - // key (@id) is the same as the destination ID (42). - $new_value = $plugin->transform($current_value, $migrate_executable, $row, 'test'); - $this->assertSame(count($new_value), 1); - $this->assertSame(count($new_value[42]), 2); - $this->assertSame($new_value[42]['foo'], 'test'); - $this->assertSame($new_value[42]['id'], 42); - } -} diff --git a/core/modules/migrate/tests/Drupal/migrate/Tests/process/MachineNameTest.php b/core/modules/migrate/tests/Drupal/migrate/Tests/process/MachineNameTest.php deleted file mode 100644 index 0c7b24b..0000000 --- a/core/modules/migrate/tests/Drupal/migrate/Tests/process/MachineNameTest.php +++ /dev/null @@ -1,93 +0,0 @@ - 'Machine mame process plugin', - 'description' => 'Tests the machine name process plugin.', - 'group' => 'Migrate', - ); - } - - /** - * {@inheritdoc} - */ - public function setUp() { - $this->transliteration = $this->getMockBuilder('Drupal\Component\Transliteration\TransliterationInterface') - ->disableOriginalConstructor() - ->getMock(); - $this->row = $this->getMockBuilder('Drupal\migrate\Row') - ->disableOriginalConstructor() - ->getMock(); - $this->migrateExecutable = $this->getMockBuilder('Drupal\migrate\MigrateExecutable') - ->disableOriginalConstructor() - ->getMock(); - parent::setUp(); - } - - /** - * Tests machine name transformation of non-alphanumeric characters. - */ - public function testMachineNames() { - - // Tests the following transformations: - // - non-alphanumeric character (including spaces) -> underscore, - // - Uppercase -> lowercase, - // - Multiple consecutive underscore -> single underscore. - $human_name_ascii = 'foo2, the.bar;2*&the%baz!YEE____HaW '; - $human_name = $human_name_ascii .'áéő'; - $expected_result = 'foo2_the_bar_2_the_baz_yee_haw_aeo'; - // Test for calling transliterate on mock object. - $this->transliteration - ->expects($this->once()) - ->method('transliterate') - ->with($human_name) - ->will($this->returnValue($human_name_ascii . 'aeo')); - - $plugin = new TestMachineName(array(), 'machine_name', array()); - $plugin->setTransliteration($this->transliteration); - $value = $plugin->transform($human_name, $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertEquals($expected_result, $value); - } - -} - -namespace Drupal\migrate\Plugin\migrate\process; - -use Drupal\Component\Transliteration\TransliterationInterface; - -class TestMachineName extends MachineName { - public function setTransliteration(TransliterationInterface $transliteration) { - $this->transliteration = $transliteration; - } -} diff --git a/core/modules/migrate/tests/Drupal/migrate/Tests/process/StaticMapTest.php b/core/modules/migrate/tests/Drupal/migrate/Tests/process/StaticMapTest.php deleted file mode 100644 index 5bd66cb..0000000 --- a/core/modules/migrate/tests/Drupal/migrate/Tests/process/StaticMapTest.php +++ /dev/null @@ -1,77 +0,0 @@ - 'Map process plugin', - 'description' => 'Tests the map process plugin.', - 'group' => 'Migrate', - ); - } - - /** - * {@inheritdoc} - */ - function setUp() { - $this->row = $this->getMockBuilder('Drupal\migrate\Row') - ->disableOriginalConstructor() - ->getMock(); - $this->migrateExecutable = $this->getMockBuilder('Drupal\migrate\MigrateExecutable') - ->disableOriginalConstructor() - ->getMock(); - $configuration['map']['foo']['bar'] = 'baz'; - $this->plugin = new StaticMap($configuration, 'map', array()); - parent::setUp(); - } - - /** - * Tests map when the source is a string. - */ - function testMapWithSourceString() { - $value = $this->plugin->transform('foo', $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, array('bar' => 'baz')); - } - - /** - * Tests map when the source is a list. - */ - function testMapWithSourceList() { - $value = $this->plugin->transform(array('foo', 'bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); - $this->assertSame($value, 'baz'); - } - - /** - * Tests when the source is empty. - * - * @expectedException \Drupal\migrate\MigrateException - */ - function testMapwithEmptySource() { - $this->plugin->transform(array(), $this->migrateExecutable, $this->row, 'destinationproperty'); - } - - /** - * Tests when the source is invalid. - * - * @expectedException \Drupal\migrate\MigrateException - */ - function testMapwithInvalidSource() { - $this->plugin->transform(array('bar'), $this->migrateExecutable, $this->row, 'destinationproperty'); - } - -} diff --git a/core/modules/node/config/views.view.content.yml b/core/modules/node/config/views.view.content.yml index 64f1acf..e18480a 100644 --- a/core/modules/node/config/views.view.content.yml +++ b/core/modules/node/config/views.view.content.yml @@ -18,7 +18,7 @@ display: type: basic options: submit_button: Filter - reset_button: true + reset_button: false reset_button_label: Reset exposed_sorts_label: 'Sort by' expose_sort_order: true diff --git a/core/modules/node/lib/Drupal/node/Plugin/views/field/Link.php b/core/modules/node/lib/Drupal/node/Plugin/views/field/Link.php index fb8b72a..4ab3c85 100644 --- a/core/modules/node/lib/Drupal/node/Plugin/views/field/Link.php +++ b/core/modules/node/lib/Drupal/node/Plugin/views/field/Link.php @@ -20,13 +20,6 @@ */ class Link extends FieldPluginBase { - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - protected function defineOptions() { $options = parent::defineOptions(); $options['text'] = array('default' => '', 'translatable' => TRUE); diff --git a/core/modules/node/node.local_tasks.yml b/core/modules/node/node.local_tasks.yml index 8be7fa6..c60dc0c 100644 --- a/core/modules/node/node.local_tasks.yml +++ b/core/modules/node/node.local_tasks.yml @@ -24,7 +24,3 @@ node.type_edit: title: 'Edit' route_name: node.type_edit tab_root_id: node.type_edit -node.overview_types: - title: List - route_name: node.overview_types - tab_root_id: node.overview_types diff --git a/core/modules/node/node.module b/core/modules/node/node.module index 1702ee9..faf8217 100644 --- a/core/modules/node/node.module +++ b/core/modules/node/node.module @@ -991,6 +991,10 @@ function node_menu() { 'description' => 'Manage content types, including default status, front page promotion, comment settings, etc.', 'route_name' => 'node.overview_types', ); + $items['admin/structure/types/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); $items['node/add'] = array( 'title' => 'Add content', 'route_name' => 'node.add_page', diff --git a/core/modules/path/path.local_tasks.yml b/core/modules/path/path.local_tasks.yml deleted file mode 100644 index 84e74d2..0000000 --- a/core/modules/path/path.local_tasks.yml +++ /dev/null @@ -1,4 +0,0 @@ -path.admin_overview: - title: List - route_name: path.admin_overview - tab_root_id: path.admin_overview diff --git a/core/modules/path/path.module b/core/modules/path/path.module index 8e96610..e638eb9 100644 --- a/core/modules/path/path.module +++ b/core/modules/path/path.module @@ -63,6 +63,10 @@ function path_menu() { 'route_name' => 'path.admin_overview', 'weight' => -5, ); + $items['admin/config/search/path/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); $items['admin/config/search/path/edit/%path'] = array( 'title' => 'Edit alias', 'route_name' => 'path.admin_edit', diff --git a/core/modules/picture/picture.local_tasks.yml b/core/modules/picture/picture.local_tasks.yml deleted file mode 100644 index 29b8446..0000000 --- a/core/modules/picture/picture.local_tasks.yml +++ /dev/null @@ -1,5 +0,0 @@ -picture.mapping_page_edit: - title: Edit - route_name: picture.mapping_page_edit - tab_root_id: picture.mapping_page_edit - weight: -10 diff --git a/core/modules/picture/picture.module b/core/modules/picture/picture.module index 72f52a5..b9b3b01 100644 --- a/core/modules/picture/picture.module +++ b/core/modules/picture/picture.module @@ -63,6 +63,11 @@ function picture_menu() { 'title' => 'Edit picture mapping', 'route_name' => 'picture.mapping_page_edit', ); + $items['admin/config/media/picturemapping/%picture_mapping/edit'] = array( + 'title' => 'Edit', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => -10, + ); $items['admin/config/media/picturemapping/%picture_mapping/duplicate'] = array( 'title' => 'Duplicate picture mapping', 'route_name' => 'picture.mapping_page_duplicate', diff --git a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php index 5d2335c..0ceef4b 100644 --- a/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php +++ b/core/modules/search/lib/Drupal/search/Form/SearchSettingsForm.php @@ -6,7 +6,6 @@ namespace Drupal\search\Form; -use Drupal\Core\Cache\Cache; use Drupal\Core\Config\ConfigFactory; use Drupal\Core\Config\Context\ContextInterface; use Drupal\Core\Extension\ModuleHandlerInterface; @@ -264,7 +263,6 @@ public function submitForm(array &$form, array &$form_state) { $this->searchSettings->set('active_plugins', $new_plugins); drupal_set_message($this->t('The active search plugins have been changed.')); $this->state->set('menu_rebuild_needed', TRUE); - Cache::deleteTags(array('local_task' => TRUE)); } $this->searchSettings->save(); } diff --git a/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php b/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php deleted file mode 100644 index f18e699..0000000 --- a/core/modules/search/lib/Drupal/search/Plugin/Derivative/SearchLocalTask.php +++ /dev/null @@ -1,42 +0,0 @@ -derivatives = array(); - - $default_info = search_get_default_plugin_info(); - if ($default_info) { - foreach (\Drupal::service('plugin.manager.search')->getActiveDefinitions() as $plugin_id => $search_info) { - $this->derivatives[$plugin_id] = array( - 'title' => $search_info['title'], - 'route_name' => 'search.view_' . $plugin_id, - 'tab_root_id' => 'search.plugins:' . $default_info['id'], - ); - if ($plugin_id == $default_info['id']) { - $this->derivatives[$plugin_id]['weight'] = -10; - } - else { - $this->derivatives[$plugin_id]['weight'] = 0; - } - } - } - return $this->derivatives; - } - -} diff --git a/core/modules/search/search.local_tasks.yml b/core/modules/search/search.local_tasks.yml deleted file mode 100644 index ac332d7..0000000 --- a/core/modules/search/search.local_tasks.yml +++ /dev/null @@ -1,3 +0,0 @@ -search.plugins: - class: \Drupal\Core\Menu\LocalTaskDefault - derivative: \Drupal\search\Plugin\Derivative\SearchLocalTask diff --git a/core/modules/search/search.module b/core/modules/search/search.module index 4afd6dc..56e6859 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -167,6 +167,25 @@ function search_menu() { 'type' => MENU_VISIBLE_IN_BREADCRUMB, ); + // Add paths for searching. We add each plugin search path twice: once without + // and once with %menu_tail appended. The reason for this is that we want to + // preserve keywords when switching tabs, and also to have search tabs + // highlighted properly. The only way to do that within the Drupal menu + // system appears to be having two sets of tabs. See discussion on issue + // http://drupal.org/node/245103 for details. + + $default_info = search_get_default_plugin_info(); + if ($default_info) { + foreach (\Drupal::service('plugin.manager.search')->getActiveDefinitions() as $plugin_id => $search_info) { + $path = 'search/' . $search_info['path']; + $items[$path] = array( + 'title' => $search_info['title'], + 'route_name' => 'search.view_' . $plugin_id, + 'type' => MENU_LOCAL_TASK, + 'weight' => $plugin_id == $default_info['id'] ? -10 : 0, + ); + } + } return $items; } diff --git a/core/modules/simpletest/simpletest.local_tasks.yml b/core/modules/simpletest/simpletest.local_tasks.yml deleted file mode 100644 index b6eea38..0000000 --- a/core/modules/simpletest/simpletest.local_tasks.yml +++ /dev/null @@ -1,9 +0,0 @@ -simpletest.test_form: - title: List - route_name: simpletest.test_form - tab_root_id: simpletest.test_form -simpletest.settings: - title: Settings - route_name: simpletest.settings - tab_root_id: simpletest.test_form - weight: 100 diff --git a/core/modules/simpletest/simpletest.module b/core/modules/simpletest/simpletest.module index bd50676..5d15878 100644 --- a/core/modules/simpletest/simpletest.module +++ b/core/modules/simpletest/simpletest.module @@ -38,6 +38,17 @@ function simpletest_menu() { 'route_name' => 'simpletest.test_form', 'weight' => -5, ); + $items['admin/config/development/testing/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/config/development/testing/settings'] = array( + 'title' => 'Settings', + 'route_name' => 'simpletest.settings', + 'access arguments' => array('administer unit tests'), + 'type' => MENU_LOCAL_TASK, + 'weight' => 100, + ); $items['admin/config/development/testing/results/%'] = array( 'title' => 'Test result', 'description' => 'View result of tests.', diff --git a/core/modules/system/lib/Drupal/system/Tests/Database/DeleteTruncateTest.php b/core/modules/system/lib/Drupal/system/Tests/Database/DeleteTruncateTest.php old mode 100755 new mode 100644 index 6f98e7c..3d72da1 --- a/core/modules/system/lib/Drupal/system/Tests/Database/DeleteTruncateTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Database/DeleteTruncateTest.php @@ -69,7 +69,6 @@ function testSimpleDelete() { */ function testTruncate() { $num_records_before = db_query("SELECT COUNT(*) FROM {test}")->fetchField(); - $this->assertTrue($num_records_before > 0, 'The table is not empty.'); db_truncate('test')->execute(); diff --git a/core/modules/system/tests/modules/batch_test/batch_test.local_tasks.yml b/core/modules/system/tests/modules/batch_test/batch_test.local_tasks.yml deleted file mode 100644 index ea4a6fd..0000000 --- a/core/modules/system/tests/modules/batch_test/batch_test.local_tasks.yml +++ /dev/null @@ -1,46 +0,0 @@ -batch_test.test_form: - title: Simple - route_name: batch_test.test_form - tab_root_id: batch_test.test_form - -batch_test.multistep: - title: Multistep - route_name: batch_test.multistep - tab_root_id: batch_test.test_form - weight: 1 - -batch_test.chained: - title: Chained - route_name: batch_test.chained - tab_root_id: batch_test.test_form - weight: 2 - -batch_test.programmatic: - title: Chained - route_name: batch_test.programmatic - tab_root_id: batch_test.test_form - weight: 3 - -batch_test.no_form: - title: 'No form' - route_name: batch_test.no_form - tab_root_id: batch_test.test_form - weight: 4 - -batch_test.large_percentage: - title: 'Large percentage' - route_name: batch_test.large_percentage - tab_root_id: batch_test.test_form - weight: 5 - -batch_test.nested_programmatic: - title: 'Nested programmatic' - route_name: batch_test.nested_programmatic - tab_root_id: batch_test.test_form - weight: 6 - -batch_test.redirect: - title: 'Redirect' - route_name: batch_test.redirect - tab_root_id: batch_test.test_form - weight: 7 diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module index ba8b273..0dbbff8 100644 --- a/core/modules/system/tests/modules/batch_test/batch_test.module +++ b/core/modules/system/tests/modules/batch_test/batch_test.module @@ -15,6 +15,57 @@ function batch_test_menu() { 'title' => 'Batch test', 'route_name' => 'batch_test.test_form', ); + // Simple form: one submit handler, setting a batch. + $items['batch-test/simple'] = array( + 'title' => 'Simple', + 'type' => MENU_DEFAULT_LOCAL_TASK, + 'weight' => 0, + ); + // Multistep form: two steps, each setting a batch. + $items['batch-test/multistep'] = array( + 'title' => 'Multistep', + 'route_name' => 'batch_test.multistep', + 'type' => MENU_LOCAL_TASK, + 'weight' => 1, + ); + // Chained form: four submit handlers, several of which set a batch. + $items['batch-test/chained'] = array( + 'title' => 'Chained', + 'route_name' => 'batch_test.chained', + 'type' => MENU_LOCAL_TASK, + 'weight' => 2, + ); + // Programmatic form: the page submits the 'Chained' form through + // drupal_form_submit(). + $items['batch-test/programmatic'] = array( + 'route_name' => 'batch_test.programmatic', + 'type' => MENU_LOCAL_TASK, + 'weight' => 3, + ); + // No form: fire a batch simply by accessing a page. + $items['batch-test/no-form'] = array( + 'route_name' => 'batch_test.no_form', + 'type' => MENU_LOCAL_TASK, + 'weight' => 4, + ); + // No form: fire a batch; return > 100% complete + $items['batch-test/large-percentage'] = array( + 'route_name' => 'batch_test.large_percentage', + 'type' => MENU_LOCAL_TASK, + 'weight' => 5, + ); + // Tests programmatic form submission within a batch operation. + $items['batch-test/nested-programmatic'] = array( + 'route_name' => 'batch_test.nested_programmatic', + 'type' => MENU_LOCAL_TASK, + 'weight' => 6, + ); + // Landing page to test redirects. + $items['batch-test/redirect'] = array( + 'route_name' => 'batch_test.redirect', + 'type' => MENU_LOCAL_TASK, + 'weight' => 7, + ); return $items; } diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 1db21da..c5f6153 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -260,6 +260,15 @@ function taxonomy_menu() { 'title callback' => 'entity_page_label', 'title arguments' => array(4), ); + $items['admin/structure/taxonomy/manage/%taxonomy_vocabulary/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); + $items['admin/structure/taxonomy/manage/%taxonomy_vocabulary/edit'] = array( + 'title' => 'Edit', + 'route_name' => 'taxonomy.vocabulary_edit', + 'type' => MENU_LOCAL_TASK, + ); return $items; } diff --git a/core/modules/toolbar/css/toolbar.theme.css b/core/modules/toolbar/css/toolbar.theme.css index 3b1f105..2135e5f 100644 --- a/core/modules/toolbar/css/toolbar.theme.css +++ b/core/modules/toolbar/css/toolbar.theme.css @@ -63,13 +63,13 @@ padding-right: 0; padding-left: 5em; } -.toolbar .toolbar-tray-vertical { +.toolbar .toolbar-tray-vertical > .toolbar-lining:before { background-color: #ffffff; border-right: 1px solid #aaaaaa; /* LTR */ box-shadow: -1px 0 5px 2px rgba(0, 0, 0, 0.3333); /* LTR */ } +[dir="rtl"] .toolbar .toolbar-tray-vertical > .toolbar-lining:before { border-left: 1px solid #aaaaaa; -[dir="rtl"] .toolbar .toolbar-tray-vertical { border-right: 0 none; box-shadow: 1px 0 5px 2px rgba(0, 0, 0, 0.3333); } diff --git a/core/modules/update/templates/update-report.html.twig b/core/modules/update/templates/update-report.html.twig new file mode 100644 index 0000000..13c3df5 --- /dev/null +++ b/core/modules/update/templates/update-report.html.twig @@ -0,0 +1,135 @@ +{# +/** + * @file + * Default theme implementation for the project status report. + * + * Available variables: + * - last_checked: A flag indicating whether the site checked for updates. + * - time: The time the site last checked for updates. + * - link: A link to check for updates manually. + * - project_types: A list of project types. + * - label: The project type label. + * - projects: Data about each project's status. + * - title: The project title. + * - attributes: HTML attributes for the project row. + * - status_label: The project status label. + * - reason: The reason you should update the project. + * - icon: The project status version indicator icon. + * - existing_version: The version of the installed project. + * - versions: The available versions of the project. + * - install_type: The type of project (e.g., dev). + * - datestamp: The date/time of a project version's release. + * - extra: HTML attributes and additional information about the project. + * - attributes: HTML attributes for the extra item. + * - label: The label for an extra item. + * - data: The data about an extra item. + * - includes: The projects within a project. + * - base_themes: The base theme declared for the project. + * - sub_themes: The subthemes declared for the project. + * + * @see template_preprocess_update_report() + * + * @ingroup themeable + */ +#} +
    + {% if last_checked %} + {% trans %} + Last checked: {{ time }} ago + {% endtrans %} + {% else %} + {{ 'Last checked: never'|t }} + {% endif %} + ({{ link }}) +
    + +{% for project_type in project_types %} +

    {{ project_type.label }}

    + + + {% for project in project_type.projects %} + + + + {% endfor %} + +
    + {% spaceless %} +
    + {%- if project.status_label -%} + {{ project.status_label }} + {%- else -%} + {{ project.reason }} + {%- endif -%} + {{ project.icon }} +
    + {% endspaceless %} + +
    {{ project.title }} {{ project.existing_version }} + {% if project.install_type == 'dev' and project.datestamp %} + ({{ project.datestamp }}) + {% endif %} +
    + + {% if project.versions %} +
    + {% for version in project.versions %} + {{ version }} + {% endfor %} +
    + {% endif %} + +
    + {% if project.extra %} +
    + {% for extra in project.extra %} + + {{ extra.label }}: {{ extra.data }} +
    + {% endfor %} +
    + {% endif %} +
    + {% set includes = project.includes|join(', ') %} + {% if project.disabled %} + {{ 'Includes:'|t }} +
      +
    • + {% trans %} + Enabled: {{ includes|placeholder }} + {% endtrans %} +
    • +
    • + {% set disabled = project.disabled|join(', ') %} + {% trans %} + Disabled: {{ disabled|placeholder }} + {% endtrans %} +
    • +
    + {% else %} + {% trans %} + Includes: {{ includes|placeholder }} + {% endtrans %} + {% endif %} +
    + + {% if project.base_themes %} + {% set basethemes = project.base_themes|join(', ') %} +
    + {% trans %} + Depends on: {{ basethemes|passthrough }} + {% endtrans %} +
    + {% endif %} + + {% if project.sub_themes %} + {% set subthemes = project.sub_themes|join(', ') %} +
    + {% trans %} + Required by: {{ subthemes|placeholder }} + {% endtrans %} +
    + {% endif %} + +
    +{% endfor %} diff --git a/core/modules/update/templates/update-version.html.twig b/core/modules/update/templates/update-version.html.twig new file mode 100644 index 0000000..e7d68d9 --- /dev/null +++ b/core/modules/update/templates/update-version.html.twig @@ -0,0 +1,30 @@ +{# +/** + * @file + * Default theme implementation for the version display of a project. + * + * Available variables: + * - attributes: HTML attributes for the update versions table. + * - version_link: Link to this version's release notes on drupal.org. + * - version_date: The date of the release. + * - version_links: Links to download this version and to this version's release + * notes. + * - tag: The title of the project. + * + * @see template_preprocess_update_version() + * + * @ingroup themeable + */ +#} + + + {{ tag }} + + {{ version_link }} + ({{ version_date }}) + + + {{ version_links }} + + + diff --git a/core/modules/update/update.manager.inc b/core/modules/update/update.manager.inc index 19c0dc1..1b1cd1d 100644 --- a/core/modules/update/update.manager.inc +++ b/core/modules/update/update.manager.inc @@ -279,27 +279,6 @@ function update_manager_update_form($form, $form_state = array(), $context) { } /** - * Returns HTML for the first page in the process of updating projects. - * - * @param $variables - * An associative array containing: - * - form: A render element representing the form. - * - * @ingroup themeable - */ -function theme_update_manager_update_form($variables) { - $form = $variables['form']; - $last = \Drupal::state()->get('update.last_check') ?: 0; - $update_last_check = array( - '#theme' => 'update_last_check', - '#last' => $last, - ); - $output = drupal_render($update_last_check); - $output .= drupal_render_children($form); - return $output; -} - -/** * Form validation handler for update_manager_update_form(). * * Ensures that at least one project is selected. diff --git a/core/modules/update/update.module b/core/modules/update/update.module index af8143b..956e3ab 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -198,24 +198,15 @@ function update_manager_access() { */ function update_theme() { return array( - 'update_manager_update_form' => array( - 'render element' => 'form', - 'file' => 'update.manager.inc', - ), - 'update_last_check' => array( - 'variables' => array('last' => NULL), - ), 'update_report' => array( 'variables' => array('data' => NULL), 'file' => 'update.report.inc', + 'template' => 'update-report', ), 'update_version' => array( 'variables' => array('version' => NULL, 'tag' => NULL, 'class' => array()), 'file' => 'update.report.inc', - ), - 'update_status_label' => array( - 'variables' => array('status' => NULL), - 'file' => 'update.report.inc', + 'template' => 'update-version', ), ); } @@ -555,30 +546,6 @@ function _update_project_status_sort($a, $b) { } /** - * Returns HTML for the last time we checked for update data. - * - * In addition to properly formatting the given timestamp, this function also - * provides a "Check manually" link that refreshes the available update and - * redirects back to the same page. - * - * @param $variables - * An associative array containing: - * - last: The timestamp when the site last checked for available updates. - * - * @see theme_update_report() - * @see theme_update_available_updates_form() - * @ingroup themeable - */ -function theme_update_last_check($variables) { - $last = $variables['last']; - $output = '
    '; - $output .= $last ? t('Last checked: @time ago', array('@time' => format_interval(REQUEST_TIME - $last))) : t('Last checked: never'); - $output .= ' (' . l(t('Check manually'), 'admin/reports/updates/check', array('query' => drupal_get_destination())) . ')'; - $output .= "
    \n"; - return $output; -} - -/** * Implements hook_verify_update_archive(). * * First, we ensure that the archive isn't a copy of Drupal core, which the diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc index 51da7dd..98b450d 100644 --- a/core/modules/update/update.report.inc +++ b/core/modules/update/update.report.inc @@ -5,8 +5,12 @@ * Code required only when rendering the available updates report. */ +use Drupal\Core\Template\Attribute; + /** - * Returns HTML for the project status report. + * Prepares variables for project status report templates. + * + * Default template: update-report.html.twig. * * @param array $variables * An associative array containing: @@ -14,22 +18,15 @@ * * @ingroup themeable */ -function theme_update_report($variables) { +function template_preprocess_update_report(&$variables) { $data = $variables['data']; + $notification_level = \Drupal::config('update.settings')->get('notification.threshold'); $last = \Drupal::state()->get('update.last_check') ?: 0; - $update_last_check = array( - '#theme' => 'update_last_check', - '#last' => $last, - ); - $output = drupal_render($update_last_check); - - if (!is_array($data)) { - $output .= '

    ' . $data . '

    '; - return $output; - } + $variables['last_checked'] = ($last != NULL); + $variables['time'] = format_interval(REQUEST_TIME - $last); + $variables['link'] = l(t('Check manually'), 'admin/reports/updates/check', array('query' => drupal_get_destination())); - $header = array(); $rows = array(); // Create an array of status values keyed by module or theme name, since @@ -80,32 +77,58 @@ function theme_update_report($variables) { '#title' => $text, ); - $row = '
    '; - $update_status_label = array('#theme' => 'update_status_label', '#status' => $project['status']); - $status_label = drupal_render($update_status_label); - $row .= !empty($status_label) ? $status_label : check_plain($project['reason']); - $row .= '' . drupal_render($icon) . ''; - $row .= "
    \n"; + // Used to collect the project values. + $row = array(); + $row['attributes'] = new Attribute(array('class' => $class)); + $row['icon'] = $icon; - $row .= '
    '; + $row['status_attributes'] = new Attribute(array('class' => array())); + switch ($project['status']) { + case UPDATE_NOT_SECURE: + $row['status_attributes']['class'] = 'security-error'; + $row['status_label'] = t('Security update required!'); + break; + case UPDATE_REVOKED: + $row['status_attributes']['class'] = 'revoked'; + $row['status_label'] = t('Revoked!'); + break; + case UPDATE_NOT_SUPPORTED: + $row['status_attributes']['class'] = 'not-supported'; + $row['status_label'] = t('Not supported!'); + break; + case UPDATE_NOT_CURRENT: + $row['status_attributes']['class'] = 'not-current'; + $row['status_label'] = t('Update available'); + break; + case UPDATE_CURRENT: + $row['status_attributes']['class'] = 'current'; + $row['status_label'] = t('Up to date'); + break; + } + + $row['reason'] = (!empty($project['reason'])) ? check_plain($project['reason']) : ''; + + // Set the project title. if (isset($project['title'])) { if (isset($project['link'])) { - $row .= l($project['title'], $project['link']); + $row['title'] = l($project['title'], $project['link']); } else { - $row .= check_plain($project['title']); + $row['title'] = check_plain($project['title']); } } else { - $row .= check_plain($project['name']); + $row['title'] = check_plain($project['name']); } - $row .= ' ' . check_plain($project['existing_version']); + + // Clean up the version for twig. + $row['existing_version'] = check_plain($project['existing_version']); + if ($project['install_type'] == 'dev' && !empty($project['datestamp'])) { - $row .= ' (' . format_date($project['datestamp'], 'custom', 'Y-M-d') . ')'; + $row['datestamp'] = format_date($project['datestamp'], 'custom', 'Y-M-d'); } - $row .= "
    \n"; - $versions_inner = ''; + $versions_inner = array(); $security_class = array(); $version_class = array(); if (isset($project['recommended'])) { @@ -115,7 +138,10 @@ function theme_update_report($variables) { // If there's only 1 security update and it has the same version we're // recommending, give it the same CSS class as if it was recommended, // but don't print out a separate "Recommended" line for this project. - if (!empty($project['security updates']) && count($project['security updates']) == 1 && $project['security updates'][0]['version'] === $project['recommended']) { + if (!empty($project['security updates']) + && count($project['security updates']) == 1 + && $project['security updates'][0]['version'] === $project['recommended'] + ) { $security_class[] = 'version-recommended'; $security_class[] = 'version-recommended-strong'; } @@ -134,141 +160,128 @@ function theme_update_report($variables) { ) { $version_class[] = 'version-recommended-strong'; } - $update_version = array( + $versions_inner[] = array( '#theme' => 'update_version', '#version' => $project['releases'][$project['recommended']], '#tag' => t('Recommended version:'), '#class' => $version_class, ); - $versions_inner .= drupal_render($update_version); } // Now, print any security updates. if (!empty($project['security updates'])) { $security_class[] = 'version-security'; foreach ($project['security updates'] as $security_update) { - $update_version = array( + $versions_inner[] = array( '#theme' => 'update_version', '#version' => $security_update, '#tag' => t('Security update:'), '#class' => $security_class, ); - $versions_inner .= drupal_render($update_version); } } } if ($project['recommended'] !== $project['latest_version']) { - $update_version = array( + $versions_inner[] = array( '#theme' => 'update_version', '#version' => $project['releases'][$project['latest_version']], '#tag' => t('Latest version:'), '#class' => array('version-latest'), ); - $versions_inner .= drupal_render($update_version); } if ($project['install_type'] == 'dev' && $project['status'] != UPDATE_CURRENT && isset($project['dev_version']) && $project['recommended'] !== $project['dev_version']) { - $update_version = array( + $versions_inner[] = array( '#theme' => 'update_version', '#version' => $project['releases'][$project['dev_version']], '#tag' => t('Development version:'), '#class' => array('version-latest'), ); - $versions_inner .= drupal_render($update_version); } } if (isset($project['also'])) { foreach ($project['also'] as $also) { - $update_version = array( + $versions_inner[] = array( '#theme' => 'update_version', '#version' => $project['releases'][$also], '#tag' => t('Also available:'), '#class' => array('version-also-available'), ); - $versions_inner .= drupal_render($update_version); } } if (!empty($versions_inner)) { - $row .= "
    \n" . $versions_inner . "
    \n"; + $row['versions'] = $versions_inner; } - $row .= "
    \n"; + + $row['extra'] = array(); if (!empty($project['extra'])) { - $row .= '
    ' . "\n"; foreach ($project['extra'] as $value) { - $row .= '
    '; - $row .= check_plain($value['label']) . ': '; - $row .= drupal_placeholder($value['data']); - $row .= "
    \n"; + $extra_item = array(); + $extra_item['attributes'] = new Attribute(array('class' => $value['class'])); + $extra_item['label'] = check_plain($value['label']); + $extra_item['data'] = drupal_placeholder($value['data']); + $row['extra'][$key] = $extra_item; } - $row .= "
    \n"; // extra div. } - $row .= '
    '; - sort($project['includes']); + // Make sure we start with a clean slate for each project in the report. + $row['disabled'] = array(); + $row['includes'] = array(); if (!empty($project['disabled'])) { sort($project['disabled']); - // Make sure we start with a clean slate for each project in the report. - $includes_items = array(); - $row .= t('Includes:'); - $includes_items[] = t('Enabled: %includes', array('%includes' => implode(', ', $project['includes']))); - $includes_items[] = t('Disabled: %disabled', array('%disabled' => implode(', ', $project['disabled']))); - $item_list = array( - '#theme' => 'item_list', - '#items' => $includes_items, - ); - $row .= drupal_render($item_list); - } - else { - $row .= t('Includes: %includes', array('%includes' => implode(', ', $project['includes']))); + $row['disabled'] = $project['disabled']; } - $row .= "
    \n"; + + sort($project['includes']); + $row['includes'] = $project['includes']; if (!empty($project['base_themes'])) { - $row .= '
    '; asort($project['base_themes']); $base_themes = array(); foreach ($project['base_themes'] as $base_key => $base_theme) { - $update_status_label = array( - '#theme' => 'update_status_label', - '#status' => $status[$base_key], - ); switch ($status[$base_key]) { case UPDATE_NOT_SECURE: + $status_label = t('Security update required!'); + break; case UPDATE_REVOKED: + $status_label = t('Revoked!'); + break; case UPDATE_NOT_SUPPORTED: - $base_themes[] = t('%base_theme (!base_label)', array('%base_theme' => $base_theme, '!base_label' => drupal_render($update_status_label))); + $status_label = t('Not supported!'); break; - default: - $base_themes[] = drupal_placeholder($base_theme); + $status_label = ''; + } + + if ($status_label) { + $base_themes[] = t('%base_theme (!base_label)', array( + '%base_theme' => $base_theme, + '!base_label' => $status_label, + )); + } + else { + $base_themes[] = drupal_placeholder($base_theme); } } - $row .= t('Depends on: !basethemes', array('!basethemes' => implode(', ', $base_themes))); - $row .= "
    \n"; + $row['base_themes'] = $base_themes; } if (!empty($project['sub_themes'])) { - $row .= '
    '; sort($project['sub_themes']); - $row .= t('Required by: %subthemes', array('%subthemes' => implode(', ', $project['sub_themes']))); - $row .= "
    \n"; + $row['sub_themes'] = $project['sub_themes']; } - $row .= "
    \n"; // info div. - + // Build project rows. if (!isset($rows[$project['project_type']])) { $rows[$project['project_type']] = array(); } - $row_key = isset($project['title']) ? drupal_strtolower($project['title']) : drupal_strtolower($project['name']); - $rows[$project['project_type']][$row_key] = array( - 'class' => array($class), - 'data' => array($row), - ); + $row_key = !empty($project['title']) ? drupal_strtolower($project['title']) : drupal_strtolower($project['name']); + $rows[$project['project_type']][$row_key] = $row; } $project_types = array( @@ -278,19 +291,14 @@ function theme_update_report($variables) { 'module-disabled' => t('Disabled modules'), 'theme-disabled' => t('Disabled themes'), ); + $variables['project_types'] = array(); foreach ($project_types as $type_name => $type_label) { if (!empty($rows[$type_name])) { ksort($rows[$type_name]); - $output .= "\n

    " . $type_label . "

    \n"; - $table = array( - '#theme' => 'table', - '#header' => $header, - '#rows' => $rows[$type_name], - '#attributes' => array( - 'class' => array('update'), - ), + $variables['project_types'][] = array( + 'label' => $type_label, + 'projects' => $rows[$type_name], ); - $output .= drupal_render($table); } } @@ -302,42 +310,12 @@ function theme_update_report($variables) { ) ); drupal_render($assets); - - return $output; } /** - * Returns HTML for a label to display for a project's update status. + * Prepares variables for the version display of a project. * - * @param array $variables - * An associative array containing: - * - status: The integer code for a project's current update status. - * - * @see update_calculate_project_data() - * @ingroup themeable - */ -function theme_update_status_label($variables) { - switch ($variables['status']) { - case UPDATE_NOT_SECURE: - return '' . t('Security update required!') . ''; - - case UPDATE_REVOKED: - return '' . t('Revoked!') . ''; - - case UPDATE_NOT_SUPPORTED: - return '' . t('Not supported!') . ''; - - case UPDATE_NOT_CURRENT: - return '' . t('Update available') . ''; - - case UPDATE_CURRENT: - return '' . t('Up to date') . ''; - - } -} - -/** - * Returns HTML for the version display of a project. + * Default template: update-version.html.twig. * * @param array $variables * An associative array containing: @@ -347,40 +325,26 @@ function theme_update_status_label($variables) { * - date: The date of the release. * - download_link: The URL for the downloadable file. * - tag: The title of the project. - * - class: A string containing extra classes for the wrapping table. - * - * @ingroup themeable + * - class: An array containing extra classes for the wrapping table. */ -function theme_update_version($variables) { +function template_preprocess_update_version(&$variables) { $version = $variables['version']; - $tag = $variables['tag']; - $class = implode(' ', $variables['class']); - - $output = ''; - $output .= ''; - $output .= ''; - $output .= '\n"; - $output .= '\n"; - $output .= ''; - $output .= ''; - $output .= "
    ' . $tag . "'; - $output .= l($version['version'], $version['release_link']); - $output .= ' (' . format_date($version['date'], 'custom', 'Y-M-d') . ')'; - $output .= "
    \n"; - return $output; } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument/Uid.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument/Uid.php index 0c299d1..03c492a 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/argument/Uid.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument/Uid.php @@ -2,15 +2,13 @@ /** * @file - * Contains \Drupal\user\Plugin\views\argument\Uid. + * Definition of Drupal\user\Plugin\views\argument\Uid. */ namespace Drupal\user\Plugin\views\argument; -use Drupal\Component\Utility\String; -use Drupal\Core\Entity\EntityStorageControllerInterface; +use Drupal\Component\Annotation\PluginID; use Drupal\views\Plugin\views\argument\Numeric; -use Symfony\Component\DependencyInjection\ContainerInterface; /** * Argument handler to accept a user id. @@ -22,47 +20,23 @@ class Uid extends Numeric { /** - * The user storage controller. - * - * @var \Drupal\Core\Entity\EntityStorageControllerInterface - */ - protected $storageController; - - /** - * Constructs a Drupal\Component\Plugin\PluginBase object. - * - * @param array $configuration - * A configuration array containing information about the plugin instance. - * @param string $plugin_id - * The plugin_id for the plugin instance. - * @param array $plugin_definition - * The plugin implementation definition. - * @param \Drupal\Core\Entity\EntityStorageControllerInterface $storage_controller - * The user storage controller. - */ - public function __construct(array $configuration, $plugin_id, array $plugin_definition, EntityStorageControllerInterface $storage_controller) { - parent::__construct($configuration, $plugin_id, $plugin_definition); - $this->storageController = $storage_controller; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container, array $configuration, $plugin_id, array $plugin_definition) { - return new static($configuration, $plugin_id, $plugin_definition, - $container->get('entity.manager')->getStorageController('user')); - } - - /** * Override the behavior of title(). Get the name of the user. * * @return array * A list of usernames. */ public function titleQuery() { - return array_map(function($account) { - return String::checkPlain($account->label()); - }, $this->storageController->loadMultiple($this->value)); + if (!$this->argument) { + return array(\Drupal::config('user.settings')->get('anonymous')); + } + + $titles = array(); + + $users = user_load_multiple($this->value); + foreach ($users as $account) { + $titles[] = check_plain($account->label()); + } + return $titles; } } diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php index 88102b8..b13f388 100644 --- a/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php +++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/Link.php @@ -24,13 +24,6 @@ class Link extends FieldPluginBase { /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - /** * Overrides Drupal\views\Plugin\views\field\FieldPluginBase::init(). */ public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { diff --git a/core/modules/user/lib/Drupal/user/Tests/Views/HandlerArgumentUserUidTest.php b/core/modules/user/lib/Drupal/user/Tests/Views/HandlerArgumentUserUidTest.php index 2c44bd8..db9c51f 100644 --- a/core/modules/user/lib/Drupal/user/Tests/Views/HandlerArgumentUserUidTest.php +++ b/core/modules/user/lib/Drupal/user/Tests/Views/HandlerArgumentUserUidTest.php @@ -43,17 +43,6 @@ public function testArgumentTitle() { $this->executeView($view, array($account->id())); $this->assertEqual($view->getTitle(), $account->label()); $view->destroy(); - - // Tests the anonymous user. - $anonymous = $this->container->get('config.factory')->get('user.settings')->get('anonymous'); - $this->executeView($view, array(0)); - $this->assertEqual($view->getTitle(), $anonymous); - $view->destroy(); - - $view->getDisplay()->getHandler('argument', 'uid')->options['break_phrase'] = TRUE; - $this->executeView($view, array($account->id() . ',0')); - $this->assertEqual($view->getTitle(), $account->label() . ', ' . $anonymous); - $view->destroy(); } } diff --git a/core/modules/user/user.local_tasks.yml b/core/modules/user/user.local_tasks.yml index 91553d0..c418f0b 100644 --- a/core/modules/user/user.local_tasks.yml +++ b/core/modules/user/user.local_tasks.yml @@ -41,13 +41,3 @@ user.edit: route_name: user.edit tab_root_id: user.view title: Edit - -user.admin_account: - title: List - route_name: user.admin_account - tab_root_id: user.admin_account - -user.admin_permissions: - title: Permissions - route_name: user.admin_permissions - tab_root_id: user.admin_account diff --git a/core/modules/user/user.module b/core/modules/user/user.module index b582725..356822f 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -767,13 +767,16 @@ function user_menu() { 'position' => 'left', 'weight' => -4, ); - + $items['admin/people/list'] = array( + 'title' => 'List', + 'type' => MENU_DEFAULT_LOCAL_TASK, + ); // Permissions and role forms. $items['admin/people/permissions'] = array( 'title' => 'Permissions', 'description' => 'Determine access to features by selecting permissions for roles.', 'route_name' => 'user.admin_permissions', - 'type' => MENU_SIBLING_LOCAL_TASK, + 'type' => MENU_LOCAL_TASK, ); $items['admin/people/roles/manage/%user_role'] = array( diff --git a/core/modules/user/user.views.inc b/core/modules/user/user.views.inc index 45a76d0..52d28eb 100644 --- a/core/modules/user/user.views.inc +++ b/core/modules/user/user.views.inc @@ -34,7 +34,6 @@ function user_views_data() { 'argument' => array( 'id' => 'user_uid', 'name field' => 'name', - 'empty field name' => \Drupal::config('user.settings')->get('anonymous'), ), 'filter' => array( 'title' => t('Name'), diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/Counter.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/Counter.php index daef361..50e47e2 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/field/Counter.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/Counter.php @@ -19,14 +19,6 @@ */ class Counter extends FieldPluginBase { - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - protected function defineOptions() { $options = parent::defineOptions(); $options['counter_start'] = array('default' => 1); diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/Custom.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/Custom.php index 7a779d3..d1a9dd6 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/field/Custom.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/Custom.php @@ -19,13 +19,6 @@ */ class Custom extends FieldPluginBase { - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - public function query() { // do nothing -- to override the parent query. } diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/field/Links.php b/core/modules/views/lib/Drupal/views/Plugin/views/field/Links.php index f466bc6..4543e98 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/field/Links.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/field/Links.php @@ -15,13 +15,6 @@ abstract class Links extends FieldPluginBase { /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - - /** * Overrides \Drupal\views\Plugin\views\field\FieldPluginBase::defineOptions(). */ public function defineOptions() { diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/sort/Random.php b/core/modules/views/lib/Drupal/views/Plugin/views/sort/Random.php index 8e1eca1..aa3fa8d 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/sort/Random.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/sort/Random.php @@ -16,13 +16,6 @@ */ class Random extends SortPluginBase { - /** - * {@inheritdoc} - */ - public function usesGroupBy() { - return FALSE; - } - public function query() { $this->query->addOrderBy('rand'); } diff --git a/core/modules/views/views.api.php b/core/modules/views/views.api.php index 52816e2..e78322e 100644 --- a/core/modules/views/views.api.php +++ b/core/modules/views/views.api.php @@ -295,15 +295,12 @@ function hook_views_data_alter(array &$data) { 'title' => t('Example field'), 'help' => t('Some example content that references a user'), 'handler' => 'hook_handlers_field_example_field', - 'field' => array( - 'id' => 'example_field', - ), ); // This example changes the handler of the node title field. // In this handler you could do stuff, like preview of the node when clicking // the node title. - $data['node']['title']['field']['id'] = 'node_title'; + $data['node']['title']['handler'] = 'modulename_handlers_field_node_title'; // This example adds a relationship to table {foo}, so that 'foo' views can // add this table using a relationship. Because we don't want to write over diff --git a/core/modules/xmlrpc/xmlrpc.server.inc b/core/modules/xmlrpc/xmlrpc.server.inc index 9a5d825..1d210e5 100644 --- a/core/modules/xmlrpc/xmlrpc.server.inc +++ b/core/modules/xmlrpc/xmlrpc.server.inc @@ -215,8 +215,7 @@ function xmlrpc_server_call($xmlrpc_server, $methodname, $args) { // If the method has a signature, validate the request against the signature if (is_array($signature)) { $ok = TRUE; - // Remove first element of $signature which is the unused 'return type'. - array_shift($signature); + $return_type = array_shift($signature); // Check the number of arguments if (count($args) != count($signature)) { return xmlrpc_error(-32602, t('Server error. Wrong number of method parameters.')); diff --git a/core/scripts/run-tests.sh b/core/scripts/run-tests.sh index ef51d8a..ff4d7cc 100755 --- a/core/scripts/run-tests.sh +++ b/core/scripts/run-tests.sh @@ -270,8 +270,6 @@ function simpletest_script_init($server_software) { $host = 'localhost'; $path = ''; - $port = '80'; - // Determine location of php command automatically, unless a command line argument is supplied. if (!empty($args['php'])) { $php = $args['php']; @@ -296,7 +294,6 @@ function simpletest_script_init($server_software) { $parsed_url = parse_url($args['url']); $host = $parsed_url['host'] . (isset($parsed_url['port']) ? ':' . $parsed_url['port'] : ''); $path = isset($parsed_url['path']) ? rtrim($parsed_url['path']) : ''; - $port = (isset($parsed_url['port']) ? $parsed_url['port'] : $port); if ($path == '/') { $path = ''; } @@ -310,7 +307,6 @@ function simpletest_script_init($server_software) { $_SERVER['HTTP_HOST'] = $host; $_SERVER['REMOTE_ADDR'] = '127.0.0.1'; $_SERVER['SERVER_ADDR'] = '127.0.0.1'; - $_SERVER['SERVER_PORT'] = $port; $_SERVER['SERVER_SOFTWARE'] = $server_software; $_SERVER['SERVER_NAME'] = 'localhost'; $_SERVER['REQUEST_URI'] = $path .'/';