diff --git a/core/core.services.yml b/core/core.services.yml index 4fab422..7d56112 100644 --- a/core/core.services.yml +++ b/core/core.services.yml @@ -410,6 +410,10 @@ services: arguments: ['@entity.manager'] tags: - { name: access_check } + access_check.theme: + class: Drupal\Core\Theme\ThemeAccessCheck + tags: + - { name: access_check } maintenance_mode_subscriber: class: Drupal\Core\EventSubscriber\MaintenanceModeSubscriber tags: diff --git a/core/includes/menu.inc b/core/includes/menu.inc index f289cbb..a6a0b9f 100644 --- a/core/includes/menu.inc +++ b/core/includes/menu.inc @@ -475,6 +475,7 @@ function menu_get_item($path = NULL, $router_item = NULL) { // occurs rarely, likely due to a race condition of multiple rebuilds. if (\Drupal::state()->get('menu_rebuild_needed') || !\Drupal::state()->get('menu.masks')) { menu_router_rebuild(); + \Drupal::service('router.builder')->rebuild(); } $original_map = arg(NULL, $path); @@ -1027,9 +1028,23 @@ function menu_item_route_access(Route $route, $href, &$map) { */ function menu_get_object($type = 'node', $position = 1, $path = NULL) { $router_item = menu_get_item($path); - if (isset($router_item['load_functions'][$position]) && !empty($router_item['map'][$position]) && $router_item['load_functions'][$position] == $type . '_load') { + if (empty($router_item['map'][$position])) { + return; + } + + if (isset($router_item['load_functions'][$position]) && $router_item['load_functions'][$position] == $type . '_load') { return $router_item['map'][$position]; } + + // Attempt to inspect the route object. + $request = \Drupal::request(); + if ($request->attributes->has(RouteObjectInterface::ROUTE_OBJECT)) { + $path = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)->getPath(); + $parts = explode('/', ltrim($path, '/')); + if (isset($parts[$position]) && $parts[$position] == '{' . $type . '}') { + return $router_item['map'][$position]; + } + } } /** diff --git a/core/includes/theme.inc b/core/includes/theme.inc index d583eb7..d382b39 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -70,15 +70,14 @@ * @return * Boolean TRUE if the theme is enabled or is the site administration theme; * FALSE otherwise. + * + * @deprecated Use \Drupal::service('access_check.theme')->checkAccess(). */ function drupal_theme_access($theme) { if (is_object($theme)) { - return !empty($theme->status); - } - else { - $themes = list_themes(); - return !empty($themes[$theme]->status); + $theme = $theme->name; } + return Drupal::service('access_check.theme')->checkAccess($theme); } /** diff --git a/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php b/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php index 28b80d4..f8a7e2b 100644 --- a/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php +++ b/core/lib/Drupal/Core/Entity/EntityConfirmFormBase.php @@ -57,6 +57,8 @@ public function getFormName() { public function buildForm(array $form, array &$form_state) { $form = parent::buildForm($form, $form_state); + $form['#title'] = $this->getQuestion(); + $form['#attributes']['class'][] = 'confirmation'; $form['description'] = array('#markup' => $this->getDescription()); $form[$this->getFormName()] = array('#type' => 'hidden', '#value' => 1); @@ -71,15 +73,6 @@ public function buildForm(array $form, array &$form_state) { /** * {@inheritdoc} */ - protected function init(array &$form_state) { - parent::init($form_state); - - drupal_set_title($this->getQuestion(), PASS_THROUGH); - } - - /** - * {@inheritdoc} - */ protected function actions(array $form, array &$form_state) { $actions = parent::actions($form, $form_state); $actions['submit']['#value'] = $this->getConfirmText(); diff --git a/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php b/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php index 0d60b72..d0bf4ef 100644 --- a/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php +++ b/core/lib/Drupal/Core/Entity/EntityNGConfirmFormBase.php @@ -56,6 +56,8 @@ public function getFormName() { public function buildForm(array $form, array &$form_state) { $form = parent::buildForm($form, $form_state); + $form['#title'] = $this->getQuestion(); + $form['#attributes']['class'][] = 'confirmation'; $form['description'] = array('#markup' => $this->getDescription()); $form[$this->getFormName()] = array('#type' => 'hidden', '#value' => 1); @@ -78,15 +80,6 @@ public function form(array $form, array &$form_state) { /** * {@inheritdoc} */ - protected function init(array &$form_state) { - parent::init($form_state); - - drupal_set_title($this->getQuestion(), PASS_THROUGH); - } - - /** - * {@inheritdoc} - */ protected function actions(array $form, array &$form_state) { $actions = parent::actions($form, $form_state); $actions['submit']['#value'] = $this->getConfirmText(); diff --git a/core/lib/Drupal/Core/Form/ConfirmFormBase.php b/core/lib/Drupal/Core/Form/ConfirmFormBase.php index ec0e5ce..a6930f4 100644 --- a/core/lib/Drupal/Core/Form/ConfirmFormBase.php +++ b/core/lib/Drupal/Core/Form/ConfirmFormBase.php @@ -44,7 +44,7 @@ public function getFormName() { * {@inheritdoc} */ public function buildForm(array $form, array &$form_state) { - drupal_set_title($this->getQuestion(), PASS_THROUGH); + $form['#title'] = $this->getQuestion(); $form['#attributes']['class'][] = 'confirmation'; $form['description'] = array('#markup' => $this->getDescription()); diff --git a/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php new file mode 100644 index 0000000..90e4a79 --- /dev/null +++ b/core/lib/Drupal/Core/Theme/ThemeAccessCheck.php @@ -0,0 +1,47 @@ +checkAccess($request->attributes->get('theme')) ? static::ALLOW : static::DENY; + } + + /** + * Checks access to a theme. + * + * @param string $theme + * The name of a theme. + * + * @return bool + * TRUE if the theme is enabled, FALSE otherwise. + */ + public function checkAccess($theme) { + $themes = list_themes(); + return !empty($themes[$theme]->status); + } + +} diff --git a/core/modules/aggregator/aggregator.module b/core/modules/aggregator/aggregator.module index 1534cb3..56f926f 100644 --- a/core/modules/aggregator/aggregator.module +++ b/core/modules/aggregator/aggregator.module @@ -142,13 +142,6 @@ function aggregator_menu() { 'title' => 'Categories', 'route_name' => 'aggregator.categories', ); - $items['aggregator/opml'] = array( - 'title' => 'OPML feed', - 'page callback' => 'aggregator_page_opml', - 'access arguments' => array('access news feeds'), - 'type' => MENU_CALLBACK, - 'file' => 'aggregator.pages.inc', - ); $items['aggregator/categories/%aggregator_category'] = array( 'title callback' => '_aggregator_category_title', 'title arguments' => array(2), diff --git a/core/modules/aggregator/aggregator.pages.inc b/core/modules/aggregator/aggregator.pages.inc index 57e2b5c..cd938e7 100644 --- a/core/modules/aggregator/aggregator.pages.inc +++ b/core/modules/aggregator/aggregator.pages.inc @@ -114,6 +114,8 @@ function template_preprocess_aggregator_item(&$variables) { * An OPML formatted string. * * @see aggregator_menu() + * + * @deprecated Use \Drupal\aggregator\Controller\AggregatorController::opmlPage() */ function aggregator_page_opml($cid = NULL) { if ($cid) { diff --git a/core/modules/aggregator/aggregator.routing.yml b/core/modules/aggregator/aggregator.routing.yml index fef5271..5c04ba6 100644 --- a/core/modules/aggregator/aggregator.routing.yml +++ b/core/modules/aggregator/aggregator.routing.yml @@ -137,3 +137,12 @@ aggregator.categorize_feed_form: _form: '\Drupal\aggregator\Form\CategorizeFeedForm' requirements: _permission: 'administer news feeds' + +aggregator.opml_page: + path: '/aggregator/opml/{cid}' + defaults: + _title: 'OPML feed' + _controller: '\Drupal\aggregator\Controller\AggregatorController::opmlPage' + cid: null + requirements: + _permission: 'access news feeds' diff --git a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php index 238693a..1e6826b 100644 --- a/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php +++ b/core/modules/aggregator/lib/Drupal/aggregator/Controller/AggregatorController.php @@ -346,4 +346,12 @@ public function sources() { return $build; } + /** + * @todo Remove aggregator_opml(). + */ + public function opmlPage($cid = NULL) { + module_load_include('pages.inc', 'aggregator'); + return aggregator_page_opml($cid); + } + } diff --git a/core/modules/block/block.admin.inc b/core/modules/block/block.admin.inc index 0f6ea1e..86c59a8 100644 --- a/core/modules/block/block.admin.inc +++ b/core/modules/block/block.admin.inc @@ -12,6 +12,8 @@ * Page callback: Attaches CSS for the block region demo. * * @see block_menu() + * + * @deprecated Use \Drupal\block\Controller\BlockController::demo() */ function block_admin_demo($theme = NULL) { return array( diff --git a/core/modules/block/block.module b/core/modules/block/block.module index 8d38c1c..bb7a898 100644 --- a/core/modules/block/block.module +++ b/core/modules/block/block.module @@ -136,14 +136,10 @@ function block_menu() { ); $items["admin/structure/block/demo/$key"] = array( 'title' => check_plain($theme->info['name']), - 'page callback' => 'block_admin_demo', - 'page arguments' => array($key), + 'route_name' => 'block.admin_demo', 'type' => MENU_CALLBACK, - 'access callback' => '_block_themes_access', - 'access arguments' => array($key), 'theme callback' => '_block_custom_theme', 'theme arguments' => array($key), - 'file' => 'block.admin.inc', ); } return $items; diff --git a/core/modules/block/block.routing.yml b/core/modules/block/block.routing.yml index bde1e0e..2a9da19 100644 --- a/core/modules/block/block.routing.yml +++ b/core/modules/block/block.routing.yml @@ -1,3 +1,13 @@ +block.admin_demo: + path: '/admin/structure/block/demo/{theme}' + defaults: + _content: '\Drupal\block\Controller\BlockAdminController::demo' + options: + _access_mode: 'ALL' + requirements: + _access_theme: 'TRUE' + _permission: 'administer blocks' + block.admin_block_delete: path: '/admin/structure/block/manage/{block}/delete' defaults: diff --git a/core/modules/block/block.services.yml b/core/modules/block/block.services.yml index 5f3dab9..c6704bc 100644 --- a/core/modules/block/block.services.yml +++ b/core/modules/block/block.services.yml @@ -13,7 +13,3 @@ services: class: Drupal\block\Routing\RouteSubscriber tags: - { name: event_subscriber} - block.theme_access_check: - class: Drupal\block\Access\BlockThemeAccessCheck - tags: - - { name: access_check} diff --git a/core/modules/block/lib/Drupal/block/Access/BlockThemeAccessCheck.php b/core/modules/block/lib/Drupal/block/Access/BlockThemeAccessCheck.php deleted file mode 100644 index 97b53d4..0000000 --- a/core/modules/block/lib/Drupal/block/Access/BlockThemeAccessCheck.php +++ /dev/null @@ -1,34 +0,0 @@ -attributes->get('theme'); - return (user_access('administer blocks') && drupal_theme_access($theme)) ? static::ALLOW : static::DENY; - } - -} diff --git a/core/modules/block/lib/Drupal/block/Controller/BlockAdminController.php b/core/modules/block/lib/Drupal/block/Controller/BlockAdminController.php new file mode 100644 index 0000000..41fd587 --- /dev/null +++ b/core/modules/block/lib/Drupal/block/Controller/BlockAdminController.php @@ -0,0 +1,26 @@ + $key, ), array( - '_block_themes_access' => 'TRUE', + '_access_theme' => 'TRUE', + '_permission' => 'administer blocks', + ), + array( + '_access_mode' => 'ALL', ) ); $collection->add("block.admin_display_$key", $route); diff --git a/core/modules/comment/comment.admin.inc b/core/modules/comment/comment.admin.inc index f732a57..6502873 100644 --- a/core/modules/comment/comment.admin.inc +++ b/core/modules/comment/comment.admin.inc @@ -16,6 +16,8 @@ * * @see comment_menu() * @see comment_multiple_delete_confirm() + * + * @deprecated Use \Drupal\comment\Controller\CommentController::adminPage() */ function comment_admin($type = 'new') { $request = \Drupal::request(); diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module index 64fe92b..cb62bea 100644 --- a/core/modules/comment/comment.module +++ b/core/modules/comment/comment.module @@ -185,10 +185,8 @@ function comment_menu() { $items['admin/content/comment'] = array( 'title' => 'Comments', 'description' => 'List and edit site comments and the comment approval queue.', - 'page callback' => 'comment_admin', - 'access arguments' => array('administer comments'), + 'route_name' => 'comment.admin', 'type' => MENU_LOCAL_TASK | MENU_NORMAL_ITEM, - 'file' => 'comment.admin.inc', ); // Tabs begin here. $items['admin/content/comment/new'] = array( @@ -198,8 +196,7 @@ function comment_menu() { $items['admin/content/comment/approval'] = array( 'title' => 'Unapproved comments', 'title callback' => 'comment_count_unpublished', - 'page arguments' => array('approval'), - 'access arguments' => array('administer comments'), + 'route_name' => 'comment.admin_approval', 'type' => MENU_LOCAL_TASK, ); $items['comment/%comment'] = array( diff --git a/core/modules/comment/comment.routing.yml b/core/modules/comment/comment.routing.yml index fb0a1c4..305d7b2 100644 --- a/core/modules/comment/comment.routing.yml +++ b/core/modules/comment/comment.routing.yml @@ -1,3 +1,21 @@ +comment.admin: + path: '/admin/content/comment' + defaults: + _title: 'Comments' + _content: '\Drupal\comment\Controller\CommentController::adminPage' + type: 'new' + requirements: + _permission: 'administer comments' + +comment.admin_approval: + path: '/admin/content/comment/approval' + defaults: + _title: 'Unapproved comments' + _content: '\Drupal\comment\Controller\CommentController::adminPage' + type: 'approval' + requirements: + _permission: 'administer comments' + comment.edit_page: path: '/comment/{comment}/edit' defaults: diff --git a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php index 48a23cd..137def5 100644 --- a/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php +++ b/core/modules/comment/lib/Drupal/comment/Controller/CommentController.php @@ -271,4 +271,12 @@ public function renderNewCommentsNodeLinks(Request $request) { return new JsonResponse($links); } + /** + * @todo Remove comment_admin(). + */ + public function adminPage($type) { + module_load_include('admin.inc', 'comment'); + return comment_admin($type); + } + } diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php index bec3930..c19ee80 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentInterfaceTest.php @@ -53,7 +53,7 @@ function testCommentInterface() { $this->assertTrue($this->commentExists($comment), 'Comment found.'); // Check comment display. - $this->drupalGet('node/' . $this->node->id() . '/' . $comment->id()); + $this->drupalGet('node/' . $this->node->id()); $this->assertText($subject_text, 'Individual comment subject found.'); $this->assertText($comment_text, 'Individual comment body found.'); diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php index 9a4dc17..ec26245 100644 --- a/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php +++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentNodeAccessTest.php @@ -68,7 +68,7 @@ function testThreadedCommentView() { $this->assertTrue($this->commentExists($comment), 'Comment found.'); // Check comment display. - $this->drupalGet('node/' . $this->node->id() . '/' . $comment->id()); + $this->drupalGet('node/' . $this->node->id()); $this->assertText($comment_subject, 'Individual comment subject found.'); $this->assertText($comment_text, 'Individual comment body found.'); diff --git a/core/modules/contact/contact.module b/core/modules/contact/contact.module index bcfe689..95058fc 100644 --- a/core/modules/contact/contact.module +++ b/core/modules/contact/contact.module @@ -80,31 +80,22 @@ function contact_menu() { $items['contact'] = array( 'title' => 'Contact', - 'page callback' => 'contact_site_page', - 'access arguments' => array('access site-wide contact form'), + 'route_name' => 'contact.site_page', 'menu_name' => 'footer', 'type' => MENU_SUGGESTED_ITEM, - 'file' => 'contact.pages.inc', ); $items['contact/%contact_category'] = array( 'title' => 'Contact category form', 'title callback' => 'entity_page_label', 'title arguments' => array(1), - 'page callback' => 'contact_site_page', - 'page arguments' => array(1), - 'access arguments' => array('access site-wide contact form'), + 'route_name' => 'contact.site_page_category', 'type' => MENU_VISIBLE_IN_BREADCRUMB, - 'file' => 'contact.pages.inc', ); $items['user/%user/contact'] = array( 'title' => 'Contact', - 'page callback' => 'contact_personal_page', - 'page arguments' => array(1), + 'route_name' => 'contact.personal_page', 'type' => MENU_LOCAL_TASK, - 'access callback' => '_contact_personal_tab_access', - 'access arguments' => array(1), 'weight' => 2, - 'file' => 'contact.pages.inc', ); return $items; } @@ -118,41 +109,7 @@ function contact_menu() { * @see contact_menu() */ function _contact_personal_tab_access(UserInterface $account) { - global $user; - - // Anonymous users cannot have contact forms. - if ($account->isAnonymous()) { - return FALSE; - } - - // Users may not contact themselves. - if ($user->id() == $account->id()) { - return FALSE; - } - - // User administrators should always have access to personal contact forms. - if (user_access('administer users')) { - return TRUE; - } - - // If requested user has been blocked, do not allow users to contact them. - if ($account->isBlocked()) { - return FALSE; - } - - // If the requested user has disabled their contact form, do not allow users - // to contact them. - $account_data = \Drupal::service('user.data')->get('contact', $account->id(), 'enabled'); - if (isset($account_data) && empty($account_data)) { - return FALSE; - } - // If the requested user did not save a preference yet, deny access if the - // configured default is disabled. - elseif (!\Drupal::config('contact.settings')->get('user_default_enabled')) { - return FALSE; - } - - return user_access('access user contact forms'); + return \Drupal::service('access_manager')->checkNamedRoute('contact.personal_page', array('user' => $account->id())); } /** diff --git a/core/modules/contact/contact.pages.inc b/core/modules/contact/contact.pages.inc index 5a8cea3..491bb30 100644 --- a/core/modules/contact/contact.pages.inc +++ b/core/modules/contact/contact.pages.inc @@ -21,6 +21,8 @@ * @see contact_menu() * @see contact_site_form_submit() * @ingroup forms + * + * @deprecated Use \Drupal\contact\Controller\ContactController::contactSitePage() */ function contact_site_page(Category $category = NULL) { // Check if flood control has been activated for sending e-mails. @@ -66,6 +68,8 @@ function contact_site_page(Category $category = NULL) { * @see contact_personal_form_submit() * * @ingroup forms + * + * @deprecated Use \Drupal\contact\Controller\ContactController::contactPersonalPage() */ function contact_personal_page($recipient) { global $user; diff --git a/core/modules/contact/contact.routing.yml b/core/modules/contact/contact.routing.yml index 1dc9773..bbfdfdc 100644 --- a/core/modules/contact/contact.routing.yml +++ b/core/modules/contact/contact.routing.yml @@ -26,3 +26,28 @@ contact.category_edit: _entity_form: contact_category.edit requirements: _entity_access: contact_category.update + +contact.site_page: + path: '/contact' + defaults: + _title: 'Contact' + _content: '\Drupal\contact\Controller\ContactPageController::contactSitePage' + contact_category: NULL + requirements: + _permission: 'access site-wide contact form' + +contact.site_page_category: + path: '/contact/{contact_category}' + defaults: + _title: 'Contact category form' + _content: '\Drupal\contact\Controller\ContactPageController::contactSitePage' + requirements: + _permission: 'access site-wide contact form' + +contact.personal_page: + path: '/user/{user}/contact' + defaults: + _title: 'Contact' + _content: '\Drupal\contact\Controller\ContactPageController::contactPersonalPage' + requirements: + _access_contact_personal_tab: 'TRUE' diff --git a/core/modules/contact/contact.services.yml b/core/modules/contact/contact.services.yml new file mode 100644 index 0000000..cccd1fd --- /dev/null +++ b/core/modules/contact/contact.services.yml @@ -0,0 +1,6 @@ +services: + access_check.contact_personal: + class: Drupal\contact\Access\ContactPageAccess + tags: + - { name: access_check } + arguments: ['@config.factory', '@user.data'] diff --git a/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php new file mode 100644 index 0000000..0bfee5c --- /dev/null +++ b/core/modules/contact/lib/Drupal/contact/Access/ContactPageAccess.php @@ -0,0 +1,98 @@ +configFactory = $config_factory; + $this->userData = $user_data; + } + + /** + * {@inheritdoc} + */ + public function appliesTo() { + return array('_access_contact_personal_tab'); + } + + /** + * {@inheritdoc} + */ + public function access(Route $route, Request $request) { + $contact_account = $request->attributes->get('user'); + // @todo revisit after https://drupal.org/node/2048223 + $user = \Drupal::currentUser(); + + // Anonymous users cannot have contact forms. + if ($contact_account->isAnonymous()) { + return static::DENY; + } + + // Users may not contact themselves. + if ($user->id() == $contact_account->id()) { + return static::DENY; + } + + // User administrators should always have access to personal contact forms. + if ($user->hasPermission('administer users')) { + return static::ALLOW; + } + + // If requested user has been blocked, do not allow users to contact them. + if ($contact_account->isBlocked()) { + return static::DENY; + } + + // If the requested user has disabled their contact form, do not allow users + // to contact them. + $account_data = $this->userData->get('contact', $contact_account->id(), 'enabled'); + if (isset($account_data) && empty($account_data)) { + return static::DENY; + } + // If the requested user did not save a preference yet, deny access if the + // configured default is disabled. + else if (!$this->configFactory->get('contact.settings')->get('user_default_enabled')) { + return static::DENY; + } + + return $user->hasPermission('access user contact forms') ? static::ALLOW : static::DENY; + } + +} diff --git a/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php b/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php new file mode 100644 index 0000000..0bdb407 --- /dev/null +++ b/core/modules/contact/lib/Drupal/contact/Controller/ContactPageController.php @@ -0,0 +1,34 @@ + 'Translate', - 'page callback' => 'content_translation_overview', - 'page arguments' => array($entity_position), + 'route_name' => "content_translation.translation_overview_$entity_type", 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, 'weight' => 2, @@ -169,25 +168,17 @@ function content_translation_menu() { $args = array($entity_position, $language_position, $language_position + 1); $items["$path/translations/add/%language/%language"] = array( 'title' => 'Add', - 'page callback' => 'content_translation_add_page', - 'page arguments' => $args, - 'access callback' => 'content_translation_add_access', - 'access arguments' => $args, - 'type' => MENU_LOCAL_TASK, + 'route_name' => "content_translation.translation_add_$entity_type", 'weight' => 1, - ) + $item; + ); // Edit translation callback. $args = array($entity_position, $language_position); $items["$path/translations/edit/%language"] = array( 'title' => 'Edit', - 'page callback' => 'content_translation_edit_page', - 'page arguments' => $args, - 'access callback' => 'content_translation_edit_access', - 'access arguments' => $args, - 'type' => MENU_LOCAL_TASK, + 'route_name' => "content_translation.translation_edit_$entity_type", 'weight' => 1, - ) + $item; + ); // Delete translation callback. $items["$path/translations/delete/%language"] = array( diff --git a/core/modules/content_translation/content_translation.pages.inc b/core/modules/content_translation/content_translation.pages.inc index a7ce4af..eb80f32 100644 --- a/core/modules/content_translation/content_translation.pages.inc +++ b/core/modules/content_translation/content_translation.pages.inc @@ -14,6 +14,8 @@ * * @param \Drupal\Core\Entity\EntityInterface $entity * The entity whose translation overview should be displayed. + * + * @deprecated Use \Drupal\content_translation\Controller\ContentTranslationController::overview() */ function content_translation_overview(EntityInterface $entity) { $controller = content_translation_controller($entity->entityType()); @@ -188,6 +190,8 @@ function _content_translation_get_switch_links($path) { * * @return array * A processed form array ready to be rendered. + * + * @deprecated Use \Drupal\content_translation\Controller\ContentTranslationController::add() */ function content_translation_add_page(EntityInterface $entity, Language $source = NULL, Language $target = NULL) { $source = !empty($source) ? $source : $entity->language(); @@ -215,6 +219,8 @@ function content_translation_add_page(EntityInterface $entity, Language $source * * @return array * A processed form array ready to be rendered. + * + * @deprecated Use \Drupal\content_translation\Controller\ContentTranslationController::edit() */ function content_translation_edit_page(EntityInterface $entity, Language $language = NULL) { $language = !empty($language) ? $language : language(Language::TYPE_CONTENT); diff --git a/core/modules/content_translation/content_translation.services.yml b/core/modules/content_translation/content_translation.services.yml index 678724d..e81c13d 100644 --- a/core/modules/content_translation/content_translation.services.yml +++ b/core/modules/content_translation/content_translation.services.yml @@ -2,3 +2,21 @@ services: content_translation.synchronizer: class: Drupal\content_translation\FieldTranslationSynchronizer arguments: ['@entity.manager'] + + content_translation.subscriber: + class: Drupal\content_translation\Routing\ContentTranslationRouteSubscriber + arguments: ['@plugin.manager.entity'] + tags: + - { name: event_subscriber } + + content_translation.overview_access: + class: Drupal\content_translation\Access\ContentTranslationOverviewAccess + arguments: ['@plugin.manager.entity'] + tags: + - { name: access_check } + + content_translation.manage_access: + class: Drupal\content_translation\Access\ContentTranslationManageAccessCheck + arguments: ['@plugin.manager.entity'] + tags: + - { name: access_check } diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php new file mode 100644 index 0000000..21eeea8 --- /dev/null +++ b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationManageAccessCheck.php @@ -0,0 +1,85 @@ +entityManager = $manager; + } + + /** + * {@inheritdoc} + */ + public function appliesTo() { + return array('_access_content_translation_manage'); + } + + /** + * {@inheritdoc} + */ + public function access(Route $route, Request $request) { + if ($entity = $request->attributes->get('entity')) { + $route_requirements = $route->getRequirements(); + $operation = $route_requirements['_access_content_translation_manage']; + $entity_type = $entity->entityType(); + $controller_class = $this->entityManager->getControllerClass($entity_type, 'translation'); + $controller = new $controller_class($entity_type, $entity->entityInfo()); + + // Load translation. + $translations = $entity->getTranslationLanguages(); + $languages = language_list(); + + if ($operation == 'create') { + $source = language_load($request->attributes->get('source')); + $target = language_load($request->attributes->get('target')); + $source = !empty($source) ? $source : $entity->language(); + $target = !empty($target) ? $target : language(Language::TYPE_CONTENT); + return ($source->id != $target->id + && isset($languages[$source->id]) + && isset($languages[$target->id]) + && !isset($translations[$target->id]) + && $controller->getTranslationAccess($entity, $operation)) + ? static::ALLOW : static::DENY; + } + elseif ($operation == 'update') { + $language = language_load($request->attributes->get('language')); + $language = !empty($language) ? $language : language(Language::TYPE_CONTENT); + return isset($languages[$language->id]) + && $language->id != $entity->getUntranslated()->language()->id + && isset($translations[$language->id]) + && $controller->getTranslationAccess($entity, $operation) + ? static::ALLOW : static::DENY; + } + } + return static::DENY; + } + +} diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php new file mode 100644 index 0000000..116e9c5 --- /dev/null +++ b/core/modules/content_translation/lib/Drupal/content_translation/Access/ContentTranslationOverviewAccess.php @@ -0,0 +1,75 @@ +entityManager = $manager; + } + + /** + * {@inheritdoc} + */ + public function appliesTo() { + return array('_access_content_translation_overview'); + } + + /** + * {@inheritdoc} + */ + public function access(Route $route, Request $request) { + if ($entity = $request->attributes->get('entity')) { + // Get entity base info. + $entity_type = $entity->entityType(); + $bundle = $entity->bundle(); + + // Get account details from request. + $account = \Drupal::currentUser(); + + // Get entity access callback. + $definitions = $this->entityManager->getDefinitions(); + $access_callback = $definitions[$entity_type]['translation']['content_translation']['access_callback']; + if (call_user_func($access_callback, $entity)) { + return static::ALLOW; + } + + // Check per entity permission. + $permission = "translate {$entity_type}"; + if ($definitions[$entity_type]['permission_granularity'] == 'bundle') { + $permission = "translate {$bundle} {$entity_type}"; + } + if ($account->hasPermission($permission)) { + return static::ALLOW; + } + } + + return static::DENY; + } +} diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php b/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php new file mode 100644 index 0000000..ec229e1 --- /dev/null +++ b/core/modules/content_translation/lib/Drupal/content_translation/Controller/ContentTranslationController.php @@ -0,0 +1,44 @@ +entityManager = $entityManager; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::DYNAMIC] = 'routes'; + return $events; + } + + /** + * Adds routes for entity translations. + */ + public function routes(RouteBuildEvent $event) { + $collection = $event->getRouteCollection(); + foreach ($this->entityManager->getDefinitions() as $entity_type => $entity_info) { + if ($entity_info['translatable'] && isset($entity_info['translation'])) { + $route = new Route( + '/' . str_replace($entity_info['menu_path_wildcard'], '{entity}', $entity_info['menu_base_path']) . "/translations", + array( + '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::overview', + '_title' => 'Translate', + 'account' => 'NULL', + ), + array( + '_access_content_translation_overview' => $entity_type, + '_permission' => 'translate any entity', + ), + array( + 'parameters' => array( + 'entity' => array( + 'type' => 'entity:' . $entity_type, + ), + ), + ) + ); + $collection->add("content_translation.translation_overview_$entity_type", $route); + + $route = new Route( + '/' . str_replace($entity_info['menu_path_wildcard'], '{entity}', $entity_info['menu_base_path']) . "/translations/add/{source}/{target}", + array( + '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::add', + 'source' => NULL, + 'target' => NULL, + '_title' => 'Add', + + ), + array( + '_permission' => 'translate any entity', + '_access_content_translation_manage' => 'create', + ), + array( + 'parameters' => array( + 'entity' => array( + 'type' => 'entity:' . $entity_type, + ), + ), + ) + ); + $collection->add("content_translation.translation_add_$entity_type", $route); + + $route = new Route( + '/' . str_replace($entity_info['menu_path_wildcard'], '{entity}', $entity_info['menu_base_path']) . "/translations/edit/{language}", + array( + '_content' => '\Drupal\content_translation\Controller\ContentTranslationController::edit', + 'language' => NULL, + '_title' => 'Edit', + ), + array( + '_permission' => 'translate any entity', + '_access_content_translation_manage' => 'update', + ), + array( + 'parameters' => array( + 'entity' => array( + 'type' => 'entity:' . $entity_type, + ), + ), + ) + ); + $collection->add("content_translation.translation_edit_$entity_type", $route); + } + } + } + +} diff --git a/core/modules/dblog/dblog.admin.inc b/core/modules/dblog/dblog.admin.inc index ec0e5e9..9a5ef3b 100644 --- a/core/modules/dblog/dblog.admin.inc +++ b/core/modules/dblog/dblog.admin.inc @@ -18,6 +18,10 @@ * A build array in the format expected by drupal_render(). * * @see dblog_menu() + * + * @deprecated Use \Drupal\dblog\Controller\DblogController::pageNotFound(), + * \Drupal\dblog\Controller\DblogController::accessDenied(), or + * \Drupal\dblog\Controller\DblogController::search() */ function dblog_top($type) { diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module index d14b6e2..3e6bf9d 100644 --- a/core/modules/dblog/dblog.module +++ b/core/modules/dblog/dblog.module @@ -49,18 +49,12 @@ function dblog_menu() { $items['admin/reports/page-not-found'] = array( 'title' => "Top 'page not found' errors", 'description' => "View 'page not found' errors (404s).", - 'page callback' => 'dblog_top', - 'page arguments' => array('page not found'), - 'access arguments' => array('access site reports'), - 'file' => 'dblog.admin.inc', + 'route_name' => 'dblog.page_not_found', ); $items['admin/reports/access-denied'] = array( 'title' => "Top 'access denied' errors", 'description' => "View 'access denied' errors (403s).", - 'page callback' => 'dblog_top', - 'page arguments' => array('access denied'), - 'access arguments' => array('access site reports'), - 'file' => 'dblog.admin.inc', + 'route_name' => 'dblog.access_denied', ); $items['admin/reports/event/%'] = array( 'title' => 'Details', @@ -71,10 +65,7 @@ function dblog_menu() { $items['admin/reports/search'] = array( 'title' => 'Top search phrases', 'description' => 'View most popular search phrases.', - 'page callback' => 'dblog_top', - 'page arguments' => array('search'), - 'access arguments' => array('access site reports'), - 'file' => 'dblog.admin.inc', + 'route_name' => 'dblog.search', ); } diff --git a/core/modules/dblog/dblog.routing.yml b/core/modules/dblog/dblog.routing.yml index d0de09b..31f1b1c 100644 --- a/core/modules/dblog/dblog.routing.yml +++ b/core/modules/dblog/dblog.routing.yml @@ -11,3 +11,19 @@ dblog.event: _content: '\Drupal\dblog\Controller\DbLogController::eventDetails' requirements: _permission: 'access site reports' + +dblog.page_not_found: + path: '/admin/reports/page-not-found' + defaults: + _title: "Top 'page not found' errors" + _content: '\Drupal\dblog\Controller\DbLogController::pageNotFound' + requirements: + _permission: 'access site reports' + +dblog.access_denied: + path: '/admin/reports/access-denied' + defaults: + _title: "Top 'access denied' errors" + _content: '\Drupal\dblog\Controller\DbLogController::accessDenied' + requirements: + _permission: 'access site reports' diff --git a/core/modules/dblog/dblog.services.yml b/core/modules/dblog/dblog.services.yml new file mode 100644 index 0000000..815734c --- /dev/null +++ b/core/modules/dblog/dblog.services.yml @@ -0,0 +1,6 @@ +services: + dblog.route_subscriber: + class: Drupal\dblog\Routing\RouteSubscriber + arguments: ['@module_handler'] + tags: + - { name: event_subscriber} diff --git a/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php b/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php index 9dc63f0..795f689 100644 --- a/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php +++ b/core/modules/dblog/lib/Drupal/dblog/Controller/DbLogController.php @@ -319,4 +319,28 @@ protected function buildFilterQuery() { ); } + /** + * @todo Remove dblog_top(). + */ + public function pageNotFound() { + module_load_include('admin.inc', 'dblog'); + return dblog_top('page not found'); + } + + /** + * @todo Remove dblog_top(). + */ + public function accessDenied() { + module_load_include('admin.inc', 'dblog'); + return dblog_top('access denied'); + } + + /** + * @todo Remove dblog_top(). + */ + public function search() { + module_load_include('admin.inc', 'dblog'); + return dblog_top('search'); + } + } diff --git a/core/modules/dblog/lib/Drupal/dblog/Routing/RouteSubscriber.php b/core/modules/dblog/lib/Drupal/dblog/Routing/RouteSubscriber.php new file mode 100644 index 0000000..f04492e --- /dev/null +++ b/core/modules/dblog/lib/Drupal/dblog/Routing/RouteSubscriber.php @@ -0,0 +1,73 @@ +moduleHandler = $module_handler; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::DYNAMIC] = 'routes'; + return $events; + } + + /** + * Generate dynamic routes for various dblog pages. + * + * @param \Drupal\Core\Routing\RouteBuildEvent $event + * The route building event. + * + * @return \Symfony\Component\Routing\RouteCollection + * The route collection that contains the new dynamic route. + */ + public function routes(RouteBuildEvent $event) { + $collection = $event->getRouteCollection(); + if ($this->moduleHandler->moduleExists('search')) { + // The block entity listing page. + $route = new Route( + 'admin/reports/search', + array( + '_content' => '\Drupal\dblog\Controller\DbLogController::search', + '_title' => 'Top search phrases', + ), + array( + '_permission' => 'access site reports', + ) + ); + $collection->add('dblog.search', $route); + } + } + +} diff --git a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php index 2ccef59..735cd95 100644 --- a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php +++ b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php @@ -155,8 +155,6 @@ private function generateLogEntries($count, $type = 'custom', $severity = WATCHD * (optional) HTTP response code. Defaults to 200. */ private function verifyReports($response = 200) { - $quote = '''; - // View the database log help page. $this->drupalGet('admin/help/dblog'); $this->assertResponse($response); @@ -175,14 +173,14 @@ private function verifyReports($response = 200) { $this->drupalGet('admin/reports/page-not-found'); $this->assertResponse($response); if ($response == 200) { - $this->assertText(t('Top ' . $quote . 'page not found' . $quote . ' errors'), 'DBLog page-not-found report was displayed'); + $this->assertText("Top 'page not found' errors", 'DBLog page-not-found report was displayed'); } // View the database log access-denied report page. $this->drupalGet('admin/reports/access-denied'); $this->assertResponse($response); if ($response == 200) { - $this->assertText(t('Top ' . $quote . 'access denied' . $quote . ' errors'), 'DBLog access-denied report was displayed'); + $this->assertText("Top 'access denied' errors", 'DBLog access-denied report was displayed'); } // View the database log event page. diff --git a/core/modules/forum/forum.module b/core/modules/forum/forum.module index 0fe30f6..f7bf99a 100644 --- a/core/modules/forum/forum.module +++ b/core/modules/forum/forum.module @@ -548,7 +548,7 @@ function forum_form_node_form_alter(&$form, &$form_state, $form_id) { // If there is no default forum already selected, try to get the forum // ID from the URL (e.g., if we are on a page like node/add/forum/2, we // expect "2" to be the ID of the forum that was requested). - $requested_forum_id = arg(3); + $requested_forum_id = Drupal::request()->query->get('forum_id'); $widget['#default_value'] = is_numeric($requested_forum_id) ? $requested_forum_id : ''; } } diff --git a/core/modules/forum/lib/Drupal/forum/ForumBreadcrumbBuilder.php b/core/modules/forum/lib/Drupal/forum/ForumBreadcrumbBuilder.php index d28dc33..2223041 100644 --- a/core/modules/forum/lib/Drupal/forum/ForumBreadcrumbBuilder.php +++ b/core/modules/forum/lib/Drupal/forum/ForumBreadcrumbBuilder.php @@ -59,23 +59,16 @@ public function __construct(EntityManager $entity_manager, ConfigFactory $config * {@inheritdoc} */ public function build(array $attributes) { - // @todo This only works for legacy routes. Once node/% and forum/% are - // converted to the new router this code will need to be updated. - if (isset($attributes['_drupal_menu_item']) && ($item = $attributes['_drupal_menu_item']) && $item['path'] == 'node/%') { - $node = $item['map'][1]; - // Load the object in case of missing wildcard loaders. - $node = is_object($node) ? $node : node_load($node); - if ($this->forumManager->checkNodeType($node)) { - $breadcrumb = $this->forumPostBreadcrumb($node); + if (!empty($attributes[RouteObjectInterface::ROUTE_NAME])) { + $route_name = $attributes[RouteObjectInterface::ROUTE_NAME]; + if ($route_name == 'node.view' && isset($attributes['node'])) { + if ($this->forumManager->checkNodeType($attributes['node'])) { + return $this->forumPostBreadcrumb($attributes['node']); + } + } + if ($route_name == 'forum.page' && isset($attributes['taxonomy_term'])) { + return $this->forumTermBreadcrumb($attributes['taxonomy_term']); } - } - - if (!empty($attributes[RouteObjectInterface::ROUTE_NAME]) && $attributes[RouteObjectInterface::ROUTE_NAME] == 'forum.page' && isset($attributes['taxonomy_term'])) { - $breadcrumb = $this->forumTermBreadcrumb($attributes['taxonomy_term']); - } - - if (!empty($breadcrumb)) { - return $breadcrumb; } } diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php index cc9ff6a..47495e4 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumBlockTest.php @@ -177,7 +177,7 @@ protected function createForumTopics($count = 5) { ); // Create the forum topic, preselecting the forum ID via a URL parameter. - $this->drupalPostForm('node/add/forum/1', $edit, t('Save and publish')); + $this->drupalPostForm('node/add/forum', $edit, t('Save and publish'), array('query' => array('forum_id' => 1))); $topics[] = $title; } diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php index 6003194..c50fe43 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumIndexTest.php @@ -52,7 +52,7 @@ function testForumIndexStatus() { ); // Create the forum topic, preselecting the forum ID via a URL parameter. - $this->drupalPostForm('node/add/forum/' . $tid, $edit, t('Save and publish')); + $this->drupalPostForm('node/add/forum', $edit, t('Save and publish'), array('query' => array('forum_id' => $tid))); // Check that the node exists in the database. $node = $this->drupalGetNodeByTitle($title); diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php index 5101ddc..489cc1b 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumNodeAccessTest.php @@ -56,7 +56,7 @@ function testForumNodeAccess() { 'body[0][value]' => $this->randomName(200), 'private' => TRUE, ); - $this->drupalPostForm('node/add/forum/1', $edit, t('Save')); + $this->drupalPostForm('node/add/forum', $edit, t('Save'), array('query' => array('forum_id' => 1))); $private_node = $this->drupalGetNodeByTitle($private_node_title); $this->assertTrue(!empty($private_node), 'New private forum node found in database.'); @@ -66,7 +66,7 @@ function testForumNodeAccess() { 'title' => $public_node_title, 'body[0][value]' => $this->randomName(200), ); - $this->drupalPostForm('node/add/forum/1', $edit, t('Save')); + $this->drupalPostForm('node/add/forum', $edit, t('Save'), array('query' => array('forum_id' => 1))); $public_node = $this->drupalGetNodeByTitle($public_node_title); $this->assertTrue(!empty($public_node), 'New public forum node found in database.'); diff --git a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php index 26b4dc6..97c9752 100644 --- a/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php +++ b/core/modules/forum/lib/Drupal/forum/Tests/ForumTest.php @@ -511,7 +511,7 @@ function createForumTopic($forum, $container = FALSE) { $tid = $forum['tid']; // Create the forum topic, preselecting the forum ID via a URL parameter. - $this->drupalPostForm('node/add/forum/' . $tid, $edit, t('Save')); + $this->drupalPostForm('node/add/forum', $edit, t('Save'), array('query' => array('forum_id' => $tid))); $type = t('Forum topic'); if ($container) { diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc index 562580b..c3f669c 100644 --- a/core/modules/language/language.admin.inc +++ b/core/modules/language/language.admin.inc @@ -336,6 +336,8 @@ function theme_language_negotiation_configure_browser_form_table($variables) { /** * Returns the content language settings form. + * + * @deprecated Use \Drupal\language\Controller\LanguageController::contentSettings() */ function language_content_settings_page() { return drupal_get_form('language_content_settings_form', language_entity_supported()); diff --git a/core/modules/language/language.module b/core/modules/language/language.module index ae3e030..772cdd1 100644 --- a/core/modules/language/language.module +++ b/core/modules/language/language.module @@ -121,9 +121,7 @@ function language_menu() { $items['admin/config/regional/content-language'] = array( 'title' => 'Content language settings', 'description' => 'Configure content language support for any multilingual element.', - 'page callback' => 'language_content_settings_page', - 'access arguments' => array('administer languages'), - 'file' => 'language.admin.inc', + 'route_name' => 'language.content_settings_page', ); return $items; diff --git a/core/modules/language/language.routing.yml b/core/modules/language/language.routing.yml index ae980ec..7494f1e 100644 --- a/core/modules/language/language.routing.yml +++ b/core/modules/language/language.routing.yml @@ -61,3 +61,11 @@ language.negotiation_browser_delete: _form: '\Drupal\language\Form\NegotiationBrowserDeleteForm' requirements: _permission: 'administer languages' + +language.content_settings_page: + path: '/admin/config/regional/content-language' + defaults: + _title: 'Content language settings' + _content: '\Drupal\language\Controller\LanguageController::contentSettings' + requirements: + _permission: 'administer languages' diff --git a/core/modules/language/lib/Drupal/language/Controller/LanguageController.php b/core/modules/language/lib/Drupal/language/Controller/LanguageController.php new file mode 100644 index 0000000..0724471 --- /dev/null +++ b/core/modules/language/lib/Drupal/language/Controller/LanguageController.php @@ -0,0 +1,23 @@ +entityManager->getAccessController('node'); + // If a node type is set on the request, just check that. + if ($request->attributes->has('node_type')) { + return $access_controller->createAccess($request->attributes->get('node_type')->type) ? static::ALLOW : static::DENY; + } + foreach (node_permissions_get_configured_types() as $type) { + if ($access_controller->createAccess($type->type)) { + // Allow access if at least one type is permitted. + return static::ALLOW; + } + } + return static::DENY; + } + +} diff --git a/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php b/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php index aca491d..c44e1f6 100644 --- a/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php +++ b/core/modules/node/lib/Drupal/node/Access/NodeRevisionAccessCheck.php @@ -73,8 +73,18 @@ public function applies(Route $route) { * {@inheritdoc} */ public function access(Route $route, Request $request) { - $revision = $this->nodeStorage->loadRevision($request->attributes->get('node_revision')); - return $this->checkAccess($revision, $route->getRequirement('_access_node_revision')) ? static::ALLOW : static::DENY; + // If the route has a {node_revision} placeholder, load the node for that + // revision. Otherwise, try to use a {node} placeholder. + if ($request->attributes->has('node_revision')) { + $node = $this->nodeStorage->loadRevision($request->attributes->get('node_revision')); + } + elseif ($request->attributes->has('node')) { + $node = $request->attributes->get('node'); + } + else { + return static::DENY; + } + return $this->checkAccess($node, $route->getRequirement('_access_node_revision')) ? static::ALLOW : static::DENY; } /** diff --git a/core/modules/node/lib/Drupal/node/Controller/NodeController.php b/core/modules/node/lib/Drupal/node/Controller/NodeController.php new file mode 100644 index 0000000..5b4d286 --- /dev/null +++ b/core/modules/node/lib/Drupal/node/Controller/NodeController.php @@ -0,0 +1,59 @@ + $node->label(), '%date' => format_date($node->getRevisionCreationTime()))), PASS_THROUGH); - } - // For markup consistency with other pages, use node_view_multiple() rather than node_view(). $page = array('nodes' => node_view_multiple(array($node->id() => $node), 'full')); + if ($message) { + $page['#title'] = t('Revision of %title from %date', array('%title' => $node->label(), '%date' => format_date($node->getRevisionCreationTime()))); + } + // Update the history table, stating that this user viewed this node. global $user; if (\Drupal::moduleHandler()->moduleExists('history') && $user->isAuthenticated()) { @@ -941,21 +944,12 @@ function _node_revision_access(EntityInterface $node, $op = 'view', $account = N * TRUE if the user has add permission, otherwise FALSE. * * @see node_menu() + * + * @deprecated + * Use \Drupal::service('access_manager')->checkNamedRoute('node.add_page'); */ function _node_add_access() { - $types = node_type_get_types(); - foreach ($types as $type) { - if (node_access('create', $type->type)) { - return TRUE; - } - } - if (user_access('administer content types')) { - // There are no content types defined that the user has permission to create, - // but the user does have the permission to administer the content types, so - // grant them access to the page anyway. - return TRUE; - } - return FALSE; + return \Drupal::service('access_manager')->checkNamedRoute('node.add_page'); } /** @@ -1001,30 +995,21 @@ function node_menu() { ); $items['node/add'] = array( 'title' => 'Add content', - 'page callback' => 'node_add_page', - 'access callback' => '_node_add_access', - 'file' => 'node.pages.inc', + 'route_name' => 'node.add_page', ); $items['node/add/%node_type'] = array( 'title callback' => 'entity_page_label', 'title arguments' => array(2), - 'page callback' => 'node_add', - 'page arguments' => array(2), - 'access callback' => 'node_access', - 'access arguments' => array('create', 2), 'description callback' => 'node_type_get_description', 'description arguments' => array(2), - 'file' => 'node.pages.inc', + 'route_name' => 'node.add', ); $items['node/%node'] = array( 'title callback' => 'node_page_title', 'title arguments' => array(1), - // The page callback also invokes drupal_set_title() in case - // the menu router's title is overridden by a menu link. - 'page callback' => 'node_page_view', - 'page arguments' => array(1), - 'access callback' => 'node_access', - 'access arguments' => array('view', 1), + // The controller also sets the #title in case the routes' title is + // overridden by a menu link. + 'route_name' => 'node.view', ); $items['node/%node/view'] = array( 'title' => 'View', @@ -1045,20 +1030,13 @@ function node_menu() { ); $items['node/%node/revisions'] = array( 'title' => 'Revisions', - 'page callback' => 'node_revision_overview', - 'page arguments' => array(1), - 'access callback' => '_node_revision_access', - 'access arguments' => array(1), + 'route_name' => 'node.revision_overview', 'weight' => 20, 'type' => MENU_LOCAL_TASK, - 'file' => 'node.pages.inc', ); $items['node/%node/revisions/%node_revision/view'] = array( 'title' => 'Revisions', - 'page callback' => 'node_show', - 'page arguments' => array(3, TRUE), - 'access callback' => '_node_revision_access', - 'access arguments' => array(3), + 'route_name' => 'node.revision_show', ); $items['node/%node/revisions/%node_revision/revert'] = array( 'title' => 'Revert to earlier revision', @@ -1501,13 +1479,10 @@ function node_view_multiple($nodes, $view_mode = 'teaser', $langcode = NULL) { * A page array suitable for use by drupal_render(). * * @see node_menu() + * + * @deprecated Use \Drupal\node\Controller\NodeController::viewPage() */ function node_page_view(EntityInterface $node) { - // If there is a menu link to this node, the link becomes the last part - // of the active trail, and the link name becomes the page title. - // Thus, we must explicitly set the page title to be the node title. - drupal_set_title($node->label()); - foreach ($node->uriRelationships() as $rel) { $uri = $node->uri($rel); // Set the node path as the canonical URL to prevent duplicate content. @@ -1519,7 +1494,13 @@ function node_page_view(EntityInterface $node) { } } - return node_show($node); + $build = node_show($node); + + // If there is a menu link to this node, the link becomes the last part + // of the active trail, and the link name becomes the page title. + // Thus, we must explicitly set the page title to be the node title. + $build['#title'] = String::checkPlain($node->label()); + return $build; } /** diff --git a/core/modules/node/node.pages.inc b/core/modules/node/node.pages.inc index 1b6a1e5..8518383 100644 --- a/core/modules/node/node.pages.inc +++ b/core/modules/node/node.pages.inc @@ -24,6 +24,8 @@ * to the node add page for that one node type and does not return at all. * * @see node_menu() + * + * @deprecated Use \Drupal\node\Controller\NodeController::addPage() */ function node_add_page() { $content = array(); @@ -80,6 +82,8 @@ function theme_node_add_list($variables) { * A node submission form. * * @see node_menu() + * + * @deprecated Use \Drupal\node\Controller\NodeController::add() */ function node_add($node_type) { global $user; @@ -175,6 +179,8 @@ function theme_node_preview($variables) { * An array as expected by drupal_render(). * * @see node_menu() + * + * @deprecated Use \Drupal\node\Controller\NodeController::revisionOverview() */ function node_revision_overview($node) { drupal_set_title(t('Revisions for %title', array('%title' => $node->label())), PASS_THROUGH); diff --git a/core/modules/node/node.routing.yml b/core/modules/node/node.routing.yml index afa2c1c..c2a4ff1 100644 --- a/core/modules/node/node.routing.yml +++ b/core/modules/node/node.routing.yml @@ -12,6 +12,29 @@ node.page_edit: requirements: _entity_access: 'node.update' +node.add_page: + path: '/node/add' + defaults: + _title: 'Add page' + _content: '\Drupal\node\Controller\NodeController::addPage' + requirements: + _permission: 'administer content types' + _node_add_access: 'node' + +node.add: + path: '/node/add/{node_type}' + defaults: + _content: '\Drupal\node\Controller\NodeController::add' + requirements: + _node_add_access: 'node:{node_type}' + +node.view: + path: '/node/{node}' + defaults: + _content: '\Drupal\node\Controller\NodeController::viewPage' + requirements: + _entity_access: 'node.view' + node.delete_confirm: path: '/node/{node}/delete' defaults: @@ -19,6 +42,22 @@ node.delete_confirm: requirements: _entity_access: 'node.delete' +node.revision_overview: + path: '/node/{node}/revisions' + defaults: + _title: 'Revisions' + _content: '\Drupal\node\Controller\NodeController::revisionOverview' + requirements: + _access_node_revision: 'view' + +node.revision_show: + path: '/node/{node}/revisions/{node_revision}/view' + defaults: + _title: 'Revisions' + _content: '\Drupal\node\Controller\NodeController::revisionShow' + requirements: + _access_node_revision: 'view' + node.revision_revert_confirm: path: '/node/{node}/revisions/{node_revision}/revert' defaults: diff --git a/core/modules/node/node.services.yml b/core/modules/node/node.services.yml index bf4c4ee..0b839a5 100644 --- a/core/modules/node/node.services.yml +++ b/core/modules/node/node.services.yml @@ -7,3 +7,8 @@ services: arguments: ['@entity.manager', '@database'] tags: - { name: access_check } + access_check.node.add: + class: Drupal\node\Access\NodeAddAccessCheck + arguments: ['@plugin.manager.entity'] + tags: + - { name: access_check } diff --git a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php index 893030e..2b70634 100644 --- a/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php +++ b/core/modules/options/lib/Drupal/options/Tests/OptionsFieldUnitTestBase.php @@ -55,7 +55,7 @@ class OptionsFieldUnitTestBase extends FieldUnitTestBase { */ public function setUp() { parent::setUp(); - $this->installSchema('system', 'menu_router'); + $this->installSchema('system', array('router', 'menu_router')); $this->fieldDefinition = array( 'name' => $this->fieldName, diff --git a/core/modules/path/lib/Drupal/path/Controller/PathController.php b/core/modules/path/lib/Drupal/path/Controller/PathController.php new file mode 100644 index 0000000..a8fae4a --- /dev/null +++ b/core/modules/path/lib/Drupal/path/Controller/PathController.php @@ -0,0 +1,40 @@ + 'URL aliases', 'description' => "Change your site's URL paths by aliasing them.", - 'page callback' => 'path_admin_overview', - 'access arguments' => array('administer url aliases'), + 'route_name' => 'path.admin_overview', 'weight' => -5, - 'file' => 'path.admin.inc', ); $items['admin/config/search/path/list'] = array( 'title' => 'List', @@ -69,10 +67,7 @@ function path_menu() { ); $items['admin/config/search/path/edit/%path'] = array( 'title' => 'Edit alias', - 'page callback' => 'path_admin_edit', - 'page arguments' => array(5), - 'access arguments' => array('administer url aliases'), - 'file' => 'path.admin.inc', + 'route_name' => 'path.admin_edit', ); $items['admin/config/search/path/delete/%path'] = array( 'title' => 'Delete alias', @@ -80,10 +75,8 @@ function path_menu() { ); $items['admin/config/search/path/add'] = array( 'title' => 'Add alias', - 'page callback' => 'path_admin_edit', - 'access arguments' => array('administer url aliases'), + 'route_name' => 'path.admin_add', 'type' => MENU_LOCAL_ACTION, - 'file' => 'path.admin.inc', ); return $items; diff --git a/core/modules/path/path.routing.yml b/core/modules/path/path.routing.yml index 1dd8193..969ab53 100644 --- a/core/modules/path/path.routing.yml +++ b/core/modules/path/path.routing.yml @@ -4,3 +4,28 @@ path.delete: _form: '\Drupal\path\Form\DeleteForm' requirements: _permission: 'administer url aliases' + +path.admin_overview: + path: '/admin/config/search/path/{keys}' + defaults: + _title: 'URL aliases' + _content: '\Drupal\path\Controller\PathController::adminOverview' + keys: NULL + requirements: + _permission: 'administer url aliases' + +path.admin_add: + path: '/admin/config/search/path/add' + defaults: + _title: 'Add alias' + _content: '\Drupal\path\Controller\PathController::adminAdd' + requirements: + _permission: 'administer url aliases' + +path.admin_edit: + path: '/admin/config/search/path/edit/{path}' + defaults: + _title: 'Edit alias' + _content: '\Drupal\path\Controller\PathController::adminEdit' + requirements: + _permission: 'administer url aliases' diff --git a/core/modules/search/lib/Drupal/search/Access/SearchAccessCheck.php b/core/modules/search/lib/Drupal/search/Access/SearchAccessCheck.php new file mode 100644 index 0000000..fb9a74e --- /dev/null +++ b/core/modules/search/lib/Drupal/search/Access/SearchAccessCheck.php @@ -0,0 +1,51 @@ +searchManager = $search_plugin_manager; + } + + /** + * {@inheritdoc} + */ + public function appliesTo() { + return array('_search_access'); + } + + /** + * {@inheritdoc} + */ + public function access(Route $route, Request $request) { + return $this->searchManager->getActiveDefinitions() ? static::ALLOW : static::DENY; + } + +} diff --git a/core/modules/search/lib/Drupal/search/Access/SearchPluginAccessCheck.php b/core/modules/search/lib/Drupal/search/Access/SearchPluginAccessCheck.php new file mode 100644 index 0000000..af4b1df --- /dev/null +++ b/core/modules/search/lib/Drupal/search/Access/SearchPluginAccessCheck.php @@ -0,0 +1,34 @@ +getRequirement('_search_plugin_view_access'); + return $this->searchManager->pluginAccess($plugin_id, $account) ? static::ALLOW : static::DENY; + } + +} diff --git a/core/modules/search/lib/Drupal/search/Controller/SearchController.php b/core/modules/search/lib/Drupal/search/Controller/SearchController.php new file mode 100644 index 0000000..8622341 --- /dev/null +++ b/core/modules/search/lib/Drupal/search/Controller/SearchController.php @@ -0,0 +1,31 @@ +searchManager = $search_plugin_manager; + } + + /** + * {@inheritdoc} + */ + public static function getSubscribedEvents() { + $events[RoutingEvents::DYNAMIC] = 'routes'; + return $events; + } + + /** + * Adds routes for search. + * + * @param \Drupal\Core\Routing\RouteBuildEvent $event + * The route building event. + */ + public function routes(RouteBuildEvent $event) { + $collection = $event->getRouteCollection(); + + foreach ($this->searchManager->getActiveDefinitions() as $plugin_id => $search_info) { + $path = 'search/' . $search_info['path'] . '/{keys}'; + $defaults = array( + '_content' => 'Drupal\search\Controller\SearchController::searchViewPlugin', + 'plugin_id' => $plugin_id, + 'keys' => '', + ); + $requirements = array( + 'keys' => '.+', + '_search_plugin_view_access' => $plugin_id, + '_permission' => 'search content', + ); + $options = array( + '_access_mode' => 'ALL', + ); + $route = new Route($path, $defaults, $requirements, $options); + $collection->add('search.view_' . $plugin_id, $route); + } + } + +} diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchKeywordsConditionsTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchKeywordsConditionsTest.php index a17c1c6..15ae685 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchKeywordsConditionsTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchKeywordsConditionsTest.php @@ -36,7 +36,7 @@ function setUp() { $this->drupalLogin($this->searching_user); // Test with all search modules enabled. \Drupal::config('search.settings')->set('active_plugins', array('node_search', 'user_search', 'search_extra_type_search'))->save(); - menu_router_rebuild(); + \Drupal::state()->set('menu_rebuild_needed', TRUE); } /** diff --git a/core/modules/search/lib/Drupal/search/Tests/SearchPageOverrideTest.php b/core/modules/search/lib/Drupal/search/Tests/SearchPageOverrideTest.php index b8ead26..ab3f913 100644 --- a/core/modules/search/lib/Drupal/search/Tests/SearchPageOverrideTest.php +++ b/core/modules/search/lib/Drupal/search/Tests/SearchPageOverrideTest.php @@ -38,7 +38,7 @@ function setUp() { // Enable the extra type module for searching. \Drupal::config('search.settings')->set('active_plugins', array('node_search', 'user_search', 'search_extra_type_search'))->save(); - menu_router_rebuild(); + \Drupal::state()->set('menu_rebuild_needed', TRUE); } function testSearchPageHook() { diff --git a/core/modules/search/search.module b/core/modules/search/search.module index 330e9a7..8b6817f 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -152,11 +152,8 @@ function search_preprocess_block(&$variables) { function search_menu() { $items['search'] = array( 'title' => 'Search', - 'page callback' => 'search_view', - 'page arguments' => array(NULL, '', ''), - 'access callback' => 'search_is_active', 'type' => MENU_SUGGESTED_ITEM, - 'file' => 'search.pages.inc', + 'route_name' => 'search.view', ); $items['admin/config/search/settings'] = array( 'title' => 'Search settings', @@ -183,46 +180,16 @@ function search_menu() { $path = 'search/' . $search_info['path']; $items[$path] = array( 'title' => $search_info['title'], - 'page callback' => 'search_view', - 'page arguments' => array($plugin_id, ''), - 'access callback' => '_search_menu_access', - 'access arguments' => array($plugin_id), + 'route_name' => 'search.view_' . $plugin_id, 'type' => MENU_LOCAL_TASK, - 'file' => 'search.pages.inc', 'weight' => $plugin_id == $default_info['id'] ? -10 : 0, ); - $items["$path/%menu_tail"] = array( - 'title' => $search_info['title'], - 'load arguments' => array('%map', '%index'), - 'page callback' => 'search_view', - 'page arguments' => array($plugin_id, 2), - 'access callback' => '_search_menu_access', - 'access arguments' => array($plugin_id), - // The default local task points to its parent, but this item points to - // where it should so it should not be changed. - 'type' => MENU_LOCAL_TASK, - 'file' => 'search.pages.inc', - 'weight' => 0, - // These tabs are not subtabs. - 'tab_root' => 'search/' . $default_info['path'] . '/%', - // These tabs need to display at the same level. - 'tab_parent' => 'search/' . $default_info['path'], - ); } } return $items; } /** - * Determines access for the 'search' path. - */ -function search_is_active() { - // This path cannot be accessed if there are no active plugins. - $account = \Drupal::request()->attributes->get('_account'); - return !empty($account) && $account->hasPermission('search content') && \Drupal::service('plugin.manager.search')->getActiveDefinitions(); -} - -/** * Returns information about the default search plugin. * * @return array @@ -251,12 +218,7 @@ function search_get_default_plugin_info() { * @see search_menu() */ function _search_menu_access($plugin_id) { - $account = \Drupal::request()->attributes->get('_account'); - // @todo - remove the empty() check once we are more confident - // that the account will be populated, especially during tests. - // @see https://drupal.org/node/2032553 - $access = !empty($account) && $account->hasPermission('search content'); - return $access && \Drupal::service('plugin.manager.search')->pluginAccess($plugin_id, $account); + return \Drupal::service('access_manager')->checkNamedRoute('search.view_' . $plugin_id); } /** diff --git a/core/modules/search/search.pages.inc b/core/modules/search/search.pages.inc index b9e06ab..9d4aebe 100644 --- a/core/modules/search/search.pages.inc +++ b/core/modules/search/search.pages.inc @@ -15,6 +15,8 @@ * Search plugin_id to use for the search. * @param $keys * Keywords to use for the search. + * + * @deprecated Use \Drupal\search\Controller\SearchController::searchView() */ function search_view($plugin_id = NULL, $keys = '') { $info = FALSE; diff --git a/core/modules/search/search.routing.yml b/core/modules/search/search.routing.yml index 11719c0..b71c85b 100644 --- a/core/modules/search/search.routing.yml +++ b/core/modules/search/search.routing.yml @@ -11,3 +11,17 @@ search.reindex_confirm: _form: 'Drupal\search\Form\ReindexConfirm' requirements: _permission: 'administer search' + +search.view: + path: '/search/{plugin_id}' + defaults: + _title: 'Search' + _content: '\Drupal\search\Controller\SearchController::searchView' + plugin_id: NULL + keys: '' + options: + _access_mode: 'ALL' + requirements: + keys: '.+' + _permission: 'search content' + _search_access: 'TRUE' diff --git a/core/modules/search/search.services.yml b/core/modules/search/search.services.yml index 22dc7f2..8af9864 100644 --- a/core/modules/search/search.services.yml +++ b/core/modules/search/search.services.yml @@ -2,3 +2,21 @@ services: plugin.manager.search: class: Drupal\search\SearchPluginManager arguments: ['@container.namespaces', '@config.factory'] + + access_check.search: + class: Drupal\search\Access\SearchAccessCheck + arguments: ['@plugin.manager.search'] + tags: + - { name: access_check } + + access_check.search_plugin: + class: Drupal\search\Access\SearchPluginAccessCheck + arguments: ['@plugin.manager.search'] + tags: + - { name: access_check } + + route_subscriber.search: + class: Drupal\search\Routing\SearchRouteSubscriber + arguments: ['@plugin.manager.search'] + tags: + - { name: event_subscriber } diff --git a/core/modules/system/lib/Drupal/system/Controller/SystemController.php b/core/modules/system/lib/Drupal/system/Controller/SystemController.php index 470b5bb..eaaa8a0 100644 --- a/core/modules/system/lib/Drupal/system/Controller/SystemController.php +++ b/core/modules/system/lib/Drupal/system/Controller/SystemController.php @@ -145,4 +145,20 @@ public function systemAdminMenuBlockPage() { return $this->systemManager->getBlockContents(); } + /** + * @todo Remove system_themes_page(). + */ + public function themesPage() { + module_load_include('admin.inc', 'system'); + return system_themes_page(); + } + + /** + * @todo Remove system_theme_default(). + */ + public function themeSetDefault() { + module_load_include('admin.inc', 'system'); + return system_theme_default(); + } + } diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php index b442171..afcfde4 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/BreadcrumbTest.php @@ -172,9 +172,6 @@ function testBreadCrumbs() { $this->assertBreadcrumb("node/$nid1", $trail); // Also verify that the node does not appear elsewhere (e.g., menu trees). $this->assertNoLink($node1->getTitle()); - // The node itself should not be contained in the breadcrumb on the default - // local task, since there is no difference between both pages. - $this->assertBreadcrumb("node/$nid1/view", $trail); // Also verify that the node does not appear elsewhere (e.g., menu trees). $this->assertNoLink($node1->getTitle()); @@ -218,9 +215,6 @@ function testBreadCrumbs() { "node/$nid2" => $node2->menu['link_title'], ); $this->assertBreadcrumb("node/$nid2", $trail, $node2->getTitle(), $tree); - // The node itself should not be contained in the breadcrumb on the - // default local task, since there is no difference between both pages. - $this->assertBreadcrumb("node/$nid2/view", $trail, $node2->getTitle(), $tree); $trail += array( "node/$nid2" => $node2->menu['link_title'], ); @@ -242,9 +236,6 @@ function testBreadCrumbs() { $nid3 = $node3->id(); $this->assertBreadcrumb("node/$nid3", $trail, $node3->getTitle(), $tree, FALSE); - // The node itself should not be contained in the breadcrumb on the - // default local task, since there is no difference between both pages. - $this->assertBreadcrumb("node/$nid3/view", $trail, $node3->getTitle(), $tree, FALSE); $trail += array( "node/$nid3" => $node3->menu['link_title'], ); diff --git a/core/modules/system/lib/Drupal/system/Tests/Menu/TreeOutputTest.php b/core/modules/system/lib/Drupal/system/Tests/Menu/TreeOutputTest.php index 0bcec30..7c5948d 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Menu/TreeOutputTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Menu/TreeOutputTest.php @@ -32,7 +32,7 @@ public static function getInfo() { function setUp() { parent::setUp(); - $this->installSchema('system', 'menu_router'); + $this->installSchema('system', array('router', 'menu_router')); } /** diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index 866b553..cab80f7 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -12,6 +12,8 @@ /** * Menu callback; displays a listing of all themes. + * + * @deprecated Use \Drupal\system\Controller\SystemController::themesPage() */ function system_themes_page() { // Get current list of themes. diff --git a/core/modules/system/system.module b/core/modules/system/system.module index 4625a82..c907f3f 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -605,13 +605,6 @@ function system_element_info() { * Implements hook_menu(). */ function system_menu() { - $items['system/temporary'] = array( - 'title' => 'Temporary files', - 'page callback' => 'file_download', - 'page arguments' => array('temporary'), - 'access callback' => TRUE, - 'type' => MENU_CALLBACK, - ); $items['system/ajax'] = array( 'title' => 'AHAH callback', 'route_name' => 'system.ajax', @@ -648,11 +641,9 @@ function system_menu() { $items['admin/appearance'] = array( 'title' => 'Appearance', 'description' => 'Select and configure your themes.', - 'page callback' => 'system_themes_page', - 'access arguments' => array('administer themes'), + 'route_name' => 'system.themes_page', 'position' => 'left', 'weight' => -6, - 'file' => 'system.admin.inc', ); $items['admin/appearance/list'] = array( 'title' => 'List', @@ -660,13 +651,6 @@ function system_menu() { 'type' => MENU_DEFAULT_LOCAL_TASK, 'file' => 'system.admin.inc', ); - $items['admin/appearance/default'] = array( - 'title' => 'Set default theme', - 'page callback' => 'system_theme_default', - 'access arguments' => array('administer themes'), - 'type' => MENU_CALLBACK, - 'file' => 'system.admin.inc', - ); $items['admin/appearance/settings'] = array( 'title' => 'Settings', 'description' => 'Configure default and theme specific settings.', diff --git a/core/modules/system/system.routing.yml b/core/modules/system/system.routing.yml index 6f60d0b..bef9a05 100644 --- a/core/modules/system/system.routing.yml +++ b/core/modules/system/system.routing.yml @@ -281,6 +281,30 @@ system.files: requirements: _access: 'TRUE' +system.temporary: + path: '/system/temporary' + defaults: + _controller: '\Drupal\system\FileDownloadController::download' + scheme: temporary + requirements: + _access: 'TRUE' + +system.themes_page: + path: '/admin/appearance' + defaults: + _title: 'Appearance' + _content: '\Drupal\system\Controller\SystemController::themesPage' + requirements: + _permission: 'administer themes' + +system.theme_set_default: + path: '/admin/appearance/default' + defaults: + _title: 'Set default theme' + _content: '\Drupal\system\Controller\SystemController::themeSetDefault' + requirements: + _permission: 'administer themes' + system.theme_settings: path: '/admin/appearance/settings' defaults: diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php index 938cc7b..eb57cc5 100644 --- a/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php +++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Controller/TaxonomyController.php @@ -8,6 +8,7 @@ namespace Drupal\taxonomy\Controller; use Drupal\Core\Controller\ControllerBase; +use Drupal\taxonomy\TermInterface; use Drupal\taxonomy\VocabularyInterface; use Symfony\Component\DependencyInjection\ContainerInterface; @@ -33,4 +34,20 @@ public function addForm(VocabularyInterface $taxonomy_vocabulary) { return $this->entityManager()->getForm($term); } + /** + * @todo Remove taxonomy_term_page(). + */ + public function termPage(TermInterface $taxonomy_term) { + module_load_include('pages.inc', 'taxonomy'); + return taxonomy_term_page($taxonomy_term); + } + + /** + * @todo Remove taxonomy_term_feed(). + */ + public function termFeed(TermInterface $taxonomy_term) { + module_load_include('pages.inc', 'taxonomy'); + return taxonomy_term_feed($taxonomy_term); + } + } diff --git a/core/modules/taxonomy/taxonomy.module b/core/modules/taxonomy/taxonomy.module index 1df57d3..81537b6 100644 --- a/core/modules/taxonomy/taxonomy.module +++ b/core/modules/taxonomy/taxonomy.module @@ -250,11 +250,7 @@ function taxonomy_menu() { 'title' => 'Taxonomy term', 'title callback' => 'taxonomy_term_title', 'title arguments' => array(2), - 'page callback' => 'taxonomy_term_page', - 'page arguments' => array(2), - 'access callback' => 'entity_page_access', - 'access arguments' => array(2, 'view'), - 'file' => 'taxonomy.pages.inc', + 'route_name' => 'taxonomy.term_page', ); $items['taxonomy/term/%taxonomy_term/view'] = array( 'title' => 'View', @@ -280,12 +276,8 @@ function taxonomy_menu() { 'title' => 'Taxonomy term', 'title callback' => 'taxonomy_term_title', 'title arguments' => array(2), - 'page callback' => 'taxonomy_term_feed', - 'page arguments' => array(2), - 'access callback' => 'entity_page_access', - 'access arguments' => array(2, 'view'), + 'route_name' => 'taxonomy.term_feed', 'type' => MENU_CALLBACK, - 'file' => 'taxonomy.pages.inc', ); $items['admin/structure/taxonomy/manage/%taxonomy_vocabulary'] = array( diff --git a/core/modules/taxonomy/taxonomy.pages.inc b/core/modules/taxonomy/taxonomy.pages.inc index a2fc467..956bc71 100644 --- a/core/modules/taxonomy/taxonomy.pages.inc +++ b/core/modules/taxonomy/taxonomy.pages.inc @@ -12,6 +12,8 @@ * * @param Drupal\taxonomy\Entity\Term $term * The taxonomy term entity. + * + * @deprecated Use \Drupal\taxonomy\Controller\TaxonomyController::termPage() */ function taxonomy_term_page(Term $term) { // Assign the term name as the page title. @@ -65,6 +67,8 @@ function taxonomy_term_page(Term $term) { * * @param Drupal\taxonomy\Entity\Term $term * The taxonomy term entity. + * + * @deprecated Use \Drupal\taxonomy\Controller\TaxonomyController::termFeed() */ function taxonomy_term_feed(Term $term) { $channel['link'] = url('taxonomy/term/' . $term->id(), array('absolute' => TRUE)); diff --git a/core/modules/taxonomy/taxonomy.routing.yml b/core/modules/taxonomy/taxonomy.routing.yml index f1b9d82..8e024a0 100644 --- a/core/modules/taxonomy/taxonomy.routing.yml +++ b/core/modules/taxonomy/taxonomy.routing.yml @@ -75,3 +75,16 @@ taxonomy.overview_terms: requirements: _entity_access: 'taxonomy_vocabulary.view' +taxonomy.term_page: + path: '/taxonomy/term/{taxonomy_term}' + defaults: + _content: '\Drupal\taxonomy\Controller\TaxonomyController::termPage' + requirements: + _entity_access: 'taxonomy_term.view' + +taxonomy.term_feed: + path: '/taxonomy/term/{taxonomy_term}/feed' + defaults: + _content: '\Drupal\taxonomy\Controller\TaxonomyController::termFeed' + requirements: + _entity_access: 'taxonomy_term.view' diff --git a/core/modules/translation/lib/Drupal/translation/Access/TranslationNodeOverviewAccessCheck.php b/core/modules/translation/lib/Drupal/translation/Access/TranslationNodeOverviewAccessCheck.php new file mode 100644 index 0000000..3b54fe1 --- /dev/null +++ b/core/modules/translation/lib/Drupal/translation/Access/TranslationNodeOverviewAccessCheck.php @@ -0,0 +1,38 @@ +getRequirement('_access_translation_tab'); + if ($request->attributes->has($key)) { + // @todo Remove _translation_tab_access(). + return _translation_tab_access($request->attributes->get($key)) ? static::ALLOW : static::DENY; + } + return static::DENY; + } + +} diff --git a/core/modules/translation/lib/Drupal/translation/Controller/TranslationController.php b/core/modules/translation/lib/Drupal/translation/Controller/TranslationController.php new file mode 100644 index 0000000..68911ec --- /dev/null +++ b/core/modules/translation/lib/Drupal/translation/Controller/TranslationController.php @@ -0,0 +1,25 @@ + 'Translate', - 'page callback' => 'translation_node_overview', - 'page arguments' => array(1), - 'access callback' => '_translation_tab_access', - 'access arguments' => array(1), + 'route_name' => 'translation.node_overview', 'type' => MENU_LOCAL_TASK, 'context' => MENU_CONTEXT_PAGE | MENU_CONTEXT_INLINE, 'weight' => 2, - 'file' => 'translation.pages.inc', ); return $items; } diff --git a/core/modules/translation/translation.pages.inc b/core/modules/translation/translation.pages.inc index 4fff31d..a1f6360 100644 --- a/core/modules/translation/translation.pages.inc +++ b/core/modules/translation/translation.pages.inc @@ -18,6 +18,8 @@ * A render array for a page containing a list of content. * * @see translation_menu() + * + * @deprecated Use \Drupal\translation\Controller\TranslationController::nodeOverview() */ function translation_node_overview(EntityInterface $node) { include_once DRUPAL_ROOT . '/core/includes/language.inc'; @@ -91,7 +93,7 @@ function translation_node_overview(EntityInterface $node) { $rows[] = $row; } - drupal_set_title(t('Translations of %title', array('%title' => $node->label())), PASS_THROUGH); + $build['#title'] = t('Translations of %title', array('%title' => $node->label())); $build['translation_node_overview'] = array( '#theme' => 'table', diff --git a/core/modules/translation/translation.routing.yml b/core/modules/translation/translation.routing.yml new file mode 100644 index 0000000..7129075 --- /dev/null +++ b/core/modules/translation/translation.routing.yml @@ -0,0 +1,7 @@ +translation.node_overview: + path: '/node/{node}/translate' + defaults: + _title: 'Translate' + _content: '\Drupal\translation\Controller\TranslationController::nodeOverview' + requirements: + _access_translation_tab: 'node' diff --git a/core/modules/translation/translation.services.yml b/core/modules/translation/translation.services.yml new file mode 100644 index 0000000..e6520d5 --- /dev/null +++ b/core/modules/translation/translation.services.yml @@ -0,0 +1,5 @@ +services: + access_check.translation.node_overview: + class: Drupal\translation\Access\TranslationNodeOverviewAccessCheck + tags: + - { name: access_check } diff --git a/core/modules/update/lib/Drupal/update/Controller/UpdateController.php b/core/modules/update/lib/Drupal/update/Controller/UpdateController.php index deef6d8..6816466 100644 --- a/core/modules/update/lib/Drupal/update/Controller/UpdateController.php +++ b/core/modules/update/lib/Drupal/update/Controller/UpdateController.php @@ -62,4 +62,12 @@ public function updateStatus() { return $build; } + /** + * @todo Remove update_manual_status(). + */ + public function updateStatusManually() { + module_load_include('fetch.inc', 'update'); + return update_manual_status(); + } + } diff --git a/core/modules/update/update.fetch.inc b/core/modules/update/update.fetch.inc index 6cb7cb7..ac3c1b5 100644 --- a/core/modules/update/update.fetch.inc +++ b/core/modules/update/update.fetch.inc @@ -14,6 +14,8 @@ * Manually checks the update status without the use of cron. * * @see update_menu() + * + * @deprecated Use \Drupal\update\Controller\UpdateController::updateStatusManually() */ function update_manual_status() { _update_refresh(); diff --git a/core/modules/update/update.module b/core/modules/update/update.module index 0210c01..692d5bc 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -173,13 +173,6 @@ function update_menu() { 'type' => MENU_LOCAL_TASK, 'weight' => 50, ); - $items['admin/reports/updates/check'] = array( - 'title' => 'Manual update check', - 'page callback' => 'update_manual_status', - 'access arguments' => array('administer site configuration'), - 'type' => MENU_CALLBACK, - 'file' => 'update.fetch.inc', - ); // We want action links for updating projects at a few different locations: // both the module and theme administration pages, and on the available diff --git a/core/modules/update/update.routing.yml b/core/modules/update/update.routing.yml index f6bd120..43ae6b5 100644 --- a/core/modules/update/update.routing.yml +++ b/core/modules/update/update.routing.yml @@ -11,3 +11,11 @@ update.status: _content: '\Drupal\update\Controller\UpdateController::updateStatus' requirements: _permission: 'administer site configuration' + +update.manual_status: + path: '/admin/reports/updates/check' + defaults: + _title: 'Manual update check' + _content: '\Drupal\update\Controller\UpdateController::updateStatusManually' + requirements: + _permission: 'administer site configuration' diff --git a/core/modules/user/lib/Drupal/user/Controller/UserController.php b/core/modules/user/lib/Drupal/user/Controller/UserController.php index cd63cb0..2ddf843 100644 --- a/core/modules/user/lib/Drupal/user/Controller/UserController.php +++ b/core/modules/user/lib/Drupal/user/Controller/UserController.php @@ -8,6 +8,7 @@ namespace Drupal\user\Controller; use Drupal\user\Form\UserLoginForm; +use Drupal\user\UserInterface; use Symfony\Component\DependencyInjection\ContainerAware; use Symfony\Component\HttpFoundation\RedirectResponse; use Symfony\Component\HttpFoundation\Request; @@ -55,4 +56,12 @@ public function logout(Request $request) { return new RedirectResponse(url('', array('absolute' => TRUE))); } + /** + * @todo Remove user_cancel_confirm(). + */ + public function confirmCancel(UserInterface $user, $timestamp = 0, $hashed_pass = '') { + module_load_include('pages.inc', 'user'); + return user_cancel_confirm($user, $timestamp, $hashed_pass); + } + } diff --git a/core/modules/user/user.module b/core/modules/user/user.module index 3bc4534..93c5b77 100644 --- a/core/modules/user/user.module +++ b/core/modules/user/user.module @@ -849,25 +849,18 @@ function user_menu() { 'title' => 'My account', 'title callback' => 'user_page_title', 'title arguments' => array(1), - 'page callback' => 'user_view_page', - 'page arguments' => array(1), - 'access callback' => 'entity_page_access', - 'access arguments' => array(1), + 'route_name' => 'user.view', ); $items['user/%user/view'] = array( 'title' => 'View', 'type' => MENU_DEFAULT_LOCAL_TASK, ); $items['user/%user/cancel'] = array( - 'route_name' => 'user.cancel_confirm', + 'route_name' => 'user.cancel', ); $items['user/%user/cancel/confirm/%/%'] = array( 'title' => 'Confirm account cancellation', - 'page callback' => 'user_cancel_confirm', - 'page arguments' => array(1, 4, 5), - 'access callback' => 'entity_page_access', - 'access arguments' => array(1, 'delete'), - 'file' => 'user.pages.inc', + 'route_name' => 'user.cancel_confirm', ); $items['user/%user/edit'] = array( 'title' => 'Edit', @@ -1371,18 +1364,6 @@ function user_delete_multiple(array $uids) { } /** - * Page callback wrapper for user_view(). - */ -function user_view_page($account) { - if (is_object($account)) { - return user_view($account); - } - // An administrator may try to view a non-existent account, - // so we give them a 404 (versus a 403 for non-admins). - throw new NotFoundHttpException(); -} - -/** * Generate an array for rendering the given user. * * When viewing a user profile, the $page array contains: diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc index 6e4f999..6d59e6c 100644 --- a/core/modules/user/user.pages.inc +++ b/core/modules/user/user.pages.inc @@ -123,6 +123,8 @@ function template_preprocess_user(&$variables) { * * @see user_cancel_confirm_form() * @see user_cancel_url() + * + * @deprecated Use \Drupal\user\Controller\UserController::confirmCancel() */ function user_cancel_confirm($account, $timestamp = 0, $hashed_pass = '') { // Time out in seconds until cancel URL expires; 24 hours = 86400 seconds. diff --git a/core/modules/user/user.routing.yml b/core/modules/user/user.routing.yml index 22b6c5e..6a9c057 100644 --- a/core/modules/user/user.routing.yml +++ b/core/modules/user/user.routing.yml @@ -111,6 +111,14 @@ user.page: requirements: _access: 'TRUE' +user.view: + path: '/user/{user}' + defaults: + _entity_view: 'user.full' + requirements: + user: \d+ + _entity_access: 'user.view' + user.login: path: '/user/login' defaults: @@ -125,10 +133,20 @@ user.edit: requirements: _entity_access: 'user.update' -user.cancel_confirm: +user.cancel: path: '/user/{user}/cancel' defaults: _title: 'Cancel account' _entity_form: 'user.cancel' requirements: _entity_access: 'user.delete' + +user.cancel_confirm: + path: '/user/{user}/cancel/confirm/{timestamp}/{hashed_pass}' + defaults: + _title: 'Confirm account cancellation' + _content: '\Drupal\user\Controller\UserController::confirmCancel' + timestamp: 0 + hashed_pass: '' + requirements: + _entity_access: 'user.delete' diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorStringTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorStringTest.php index d3c3862..3617409 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorStringTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorStringTest.php @@ -49,7 +49,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + $this->installSchema('system', array('router', 'menu_router', 'variable', 'key_value_expire')); } diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php index 77841f3..8ff7823 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterBooleanOperatorTest.php @@ -45,7 +45,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + $this->installSchema('system', array('router', 'menu_router', 'variable', 'key_value_expire')); } /** diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php index 9b74533..4ab42ad 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterEqualityTest.php @@ -38,7 +38,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + $this->installSchema('system', array('router', 'menu_router', 'variable', 'key_value_expire')); } function viewsData() { diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php index 0c1f32a..6e3e4e5 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterInOperatorTest.php @@ -39,7 +39,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + $this->installSchema('system', array('router', 'menu_router', 'variable', 'key_value_expire')); } function viewsData() { diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php index a1f50ef..62b16d3 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterNumericTest.php @@ -39,7 +39,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + $this->installSchema('system', array('router', 'menu_router', 'variable', 'key_value_expire')); } function viewsData() { diff --git a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php index 2bf0e9b..efb19f7 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Handler/FilterStringTest.php @@ -38,7 +38,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router', 'variable', 'key_value_expire')); + $this->installSchema('system', array('router', 'menu_router', 'variable', 'key_value_expire')); } function viewsData() { diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayPageTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayPageTest.php index d3ddcf0..f597199 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayPageTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/DisplayPageTest.php @@ -57,9 +57,7 @@ protected function setUp() { parent::setUp(); // Setup the needed tables in order to make the drupal router working. - $this->installSchema('system', 'router'); - $this->installSchema('system', 'url_alias'); - $this->installSchema('system', 'menu_router'); + $this->installSchema('system', array('router', 'menu_router', 'url_alias')); $this->installSchema('menu_link', 'menu_links'); } diff --git a/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php b/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php index 8ce7a8e..4486157 100644 --- a/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/Plugin/RowEntityTest.php @@ -51,7 +51,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', array('menu_router')); + $this->installSchema('system', array('menu_router', 'router')); $this->installSchema('taxonomy', array('taxonomy_term_data', 'taxonomy_term_hierarchy')); $this->installConfig(array('taxonomy')); } diff --git a/core/modules/views/lib/Drupal/views/Tests/ViewPageControllerTest.php b/core/modules/views/lib/Drupal/views/Tests/ViewPageControllerTest.php index 892b2be..d4806f0 100644 --- a/core/modules/views/lib/Drupal/views/Tests/ViewPageControllerTest.php +++ b/core/modules/views/lib/Drupal/views/Tests/ViewPageControllerTest.php @@ -55,7 +55,7 @@ public static function getInfo() { protected function setUp() { parent::setUp(); - $this->installSchema('system', 'menu_router'); + $this->installSchema('system', array('router', 'menu_router')); $this->pageController = new ViewPageController($this->container->get('entity.manager')->getStorageController('view'), new ViewExecutableFactory()); } diff --git a/core/modules/xmlrpc/lib/Drupal/xmlrpc/Controller/XmlrpcController.php b/core/modules/xmlrpc/lib/Drupal/xmlrpc/Controller/XmlrpcController.php new file mode 100644 index 0000000..4abbf3d --- /dev/null +++ b/core/modules/xmlrpc/lib/Drupal/xmlrpc/Controller/XmlrpcController.php @@ -0,0 +1,23 @@ + 'XML-RPC', - 'page callback' => 'xmlrpc_server_page', - 'access callback' => TRUE, - 'type' => MENU_CALLBACK, - 'file' => 'xmlrpc.server.inc', - ); - return $items; -} - -/** * Performs one or more XML-RPC request(s). * * Usage example: diff --git a/core/modules/xmlrpc/xmlrpc.routing.yml b/core/modules/xmlrpc/xmlrpc.routing.yml new file mode 100644 index 0000000..f6cc78c --- /dev/null +++ b/core/modules/xmlrpc/xmlrpc.routing.yml @@ -0,0 +1,7 @@ +xmlrpc.php: + path: '/xmlrpc.php' + defaults: + _title: 'XML-RPC' + _content: '\Drupal\xmlrpc\Controller\XmlrpcController::php' + requirements: + _access: 'TRUE' diff --git a/core/modules/xmlrpc/xmlrpc.server.inc b/core/modules/xmlrpc/xmlrpc.server.inc index 8f171a5..1d210e5 100644 --- a/core/modules/xmlrpc/xmlrpc.server.inc +++ b/core/modules/xmlrpc/xmlrpc.server.inc @@ -13,6 +13,8 @@ * * @return \Symfony\Component\HttpFoundation\Response * A Response object. + * + * @deprecated Use \Drupal\xmlrpc\Controller\XmlrpcController::php() */ function xmlrpc_server_page() { module_load_include('inc', 'xmlrpc');