diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 5372dc7c5fa..79620156366 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -183,13 +183,6 @@ const DRUPAL_EXTENSION_NAME_MAX_LENGTH = 50; */ define('REQUEST_TIME', (int) $_SERVER['REQUEST_TIME']); -/** - * Flag for drupal_set_title(); text has already been sanitized. - * - * @todo Move to the Title class. - */ -const PASS_THROUGH = -1; - /** * Regular expression to match PHP function names. * @@ -1330,46 +1323,6 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) { return array(); } -/** - * Gets the title of the current page. - * - * The title is displayed on the page and in the title bar. - * - * @return - * The current page's title. - */ -function drupal_get_title() { - return drupal_set_title() ?: ''; -} - -/** - * Sets the title of the current page. - * - * The title is displayed on the page and in the title bar. - * - * @param $title - * Optional string value to assign to the page title; or if set to NULL - * (default), leaves the current title unchanged. - * @param $output - * Optional flag - normally should be left as Title::CHECK_PLAIN. Only set to - * PASS_THROUGH if you have already removed any possibly dangerous code - * from $title using a function like - * \Drupal\Component\Utility\String::checkPlain() or filter_xss(). With this - * flag the string will be passed through unchanged. - * - * @return - * The updated title of the current page. - */ -function drupal_set_title($title = NULL, $output = Title::CHECK_PLAIN) { - $stored_title = &drupal_static(__FUNCTION__); - - if (isset($title)) { - $stored_title = ($output == PASS_THROUGH) ? $title : String::checkPlain($title); - } - - return $stored_title; -} - /** * Generates a default anonymous $user object. * diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 49a8bd1367e..fba130e7fdc 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -2047,12 +2047,6 @@ function template_preprocess_html(&$variables) { 'name' => String::checkPlain($site_config->get('name')), ); } - elseif (drupal_get_title()) { - $head_title = array( - 'title' => strip_tags(drupal_get_title()), - 'name' => String::checkPlain($site_config->get('name')), - ); - } // @todo Remove once views is not bypassing the view subscriber anymore. // @see http://drupal.org/node/2068471 elseif (drupal_is_front_page()) { @@ -2133,6 +2127,7 @@ function template_preprocess_page(&$variables) { // Move some variables to the top level for themer convenience and template cleanliness. $variables['show_messages'] = $variables['page']['#show_messages']; + $variables['title'] = $variables['page']['#title']; foreach (system_region_list($GLOBALS['theme']) as $region_key => $region_name) { if (!isset($variables['page'][$region_key])) { @@ -2162,13 +2157,6 @@ function template_preprocess_page(&$variables) { $variables['site_slogan'] = (theme_get_setting('features.slogan') ? filter_xss_admin($site_config->get('slogan')) : ''); $variables['tabs'] = menu_local_tabs(); - if (isset($variables['page']['#title'])) { - $variables['title'] = $variables['page']['#title']; - } - else { - $variables['title'] = new RenderWrapper('drupal_get_title'); - } - // Pass the main menu and secondary menu to the template as render arrays. if (!empty($variables['main_menu'])) { $variables['main_menu'] = array( @@ -2353,12 +2341,6 @@ function template_preprocess_maintenance_page(&$variables) { 'name' => String::checkPlain($site_config->get('name')), ); } - elseif (drupal_get_title()) { - $head_title = array( - 'title' => strip_tags(drupal_get_title()), - 'name' => String::checkPlain($site_config->get('name')), - ); - } else { $head_title = array('name' => String::checkPlain($site_name)); if ($site_slogan) { @@ -2419,9 +2401,6 @@ function template_preprocess_maintenance_page(&$variables) { if (isset($variables['page']['#title'])) { $variables['title'] = $variables['page']['#title']; } - if (!isset($variables['title'])) { - $variables['title'] = drupal_get_title(); - } } /** diff --git a/core/lib/Drupal/Core/Controller/DialogController.php b/core/lib/Drupal/Core/Controller/DialogController.php index 5fda730ad96..e86b9bd4ccb 100644 --- a/core/lib/Drupal/Core/Controller/DialogController.php +++ b/core/lib/Drupal/Core/Controller/DialogController.php @@ -93,14 +93,7 @@ class DialogController { } $content = drupal_render($page_content); - - // @todo Remove use of drupal_get_title() when - // http://drupal.org/node/1871596 is in. - if (!$title = $this->titleResolver->getTitle($request, $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT))) { - // @todo Remove use of drupal_get_title() when - // http://drupal.org/node/1871596 is in. - $title = drupal_get_title(); - } + $title = $this->titleResolver->getTitle($request, $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)); $response = new AjaxResponse(); // Fetch any modal options passed in from data-dialog-options. if (!($options = $request->request->get('dialogOptions'))) { diff --git a/core/lib/Drupal/Core/Controller/HtmlControllerBase.php b/core/lib/Drupal/Core/Controller/HtmlControllerBase.php index 0204bc06e1e..9cc76519b52 100644 --- a/core/lib/Drupal/Core/Controller/HtmlControllerBase.php +++ b/core/lib/Drupal/Core/Controller/HtmlControllerBase.php @@ -80,7 +80,7 @@ class HtmlControllerBase { $fragment->setTitle($page_content['#title'], Title::FILTER_XSS_ADMIN); } else if ($route = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) { - $fragment->setTitle($this->titleResolver->getTitle($request, $route), PASS_THROUGH); + $fragment->setTitle($this->titleResolver->getTitle($request, $route), Title::PASS_THROUGH); } return $fragment; diff --git a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php index 64aed01b160..6e0c5095e73 100644 --- a/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php +++ b/core/lib/Drupal/Core/Page/DefaultHtmlFragmentRenderer.php @@ -74,14 +74,6 @@ class DefaultHtmlFragmentRenderer implements HtmlFragmentRendererInterface { * The modified page object. */ public function preparePage(HtmlPage $page, &$page_array) { - // @todo Remove this one drupal_get_title() has been eliminated. - if (!$page->hasTitle()) { - $title = drupal_get_title(); - // drupal_set_title() already ensured security, so not letting the - // title pass through would cause double escaping. - $page->setTitle($title, PASS_THROUGH); - } - $page_array['#page'] = $page; // HTML element attributes. diff --git a/core/lib/Drupal/Core/Page/HtmlFragment.php b/core/lib/Drupal/Core/Page/HtmlFragment.php index cc5cac5a6c4..cf1ca4dd8c0 100644 --- a/core/lib/Drupal/Core/Page/HtmlFragment.php +++ b/core/lib/Drupal/Core/Page/HtmlFragment.php @@ -103,8 +103,8 @@ class HtmlFragment implements CacheableInterface { * Value to assign to the page title. * @param int $output * (optional) normally should be left as Title::CHECK_PLAIN. Only set to - * PASS_THROUGH if you have already removed any possibly dangerous code - * from $title using a function like + * Title::PASS_THROUGH if you have already removed any possibly dangerous + * code from $title using a function like * \Drupal\Component\Utility\String::checkPlain() or * \Drupal\Component\Utility\Xss::filterAdmin(). With this flag the string * will be passed through unchanged. diff --git a/core/lib/Drupal/Core/Utility/Title.php b/core/lib/Drupal/Core/Utility/Title.php index b6380b6c98b..40a3a91e278 100644 --- a/core/lib/Drupal/Core/Utility/Title.php +++ b/core/lib/Drupal/Core/Utility/Title.php @@ -22,4 +22,9 @@ class Title { */ const FILTER_XSS_ADMIN = 1; + /** + * For controller titles, text has already been sanitized. + */ + const PASS_THROUGH = -1; + } diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php index daf2e77a2da..001b8076b89 100644 --- a/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderElementTypesTest.php @@ -161,21 +161,6 @@ class RenderElementTypesTest extends DrupalUnitTestBase { $html_attributes['dir'] = $language_interface->direction ? 'rtl' : 'ltr'; $site_config = \Drupal::config('system.site'); - $site_name = $site_config->get('name'); - $site_slogan = $site_config->get('slogan'); - if ($title = drupal_get_title()) { - $head_title = array( - 'title' => strip_tags($title), - 'name' => String::checkPlain($site_config->get('name')), - ); - } - else { - $head_title = array('name' => String::checkPlain($site_name)); - if ($site_slogan) { - $head_title['slogan'] = strip_tags(Xss::filterAdmin($site_slogan)); - } - } - $head_title = implode(' | ', $head_title); // Add favicon. $favicon = theme_get_setting('favicon.url'); @@ -229,14 +214,14 @@ EOT; $placeholders = array( '!html_attributes' => $html_attributes->__toString(), '!head' => drupal_get_html_head(), - '!head_title' => $head_title, + '!head_title' => $site_config->get('name'), '!styles' => drupal_get_css($css), '!scripts' => drupal_get_js(), '!attributes.class' => 'maintenance-page in-maintenance no-sidebars', '!front_page' => url(), '!logo' => theme_get_setting('logo.url'), '!site_name' => $site_config->get('name'), - '!title' => $title ? '

' . $title . '

' : '', + '!title' => '', '!content' => 'foo', ); @@ -244,6 +229,7 @@ EOT; drupal_static_reset(); // Test basic string for maintenance page content. + // No page title is set, so it should default to the site name. $elements = array( array( 'name' => "#theme 'maintenance_page' with content of foo", @@ -262,6 +248,11 @@ EOT; drupal_static_reset(); $elements[0]['name'] = "#theme 'maintenance_page' with content as a render array"; $elements[0]['value']['#content'] = array('#markup' => 'foo'); + // Testing with a page title, which should be combined with the site name. + $title = t('A non-empty title'); + $elements[0]['value']['#page']['#title'] = $title; + $elements[0]['placeholders']['!title'] = '

' . $title . '

'; + $elements[0]['placeholders']['!head_title'] = strip_tags($title) . ' | ' . String::checkPlain($site_config->get('name')); $this->assertElements($elements); } diff --git a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php index 33f2f47bd97..fdc511a5abb 100644 --- a/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php +++ b/core/modules/system/lib/Drupal/system/Tests/System/PageTitleTest.php @@ -28,7 +28,7 @@ class PageTitleTest extends WebTestBase { public static function getInfo() { return array( 'name' => 'Page titles', - 'description' => 'Tests correct handling or conversion by drupal_set_title() and drupal_get_title() and checks the correct escaping of site name and slogan.', + 'description' => 'Tests correct escaping of page title, site name and slogan.', 'group' => 'System' ); } @@ -43,32 +43,13 @@ class PageTitleTest extends WebTestBase { $this->content_user = $this->drupalCreateUser(array('create page content', 'access content', 'administer themes', 'administer site configuration')); $this->drupalLogin($this->content_user); - $this->saved_title = drupal_get_title(); } /** - * Reset page title. - */ - function tearDown() { - // Restore the page title. - drupal_set_title($this->saved_title, PASS_THROUGH); - - parent::tearDown(); - } - - /** - * Tests the handling of HTML by drupal_set_title() and drupal_get_title() + * Tests the handling of HTML in node titles. */ function testTitleTags() { $title = "string with HTML"; - // drupal_set_title's $filter is Title::CHECK_PLAIN by default, so the title should be - // returned with check_plain(). - drupal_set_title($title, Title::CHECK_PLAIN); - $this->assertTrue(strpos(drupal_get_title(), '') === FALSE, 'Tags in title converted to entities when $output is Title::CHECK_PLAIN.'); - // drupal_set_title's $filter is passed as PASS_THROUGH, so the title should be - // returned with HTML. - drupal_set_title($title, PASS_THROUGH); - $this->assertTrue(strpos(drupal_get_title(), '') !== FALSE, 'Tags in title are not converted to entities when $output is PASS_THROUGH.'); // Generate node content. $edit = array( 'title[0][value]' => '!SimpleTest! ' . $title . $this->randomName(20), @@ -82,6 +63,7 @@ class PageTitleTest extends WebTestBase { $this->drupalGet("node/" . $node->id()); $this->assertText(check_plain($edit['title[0][value]']), 'Check to make sure tags in the node title are converted.'); } + /** * Test if the title of the site is XSS proof. */ @@ -113,9 +95,10 @@ class PageTitleTest extends WebTestBase { $this->drupalGet(''); // Test the title. - $this->assertNoRaw($title, 'Check for the unfiltered version of the title.'); - // Adding so we do not test the escaped version from drupal_set_title(). - $this->assertRaw($title_filtered . '', 'Check for the filtered version of the title.'); + $this->assertNoRaw($title, 'Check for the lack of the unfiltered version of the title.'); + // Add to make sure we're checking the title tag, rather than the + // first 'heading' on the page. + $this->assertRaw($title_filtered . '', 'Check for the filtered version of the title in a tag.'); // Test the slogan. $this->assertNoRaw($slogan, 'Check for the unfiltered version of the slogan.'); diff --git a/core/modules/system/system.module b/core/modules/system/system.module index eef5bce800b..25fe8d41fdf 100644 --- a/core/modules/system/system.module +++ b/core/modules/system/system.module @@ -292,6 +292,7 @@ function system_element_info() { $types['page'] = array( '#show_messages' => TRUE, '#theme' => 'page', + '#title' => '', ); // By default, we don't want Ajax commands being rendered in the context of an // HTML page, so we don't provide defaults for #theme or #theme_wrappers. diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/area/Title.php b/core/modules/views/lib/Drupal/views/Plugin/views/area/Title.php index 66f34952b07..bbc26ecdd99 100644 --- a/core/modules/views/lib/Drupal/views/Plugin/views/area/Title.php +++ b/core/modules/views/lib/Drupal/views/Plugin/views/area/Title.php @@ -7,6 +7,8 @@ namespace Drupal\views\Plugin\views\area; +use \Drupal\Core\Utility\Title as UtilityTitle; + /** * Views area title override handler. * @@ -51,7 +53,7 @@ class Title extends AreaPluginBase { // If a title is provided, process it. if (!empty($this->options['title'])) { $value = $this->globalTokenReplace($this->options['title']); - $this->view->setTitle($this->sanitizeValue($value, 'xss_admin'), PASS_THROUGH); + $this->view->setTitle($this->sanitizeValue($value, 'xss_admin'), UtilityTitle::PASS_THROUGH); } }