diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index e8ccd36..e1c15fe 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -2,7 +2,6 @@
use Drupal\Component\Utility\NestedArray;
use Drupal\Component\Utility\Settings;
-use Drupal\Component\Utility\Timer;
use Drupal\Core\DrupalKernel;
use Drupal\Core\Database\Database;
use Drupal\Core\DependencyInjection\ContainerBuilder;
@@ -335,27 +334,71 @@
define('DRUPAL_ROOT', dirname(dirname(__DIR__)));
/**
- * @deprecated as of Drupal 8.0.
- * @see \Drupal\Component\Utility\Timer::start
+ * Starts the timer with the specified name.
+ *
+ * If you start and stop the same timer multiple times, the measured intervals
+ * will be accumulated.
+ *
+ * @param $name
+ * The name of the timer.
*/
function timer_start($name) {
- Timer::start($name);
+ global $timers;
+
+ $timers[$name]['start'] = microtime(TRUE);
+ $timers[$name]['count'] = isset($timers[$name]['count']) ? ++$timers[$name]['count'] : 1;
}
/**
- * @deprecated as of Drupal 8.0.
- * @see \Drupal\Component\Utility\Timer::read
+ * Reads the current timer value without stopping the timer.
+ *
+ * @param $name
+ * The name of the timer.
+ *
+ * @return
+ * The current timer value in ms.
*/
function timer_read($name) {
- return Timer::read($name);
+ global $timers;
+
+ if (isset($timers[$name]['start'])) {
+ $stop = microtime(TRUE);
+ $diff = round(($stop - $timers[$name]['start']) * 1000, 2);
+
+ if (isset($timers[$name]['time'])) {
+ $diff += $timers[$name]['time'];
+ }
+ return $diff;
+ }
+ return $timers[$name]['time'];
}
/**
- * @deprecated as of Drupal 8.0.
- * @see \Drupal\Component\Utility\Timer::stop
+ * Stops the timer with the specified name.
+ *
+ * @param $name
+ * The name of the timer.
+ *
+ * @return
+ * A timer array. The array contains the number of times the timer has been
+ * started and stopped (count) and the accumulated timer value in ms (time).
*/
function timer_stop($name) {
- return Timer::stop($name);
+ global $timers;
+
+ if (isset($timers[$name]['start'])) {
+ $stop = microtime(TRUE);
+ $diff = round(($stop - $timers[$name]['start']) * 1000, 2);
+ if (isset($timers[$name]['time'])) {
+ $timers[$name]['time'] += $diff;
+ }
+ else {
+ $timers[$name]['time'] = $diff;
+ }
+ unset($timers[$name]['start']);
+ }
+
+ return $timers[$name];
}
/**
@@ -2238,6 +2281,8 @@ function _drupal_exception_handler($exception) {
*/
function _drupal_bootstrap_configuration() {
drupal_environment_initialize();
+ // Start a page timer:
+ timer_start('page');
// Initialize the configuration, including variables from settings.php.
drupal_settings_initialize();
@@ -2247,9 +2292,6 @@ function _drupal_bootstrap_configuration() {
// Activate the class loader.
drupal_classloader();
- // Start a page timer:
- Timer::start('page');
-
// Load the procedural configuration system helper functions.
require_once DRUPAL_ROOT . '/core/includes/config.inc';
diff --git a/core/lib/Drupal/Component/Utility/Timer.php b/core/lib/Drupal/Component/Utility/Timer.php
deleted file mode 100644
index 294632c..0000000
--- a/core/lib/Drupal/Component/Utility/Timer.php
+++ /dev/null
@@ -1,79 +0,0 @@
- 'URL language detection configuration',
- 'route_name' => 'language_negotiation_url',
+ 'page callback' => 'NOT_USED',
+ 'access arguments' => array('administer languages'),
'type' => MENU_VISIBLE_IN_BREADCRUMB,
);
$items['admin/config/regional/language/detection/session'] = array(
'title' => 'Session language detection configuration',
- 'route_name' => 'language_negotiation_session',
+ 'page callback' => 'NOT_USED',
+ 'access arguments' => array('administer languages'),
'type' => MENU_VISIBLE_IN_BREADCRUMB,
);
$items['admin/config/regional/language/detection/browser'] = array(
@@ -139,7 +141,8 @@ function language_menu() {
);
$items['admin/config/regional/language/detection/selected'] = array(
'title' => 'Selected language detection configuration',
- 'route_name' => 'language_negotiation_selected',
+ 'page callback' => 'NOT_USED',
+ 'access arguments' => array('administer languages'),
'type' => MENU_VISIBLE_IN_BREADCRUMB,
);
diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/TimerUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/TimerUnitTest.php
new file mode 100644
index 0000000..ab100e2
--- /dev/null
+++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/TimerUnitTest.php
@@ -0,0 +1,43 @@
+ 'Timer test',
+ 'description' => 'Test that timer_read() works both when a timer is running and when a timer is stopped.',
+ 'group' => 'Bootstrap',
+ );
+ }
+
+ /**
+ * Tests timer_read() time accumulation accuracy across multiple restarts.
+ */
+ function testTimer() {
+ timer_start('test');
+ sleep(1);
+ $this->assertTrue(timer_read('test') >= 1000, 'Timer measured 1 second of sleeping while running.');
+ sleep(1);
+ timer_stop('test');
+ $this->assertTrue(timer_read('test') >= 2000, 'Timer measured 2 seconds of sleeping after being stopped.');
+ timer_start('test');
+ sleep(1);
+ $this->assertTrue(timer_read('test') >= 3000, 'Timer measured 3 seconds of sleeping after being restarted.');
+ sleep(1);
+ $timer = timer_stop('test');
+ $this->assertTrue(timer_read('test') >= 4000, 'Timer measured 4 seconds of sleeping after being stopped for a second time.');
+ $this->assertEqual($timer['count'], 2, 'Timer counted 2 instances of being started.');
+ }
+}
diff --git a/core/modules/tour/config/schema/tour.schema.yml b/core/modules/tour/config/schema/tour.schema.yml
deleted file mode 100644
index 3975fb4..0000000
--- a/core/modules/tour/config/schema/tour.schema.yml
+++ /dev/null
@@ -1,60 +0,0 @@
-# Schema for the configuration files of the Tour module.
-
-tour.tour.*:
- type: mapping
- label: 'Tour settings'
- mapping:
- id:
- type: string
- label: 'ID'
- label:
- type: label
- label: 'Label'
- langcode:
- type: string
- label: 'Language'
- paths:
- type: sequence
- label: 'Path settings'
- sequence:
- - type: path
- label: 'Path'
- tips:
- type: sequence
- label: 'Tips'
- sequence:
- - type: tour.tip.[plugin]
- label: 'Tour tip'
-
-tour.tip:
- type: mapping
- label: 'Tour tip'
- mapping:
- id:
- type: string
- label: 'ID'
- plugin:
- type: string
- label: 'Plugin'
- label:
- type: label
- label: 'Label'
- weight:
- type: integer
- label: 'Weight'
- attributes:
- type: sequence
- label: 'Attributes'
- sequence:
- - type: string
- label: 'Attribute'
-
-tour.tip.text:
- type: tour.tip
- label: 'Textual tour tip'
- mapping:
- body:
- type: text
- label: 'Body'
-
-
diff --git a/core/modules/tour/tests/tour_test/config/schema/tour_test.schema.yml b/core/modules/tour/tests/tour_test/config/schema/tour_test.schema.yml
deleted file mode 100644
index a43cc26..0000000
--- a/core/modules/tour/tests/tour_test/config/schema/tour_test.schema.yml
+++ /dev/null
@@ -1,9 +0,0 @@
-# Schema for the configuration files of the Tour Test module.
-
-tour.tip.image:
- type: tour.tip
- label: 'Image tour tip'
- mapping:
- url:
- type: uri
- label: 'Image URL'
diff --git a/core/modules/user/templates/user-permission-description.html.twig b/core/modules/user/templates/user-permission-description.html.twig
new file mode 100644
index 0000000..d1d5562
--- /dev/null
+++ b/core/modules/user/templates/user-permission-description.html.twig
@@ -0,0 +1,26 @@
+{#
+/**
+ * @file
+ * Default theme implementation for an individual permission description.
+ *
+ * Available variables:
+ * - description: The text of the permission description.
+ * - warning: A security-related warning message about the permission (if
+ * there is one).
+ * - hide: Indicates whether or not the permission description was requested
+ * to be hidden rather than shown.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_user_permission_description()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if not hide %}
+ {% if description %}
+ {{- description -}}
+ {% endif %}
+ {% if warning %}
+ {{ warning }}
+ {% endif %}
+{% endif %}
diff --git a/core/modules/user/templates/user-picture.tpl.php b/core/modules/user/templates/user-picture.tpl.php
deleted file mode 100644
index ee82187..0000000
--- a/core/modules/user/templates/user-picture.tpl.php
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-
-
-
-
diff --git a/core/modules/user/templates/user-signature.html.twig b/core/modules/user/templates/user-signature.html.twig
new file mode 100644
index 0000000..cac3a68
--- /dev/null
+++ b/core/modules/user/templates/user-signature.html.twig
@@ -0,0 +1,22 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a user signature.
+ *
+ * Available variables:
+ * - signature: The user's signature.
+ * - attributes: An array of HTML attributes for the wrapper of the signature.
+ *
+ * @todo Use a general wrapper instead of this file.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_user_signature()
+ *
+ * @ingroup themeable
+ */
+#}
+{% spaceless %}
+{% if signature %}
+
+{% endif %}
+{% endspaceless %}
diff --git a/core/modules/user/templates/user.html.twig b/core/modules/user/templates/user.html.twig
new file mode 100644
index 0000000..c7a9a0e
--- /dev/null
+++ b/core/modules/user/templates/user.html.twig
@@ -0,0 +1,34 @@
+{#
+/**
+ * @file
+ * Default theme implementation to present all user data.
+ *
+ * This template is used when viewing a registered user's page,
+ * e.g., example.com/user/123. 123 being the users ID.
+ *
+ * Use 'content' to print all content, or print a subset
+ * such as 'content.field_example'.
+ * By default, $user_profile['summary'] is provided, which contains data on the
+ * user's history. Other data can be included by modules.
+ *
+ * Available variables:
+ * - content: A list of content items.
+ * - Field variables: for each field instance attached to the user a
+ * corresponding variable is defined; e.g., account.field_example has a
+ * variable 'field_example' defined. When needing to access a field's raw
+ * values, developers/themers are strongly encouraged to use these
+ * variables. Otherwise they will have to explicitly specify the desired
+ * field language, e.g. account.field_example['en'], thus overriding any
+ * language negotiation rule that was previously applied.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_user()
+ *
+ * @ingroup themeable
+ */
+#}
+
+ {% if content is not empty %}
+ {{- content -}}
+ {% endif %}
+
diff --git a/core/modules/user/templates/user.tpl.php b/core/modules/user/templates/user.tpl.php
deleted file mode 100644
index 617d310..0000000
--- a/core/modules/user/templates/user.tpl.php
+++ /dev/null
@@ -1,32 +0,0 @@
-field_example has a
- * variable $field_example defined. When needing to access a field's raw
- * values, developers/themers are strongly encouraged to use these
- * variables. Otherwise they will have to explicitly specify the desired
- * field language, e.g. $account->field_example['en'], thus overriding any
- * language negotiation rule that was previously applied.
- *
- * @see template_preprocess_user()
- *
- * @ingroup themeable
- */
-?>
->
-
-
diff --git a/core/modules/user/templates/username.html.twig b/core/modules/user/templates/username.html.twig
new file mode 100644
index 0000000..4524dba
--- /dev/null
+++ b/core/modules/user/templates/username.html.twig
@@ -0,0 +1,32 @@
+{#
+/**
+ * @file
+ * Default theme implementation for displaying a username.
+ *
+ * Available variables:
+ * - account: The user object to format.
+ * - name: The user's name, sanitized.
+ * - extra: Additional text to append to the user's name, sanitized.
+ * - link: The fully generated link by l if a link_path is set
+ * - link_path: The path or URL of the user's profile page, home page,
+ * or other desired page to link to for more information about the user.
+ * - link_options: An array of options to pass to the l() function's $options
+ * parameter if linking the user's name to the user's page.
+ * - attributes: An array of attributes if not linking to the user's page.
+ *
+ * @see template_preprocess()
+ * @see template_preprocess_username()
+ *
+ * @ingroup themeable
+ */
+#}
+{% if link %}
+ {{- link -}}
+{% else %}
+ {#
+ Modules may have added important attributes so they must be included
+ in the output. Additional classes may be added as array elements like
+ {% set attributes.class = attributes.class|merge(["myclass"]) %}
+ #}
+ {{ name }}{{ extra }}
+{% endif %}
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index c3931d8..aee6ea1 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -818,9 +818,11 @@ function theme_user_admin_permissions($variables) {
}
/**
- * Returns HTML for an individual permission description.
+ * Default theme implementation for an individual permission description.
*
- * @param $variables
+ * Default template: user-permission-description.html.twig.
+ *
+ * @param array $variables
* An associative array containing:
* - permission_item: An associative array representing the permission whose
* description is being themed. Useful keys include:
@@ -829,22 +831,14 @@ function theme_user_admin_permissions($variables) {
* there is one).
* - hide: A boolean indicating whether or not the permission description was
* requested to be hidden rather than shown.
- *
- * @ingroup themeable
*/
-function theme_user_permission_description($variables) {
- if (!$variables['hide']) {
- $description = array();
- $permission_item = $variables['permission_item'];
- if (!empty($permission_item['description'])) {
- $description[] = $permission_item['description'];
- }
- if (!empty($permission_item['warning'])) {
- $description[] = '' . $permission_item['warning'] . '';
- }
- if (!empty($description)) {
- return implode(' ', $description);
- }
+function template_preprocess_user_permission_description(&$variables) {
+ $permission_item = $variables['permission_item'];
+ if (!empty($permission_item['description'])) {
+ $variables['description'] = $permission_item['description'];
+ }
+ if (!empty($permission_item['warning'])) {
+ $variables['warning'] = $permission_item['warning'];
}
}
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index bdf5862..3445c10 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -92,8 +92,8 @@ function user_theme() {
return array(
'user' => array(
'render element' => 'elements',
- 'template' => 'user',
'file' => 'user.pages.inc',
+ 'template' => 'user',
),
'user_admin_permissions' => array(
'render element' => 'form',
@@ -106,12 +106,15 @@ function user_theme() {
'user_permission_description' => array(
'variables' => array('permission_item' => NULL, 'hide' => NULL),
'file' => 'user.admin.inc',
+ 'template' => 'user-permission-description',
),
'user_signature' => array(
'variables' => array('signature' => NULL),
+ 'template' => 'user-signature',
),
'username' => array(
'variables' => array('account' => NULL),
+ 'template' => 'username',
),
);
}
@@ -728,13 +731,19 @@ function user_template_preprocess_default_variables_alter(&$variables) {
}
/**
- * Preprocesses variables for theme_username().
+ * Preprocesses variables for username.
+ *
+ * Default template: username.html.twig.
+ *
+ * @param array $variables
+ * An associative array containing:
+ * - account: The user account to check access for
+ * (Drupal\user\Plugin\Core\Entity\User).
+ * - uid: The user uid number.
*
* Modules that make any changes to variables like 'name' or 'extra' must insure
* that the final string is safe to include directly in the output by using
* check_plain() or filter_xss().
- *
- * @see template_process_username()
*/
function template_preprocess_username(&$variables) {
$account = $variables['account'];
@@ -779,18 +788,8 @@ function template_preprocess_username(&$variables) {
// We do not want the l() function to check_plain() a second time.
$variables['link_options']['html'] = TRUE;
// Set a default class.
- $variables['attributes'] = array('class' => array('username'));
-}
+ $variables['attributes'] = new Attribute(array('class' => array('username')));
-/**
- * Processes variables for theme_username().
- *
- * @see template_preprocess_username()
- */
-function template_process_username(&$variables) {
- // Finalize the link_options array for passing to the l() function.
- // This is done in the process phase so that attributes may be added by
- // modules or the theme during the preprocess phase.
if (isset($variables['link_path'])) {
// $variables['attributes'] contains attributes that should be applied
// regardless of whether a link is being rendered or not.
@@ -802,42 +801,15 @@ function template_process_username(&$variables) {
// This purposefully does not use
// \Drupal\Component\Utility\NestedArray::mergeDeep() for performance
// reasons, since it is potentially called very often.
- $variables['link_options']['attributes'] = array_merge_recursive($variables['link_attributes'], $variables['attributes']);
- }
-}
-
-/**
- * Returns HTML for a username, potentially linked to the user's page.
- *
- * @param $variables
- * An associative array containing:
- * - account: The user object to format.
- * - name: The user's name, sanitized.
- * - extra: Additional text to append to the user's name, sanitized.
- * - link_path: The path or URL of the user's profile page, home page, or
- * other desired page to link to for more information about the user.
- * - link_options: An array of options to pass to the l() function's $options
- * parameter if linking the user's name to the user's page.
- * - attributes: An array of attributes to instantiate the
- * Drupal\Core\Template\Attribute class if not linking to the user's page.
- *
- * @see template_preprocess_username()
- * @see template_process_username()
- */
-function theme_username($variables) {
- if (isset($variables['link_path'])) {
- // We have a link path, so we should generate a link using l().
- // Additional classes may be added as array elements like
- // $variables['link_options']['attributes']['class'][] = 'myclass';
- $output = l($variables['name'] . $variables['extra'], $variables['link_path'], $variables['link_options']);
- }
- else {
- // Modules may have added important attributes so they must be included
- // in the output. Additional classes may be added as array elements like
- // $variables['attributes']['class'][] = 'myclass';
- $output = '' . $variables['name'] . $variables['extra'] . '';
+ $attributes = (array) $variables['attributes'];
+ $variables['link_options']['attributes'] = new Attribute(array_merge_recursive($variables['link_attributes'], $attributes));
+ $variables['link'] = array(
+ '#theme' => 'link',
+ '#text' => $variables['name'] . $variables['extra'],
+ '#path' => $variables['link_path'],
+ '#options' => $variables['link_options'],
+ );
}
- return $output;
}
/**
@@ -1688,7 +1660,7 @@ function user_view_page($account) {
* - $page['content']['#user']:
* The user account of the profile being viewed.
*
- * To theme user profiles, copy modules/user/user.tpl.php
+ * To theme user profiles, copy modules/user/templates/user.html.twig
* to your theme directory, and edit it as instructed in that file's comments.
*
* @param $account
@@ -2294,26 +2266,16 @@ function user_build_filter_query(SelectInterface $query) {
}
/**
- * Returns HTML for a user signature.
+ * Preprocess variables for user signature templates.
+ *
+ * Default template: user-signature.html.twig.
*
- * @param $variables
+ * @param array $variables
* An associative array containing:
* - signature: The user's signature.
- *
- * @ingroup themeable
*/
-function theme_user_signature($variables) {
- $signature = $variables['signature'];
- $output = '';
-
- if ($signature) {
- $output .= '';
- $output .= '
—
';
- $output .= $signature;
- $output .= '
';
- }
-
- return $output;
+function template_preprocess_user_signature(&$variables) {
+ $variables['attributes'] = new Attribute(array('class' => array('clear')));
}
/**
diff --git a/core/modules/user/user.pages.inc b/core/modules/user/user.pages.inc
index 140b767..590d65a 100644
--- a/core/modules/user/user.pages.inc
+++ b/core/modules/user/user.pages.inc
@@ -5,6 +5,7 @@
* User page callback file for the user module.
*/
+use Drupal\Core\Template\Attribute;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
@@ -175,12 +176,14 @@ function user_logout() {
}
/**
- * Process variables for user.tpl.php.
+ * Prepares variables for user template.
*
- * The $variables array contains the following arguments:
- * - $account
+ * Default template: user.html.twig.
*
- * @see user.tpl.php
+ * @param array $variables
+ * An associative array containing:
+ * - account: The user account to check access for
+ * (Drupal\user\Plugin\Core\Entity\User).
*/
function template_preprocess_user(&$variables) {
$account = $variables['elements']['#user'];
@@ -192,6 +195,10 @@ function template_preprocess_user(&$variables) {
// Preprocess fields.
field_attach_preprocess($account, $variables['elements'], $variables);
+
+ // Set up attributes.
+ $variables['attributes'] = array('class' => array('profile'));
+ $variables['attributes'] = new Attribute($variables['attributes']);
}
/**
diff --git a/core/tests/Drupal/Tests/Component/Utility/TimerUnitTest.php b/core/tests/Drupal/Tests/Component/Utility/TimerUnitTest.php
deleted file mode 100644
index 7da8b99..0000000
--- a/core/tests/Drupal/Tests/Component/Utility/TimerUnitTest.php
+++ /dev/null
@@ -1,57 +0,0 @@
- 'Timer test',
- 'description' => 'Test that Timer::read() works both when a timer is running and when a timer is stopped.',
- 'group' => 'Bootstrap',
- );
- }
-
- /**
- * Tests Timer::read() time accumulation accuracy across multiple restarts.
- *
- * @see Drupal\Component\Utility\Timer::read()
- */
- public function testTimer() {
- Timer::start('test');
- usleep(5000);
- $value = Timer::read('test');
- usleep(5000);
- $value2 = Timer::read('test');
- usleep(5000);
- $value3 = Timer::read('test');
- usleep(5000);
- $value4 = Timer::read('test');
-
- $this->assertGreaterThanOrEqual(5, $value, 'Timer measured 5 milliseconds of sleeping while running.');
- $this->assertLessThan(10, $value, 'Timer measured 5 milliseconds of sleeping while running.');
-
- $this->assertGreaterThanOrEqual(10, $value2, 'Timer measured 10 milliseconds of sleeping while running.');
- $this->assertLessThan(15, $value2, 'Timer measured 10 milliseconds of sleeping while running.');
-
- $this->assertGreaterThanOrEqual(15, $value3, 'Timer measured 15 milliseconds of sleeping while running.');
- $this->assertLessThan(20, $value3, 'Timer measured 15 milliseconds of sleeping while running.');
-
- $this->assertGreaterThanOrEqual(20, $value4, 'Timer measured 20 milliseconds of sleeping while running.');
- $this->assertLessThan(25, $value4, 'Timer measured 20 milliseconds of sleeping while running.');
- }
-
-}