summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2014-05-22 09:38:46 (GMT)
committerNathaniel Catchpole2014-05-22 09:38:46 (GMT)
commite44d15a76dccc388db9e2d883c78bad91fe03783 (patch)
treefa95aecf6fefff021290ce764d45d20be82f778a
parent85d39d8403399fc0a17d993ec9e28ccb6c3b2bb7 (diff)
Issue #1289536 by ParisLiakos, RobLoach, Crell, larowlan, fgm, pounard, Pancho, dawehner, scor, tim.plunkett, alexpott, socketwench: Switch Watchdog to a PSR-3 logging framework.
-rw-r--r--core/authorize.php2
-rw-r--r--core/core.services.yml20
-rw-r--r--core/includes/bootstrap.inc56
-rw-r--r--core/lib/Drupal.php14
-rw-r--r--core/lib/Drupal/Core/Controller/ControllerResolver.php4
-rw-r--r--core/lib/Drupal/Core/Controller/ExceptionController.php4
-rw-r--r--core/lib/Drupal/Core/Form/FormValidator.php2
-rw-r--r--core/lib/Drupal/Core/Logger/LogMessageParser.php46
-rw-r--r--core/lib/Drupal/Core/Logger/LogMessageParserInterface.php39
-rw-r--r--core/lib/Drupal/Core/Logger/LoggerChannel.php158
-rw-r--r--core/lib/Drupal/Core/Logger/LoggerChannelFactory.php74
-rw-r--r--core/lib/Drupal/Core/Logger/LoggerChannelFactoryInterface.php40
-rw-r--r--core/lib/Drupal/Core/Logger/LoggerChannelInterface.php53
-rw-r--r--core/lib/Drupal/Core/Routing/UrlGenerator.php4
-rw-r--r--core/modules/config/lib/Drupal/config/Form/ConfigSync.php2
-rw-r--r--core/modules/dblog/dblog.module26
-rw-r--r--core/modules/dblog/dblog.services.yml6
-rw-r--r--core/modules/dblog/lib/Drupal/dblog/Logger/DbLog.php76
-rw-r--r--core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php8
-rw-r--r--core/modules/filter/lib/Drupal/filter/Tests/FilterSettingsTest.php2
-rw-r--r--core/modules/rest/lib/Drupal/rest/Tests/DBLogTest.php6
-rw-r--r--core/modules/syslog/lib/Drupal/syslog/Logger/SysLog.php96
-rw-r--r--core/modules/syslog/syslog.module33
-rw-r--r--core/modules/syslog/syslog.services.yml6
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiInfoTest.php4
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Pager/PagerTest.php2
-rw-r--r--core/modules/system/system.api.php88
-rw-r--r--core/modules/system/tests/modules/entity_cache_test/entity_cache_test.module16
-rw-r--r--core/modules/user/user.services.yml5
-rw-r--r--core/tests/Drupal/Tests/Core/EventSubscriber/SpecialAttributesRouteSubscriberTest.php2
-rw-r--r--core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php1
-rw-r--r--core/tests/Drupal/Tests/Core/Logger/LogMessageParserTest.php93
-rw-r--r--core/tests/Drupal/Tests/Core/Logger/LoggerChannelFactoryTest.php66
-rw-r--r--core/tests/Drupal/Tests/Core/Logger/LoggerChannelTest.php158
-rw-r--r--core/update.php2
35 files changed, 981 insertions, 233 deletions
diff --git a/core/authorize.php b/core/authorize.php
index f2da377..f938f39 100644
--- a/core/authorize.php
+++ b/core/authorize.php
@@ -147,7 +147,7 @@ if (authorize_access_allowed()) {
}
else {
drupal_add_http_header('Status', '403 Forbidden');
- watchdog('access denied', 'authorize.php', NULL, WATCHDOG_WARNING);
+ watchdog('access denied', 'authorize.php', array(), WATCHDOG_WARNING);
$page_title = t('Access denied');
$output = t('You are not allowed to access this page.');
}
diff --git a/core/core.services.yml b/core/core.services.yml
index 92b5f7c..c4b55ac 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -142,6 +142,18 @@ services:
arguments: ['@serialization.phpserialize', '@database']
tags:
- { name: needs_destruction }
+ logger.factory:
+ class: Drupal\Core\Logger\LoggerChannelFactory
+ parent: container.trait
+ tags:
+ - { name: service_collector, tag: logger, call: addLogger }
+ logger.channel.default:
+ class: Drupal\Core\Logger\LoggerChannel
+ factory_method: get
+ factory_service: logger.factory
+ arguments: ['system']
+ logger.log_message_parser:
+ class: Drupal\Core\Logger\LogMessageParser
serialization.json:
class: Drupal\Component\Serialization\Json
@@ -258,6 +270,7 @@ services:
arguments: ['@service_container']
controller_resolver:
class: Drupal\Core\Controller\ControllerResolver
+ arguments: ['@logger.channel.default']
parent: container.trait
title_resolver:
class: Drupal\Core\Controller\TitleResolver
@@ -330,7 +343,7 @@ services:
- { name: service_collector, tag: route_filter, call: addRouteFilter }
url_generator:
class: Drupal\Core\Routing\UrlGenerator
- arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@config.factory', '@settings']
+ arguments: ['@router.route_provider', '@path_processor_manager', '@route_processor_manager', '@config.factory', '@settings', '@logger.channel.default']
calls:
- [setRequest, ['@?request']]
- [setContext, ['@?router.request_context']]
@@ -752,11 +765,6 @@ services:
- { name: needs_destruction }
authentication:
class: Drupal\Core\Authentication\AuthenticationManager
- authentication.cookie:
- class: Drupal\Core\Authentication\Provider\Cookie
- arguments: ['@session_manager']
- tags:
- - { name: authentication_provider, priority: 0 }
authentication_subscriber:
class: Drupal\Core\EventSubscriber\AuthenticationSubscriber
tags:
diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index d33d1ee..ac20992 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -1137,58 +1137,18 @@ function watchdog_exception($type, Exception $exception, $message = NULL, $varia
* @param $link
* A link to associate with the message.
*
+ * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
+ * Use \Drupal::logger($channel)->log($severity, $message, $context), or any
+ * of the shortcut methods of \Psr\Log\LoggerTrait.
+ *
* @see watchdog_severity_levels()
* @see hook_watchdog()
*/
-function watchdog($type, $message, array $variables = NULL, $severity = WATCHDOG_NOTICE, $link = NULL) {
- global $user, $base_root;
-
- static $in_error_state = FALSE;
-
- // It is possible that the error handling will itself trigger an error. In that case, we could
- // end up in an infinite loop. To avoid that, we implement a simple static semaphore.
- if (!$in_error_state && \Drupal::hasService('module_handler')) {
- $in_error_state = TRUE;
-
- // The user object may not exist in all conditions, so 0 is substituted if needed.
- $user_uid = isset($user) ? $user->id() : 0;
-
- // Prepare the fields to be logged
- $log_entry = array(
- 'type' => $type,
- 'message' => $message,
- 'variables' => $variables,
- 'severity' => $severity,
- 'link' => $link,
- 'user' => $user,
- 'uid' => $user_uid,
- 'request_uri' => '',
- 'referer' => '',
- 'ip' => '',
- // Request time isn't accurate for long processes, use time() instead.
- 'timestamp' => time(),
- );
-
- try {
- $request = \Drupal::request();
- $log_entry['request_uri'] = $request->getUri();
- $log_entry['referer'] = $request->headers->get('Referer', '');
- $log_entry['ip'] = $request->getClientIP();
- }
- catch (DependencyInjectionRuntimeException $e) {
- // We are not in a request context.
- }
-
- // Call the logging hooks to log/process the message
- foreach (\Drupal::moduleHandler()->getImplementations('watchdog') as $module) {
- $function = $module . '_watchdog';
- $function($log_entry);
- }
-
- // It is critical that the semaphore is only cleared here, in the parent
- // watchdog() call (not outside the loop), to prevent recursive execution.
- $in_error_state = FALSE;
+function watchdog($type, $message, array $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) {
+ if ($link) {
+ $variables['link'] = $link;
}
+ \Drupal::service('logger.factory')->get($type)->log($severity, $message, $variables);
}
/**
diff --git a/core/lib/Drupal.php b/core/lib/Drupal.php
index 5c72435..83fe15f 100644
--- a/core/lib/Drupal.php
+++ b/core/lib/Drupal.php
@@ -622,4 +622,18 @@ class Drupal {
return static::$container->get('config.installer')->isSyncing();
}
+ /**
+ * Returns a channel logger object.
+ *
+ * @param string $channel
+ * The name of the channel. Can be any string, but the general practice is
+ * to use the name of the subsystem calling this.
+ *
+ * @return \Drupal\Core\Logger\LoggerChannelInterface
+ * The logger for this channel.
+ */
+ public static function logger($channel) {
+ return static::$container->get('logger.factory')->get($channel);
+ }
+
}
diff --git a/core/lib/Drupal/Core/Controller/ControllerResolver.php b/core/lib/Drupal/Core/Controller/ControllerResolver.php
index c37ed83..c80242c 100644
--- a/core/lib/Drupal/Core/Controller/ControllerResolver.php
+++ b/core/lib/Drupal/Core/Controller/ControllerResolver.php
@@ -7,9 +7,9 @@
namespace Drupal\Core\Controller;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Controller\ControllerResolver as BaseControllerResolver;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\ContainerAwareInterface;
use Symfony\Component\DependencyInjection\ContainerAwareTrait;
@@ -42,7 +42,7 @@ class ControllerResolver extends BaseControllerResolver implements ControllerRes
/**
* Constructs a new ControllerResolver.
*
- * @param \Symfony\Component\HttpKernel\Log\LoggerInterface $logger
+ * @param \Psr\Log\LoggerInterface $logger
* (optional) A LoggerInterface instance.
*/
public function __construct(LoggerInterface $logger = NULL) {
diff --git a/core/lib/Drupal/Core/Controller/ExceptionController.php b/core/lib/Drupal/Core/Controller/ExceptionController.php
index f95930b..320cb06 100644
--- a/core/lib/Drupal/Core/Controller/ExceptionController.php
+++ b/core/lib/Drupal/Core/Controller/ExceptionController.php
@@ -143,7 +143,7 @@ class ExceptionController extends HtmlControllerBase implements ContainerAwareIn
*/
public function on403Html(FlattenException $exception, Request $request) {
$system_path = $request->attributes->get('_system_path');
- watchdog('access denied', $system_path, NULL, WATCHDOG_WARNING);
+ watchdog('access denied', $system_path, array(), WATCHDOG_WARNING);
$system_config = $this->container->get('config.factory')->get('system.site');
$path = $this->container->get('path.alias_manager')->getPathByAlias($system_config->get('page.403'));
@@ -185,7 +185,7 @@ class ExceptionController extends HtmlControllerBase implements ContainerAwareIn
* A response object.
*/
public function on404Html(FlattenException $exception, Request $request) {
- watchdog('page not found', String::checkPlain($request->attributes->get('_system_path')), NULL, WATCHDOG_WARNING);
+ watchdog('page not found', String::checkPlain($request->attributes->get('_system_path')), array(), WATCHDOG_WARNING);
// Check for and return a fast 404 page if configured.
$config = \Drupal::config('system.performance');
diff --git a/core/lib/Drupal/Core/Form/FormValidator.php b/core/lib/Drupal/Core/Form/FormValidator.php
index 9e73738..eda8238 100644
--- a/core/lib/Drupal/Core/Form/FormValidator.php
+++ b/core/lib/Drupal/Core/Form/FormValidator.php
@@ -502,7 +502,7 @@ class FormValidator implements FormValidatorInterface {
/**
* Wraps watchdog().
*/
- protected function watchdog($type, $message, array $variables = NULL, $severity = WATCHDOG_NOTICE, $link = NULL) {
+ protected function watchdog($type, $message, array $variables = array(), $severity = WATCHDOG_NOTICE, $link = NULL) {
watchdog($type, $message, $variables, $severity, $link);
}
diff --git a/core/lib/Drupal/Core/Logger/LogMessageParser.php b/core/lib/Drupal/Core/Logger/LogMessageParser.php
new file mode 100644
index 0000000..ba99129
--- /dev/null
+++ b/core/lib/Drupal/Core/Logger/LogMessageParser.php
@@ -0,0 +1,46 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Logger\LogMessageParser.
+ */
+
+namespace Drupal\Core\Logger;
+
+/**
+ * Parses log messages and their placeholders.
+ */
+class LogMessageParser implements LogMessageParserInterface {
+
+ /**
+ * {@inheritdoc}
+ */
+ public function parseMessagePlaceholders(&$message, array &$context) {
+ $variables = array();
+ $has_psr3 = FALSE;
+ if (($start = strpos($message, '{')) !== FALSE && strpos($message, '}') > $start) {
+ $has_psr3 = TRUE;
+ // Transform PSR3 style messages containing placeholders to
+ // \Drupal\Component\Utility\String::format() style.
+ $message = preg_replace('/\{(.*)\}/U', '@$1', $message);
+ }
+ foreach ($context as $key => $variable) {
+ // PSR3 style placeholders.
+ if ($has_psr3) {
+ // Keys are not prefixed with anything according to PSR3 specs.
+ // If the message is "User {username} created" the variable key will be
+ // just "username".
+ if (strpos($message, '@' . $key) !== FALSE) {
+ $key = '@' . $key;
+ }
+ }
+ if (!empty($key) && ($key[0] === '@' || $key[0] === '%' || $key[0] === '!')) {
+ // The key is now in \Drupal\Component\Utility\String::format() style.
+ $variables[$key] = $variable;
+ }
+ }
+
+ return $variables;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Logger/LogMessageParserInterface.php b/core/lib/Drupal/Core/Logger/LogMessageParserInterface.php
new file mode 100644
index 0000000..545b039
--- /dev/null
+++ b/core/lib/Drupal/Core/Logger/LogMessageParserInterface.php
@@ -0,0 +1,39 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Logger\LogMessageParserInterface.
+ */
+
+namespace Drupal\Core\Logger;
+
+/**
+ * Defines an interface for parsing log messages and their placeholders.
+ */
+interface LogMessageParserInterface {
+
+ /**
+ * Parses and transforms message and its placeholders to a common format.
+ *
+ * For a value to be considered as a placeholder should be in the following
+ * formats:
+ * - PSR3 format:
+ * @see https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-3-logger-interface.md#12-message
+ * - Drupal specific string placeholder format:
+ * @see \Drupal\Component\Utility\String::format()
+ *
+ * Values in PSR3 format will be transformed to String::format() format.
+ *
+ * @param string $message
+ * The message that contains the placeholders.
+ * If the message is in PSR3 style, it will be transformed to
+ * \Drupal\Component\Utility\String::format() style.
+ * @param array $context
+ * An array that may or may not contain placeholder variables.
+ *
+ * @return array
+ * An array of the extracted message placeholders.
+ */
+ public function parseMessagePlaceholders(&$message, array &$context);
+
+}
diff --git a/core/lib/Drupal/Core/Logger/LoggerChannel.php b/core/lib/Drupal/Core/Logger/LoggerChannel.php
new file mode 100644
index 0000000..074cd23
--- /dev/null
+++ b/core/lib/Drupal/Core/Logger/LoggerChannel.php
@@ -0,0 +1,158 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Logger\LoggerChannel.
+ */
+
+namespace Drupal\Core\Logger;
+
+use Drupal\Core\Session\AccountInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LoggerTrait;
+use Psr\Log\LogLevel;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines a logger channel that most implementations will use.
+ */
+class LoggerChannel implements LoggerChannelInterface {
+ use LoggerTrait;
+
+ /**
+ * The name of the channel of this logger instance.
+ *
+ * @var string
+ */
+ protected $channel;
+
+ /**
+ * Map of PSR Log constants to Watchdog log constants.
+ *
+ * @todo Move watchdog constants here when watchdog() is removed.
+ *
+ * @var array
+ */
+ protected $levelTranslation = array(
+ LogLevel::EMERGENCY => WATCHDOG_EMERGENCY,
+ LogLevel::ALERT => WATCHDOG_ALERT,
+ LogLevel::CRITICAL => WATCHDOG_CRITICAL,
+ LogLevel::ERROR => WATCHDOG_ERROR,
+ LogLevel::WARNING => WATCHDOG_WARNING,
+ LogLevel::NOTICE => WATCHDOG_NOTICE,
+ LogLevel::INFO => WATCHDOG_INFO,
+ LogLevel::DEBUG => WATCHDOG_DEBUG,
+ );
+
+ /**
+ * An array of arrays of \Psr\Log\LoggerInterface keyed by priority.
+ *
+ * @var array
+ */
+ protected $loggers = array();
+
+ /**
+ * The request object.
+ *
+ * @var \Symfony\Component\HttpFoundation\Request
+ */
+ protected $request;
+
+ /**
+ * The current user object.
+ *
+ * @var \Drupal\Core\Session\AccountInterface
+ */
+ protected $currentUser;
+
+ /**
+ * Constructs a LoggerChannel object
+ *
+ * @param string $channel
+ * The channel name for this instance.
+ */
+ public function __construct($channel) {
+ $this->channel = $channel;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function log($level, $message, array $context = array()) {
+ // Merge in defaults.
+ $context += array(
+ 'channel' => $this->channel,
+ 'link' => '',
+ 'user' => NULL,
+ 'uid' => 0,
+ 'request_uri' => '',
+ 'referer' => '',
+ 'ip' => '',
+ 'timestamp' => time(),
+ );
+ if ($this->currentUser) {
+ $context['user'] = $this->currentUser;
+ $context['uid'] = $this->currentUser->id();
+ }
+ // Some context values are only available when in a request context.
+ if ($this->request) {
+ $context['request_uri'] = $this->request->getUri();
+ $context['referer'] = $this->request->headers->get('Referer', '');
+ $context['ip'] = $this->request->getClientIP();
+ }
+
+ if (is_string($level)) {
+ // Convert to integer equivalent for consistency with RFC 3164.
+ $level = $this->levelTranslation[$level];
+ }
+ // Call all available loggers.
+ foreach ($this->sortLoggers() as $logger) {
+ $logger->log($level, $message, $context);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setRequest(Request $request = NULL) {
+ $this->request = $request;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setCurrentUser(AccountInterface $current_user = NULL) {
+ $this->currentUser = $current_user;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function setLoggers(array $loggers) {
+ $this->loggers = $loggers;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addLogger(LoggerInterface $logger, $priority = 0) {
+ $this->loggers[$priority][] = $logger;
+ }
+
+ /**
+ * Sorts loggers according to priority.
+ *
+ * @return array
+ * An array of sorted loggers by priority.
+ */
+ protected function sortLoggers() {
+ $sorted = array();
+ krsort($this->loggers);
+
+ foreach ($this->loggers as $loggers) {
+ $sorted = array_merge($sorted, $loggers);
+ }
+ return $sorted;
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Logger/LoggerChannelFactory.php b/core/lib/Drupal/Core/Logger/LoggerChannelFactory.php
new file mode 100644
index 0000000..1ec1710
--- /dev/null
+++ b/core/lib/Drupal/Core/Logger/LoggerChannelFactory.php
@@ -0,0 +1,74 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Logger\LoggerChannelFactory.
+ */
+
+namespace Drupal\Core\Logger;
+
+use Psr\Log\LoggerInterface;
+use Symfony\Component\DependencyInjection\ContainerAwareInterface;
+use Symfony\Component\DependencyInjection\ContainerAwareTrait;
+use Symfony\Component\DependencyInjection\Exception\RuntimeException;
+
+/**
+ * Defines a factory for logging channels.
+ */
+class LoggerChannelFactory implements LoggerChannelFactoryInterface, ContainerAwareInterface {
+ use ContainerAwareTrait;
+
+ /**
+ * Array of all instantiated logger channels keyed by channel name.
+ *
+ * @var Drupal\Core\Logger\LoggerChannelInterface[]
+ */
+ protected $channels = array();
+
+ /**
+ * An array of arrays of \Psr\Log\LoggerInterface keyed by priority.
+ *
+ * @var array
+ */
+ protected $loggers = array();
+
+ /**
+ * {@inheritdoc}
+ */
+ public function get($channel) {
+ if (!isset($this->channels[$channel])) {
+ $instance = new LoggerChannel($channel);
+
+ // If the service container is set and request is available, set it with
+ // the current user to the channel.
+ if ($this->container) {
+ try {
+ $instance->setRequest($this->container->get('request'));
+ $instance->setCurrentUser($this->container->get('current_user'));
+ }
+ catch (RuntimeException $e) {
+ // We are not in a request context.
+ }
+ }
+
+ // Pass the loggers to the channel.
+ $instance->setLoggers($this->loggers);
+ $this->channels[$channel] = $instance;
+ }
+
+ return $this->channels[$channel];
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function addLogger(LoggerInterface $logger, $priority = 0) {
+ // Store it so we can pass it to potential new logger instances.
+ $this->loggers[$priority][] = $logger;
+ // Add the logger to already instantiated channels.
+ foreach ($this->channels as $channel) {
+ $channel->addLogger($logger, $priority);
+ }
+ }
+
+}
diff --git a/core/lib/Drupal/Core/Logger/LoggerChannelFactoryInterface.php b/core/lib/Drupal/Core/Logger/LoggerChannelFactoryInterface.php
new file mode 100644
index 0000000..67d178c
--- /dev/null
+++ b/core/lib/Drupal/Core/Logger/LoggerChannelFactoryInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Logger\LoggerChannelFactoryInterface.
+ */
+
+namespace Drupal\Core\Logger;
+
+use Psr\Log\LoggerInterface;
+
+/**
+ * Logger channel factory interface.
+ */
+interface LoggerChannelFactoryInterface {
+
+ /**
+ * Retrieves the registered logger for the requested channel.
+ *
+ * @return \Drupal\Core\Logger\LoggerChannelInterface
+ * The registered logger for this channel.
+ */
+ public function get($channel);
+
+ /**
+ * Adds a logger.
+ *
+ * Here is were all services tagged as 'logger' are being retrieved and then
+ * passed to the channels after instantiation.
+ *
+ * @param \Psr\Log\LoggerInterface $logger
+ * The PSR-3 logger to add.
+ * @param int $priority
+ * The priority of the logger being added.
+ *
+ * @see \Drupal\Core\DependencyInjection\Compiler\RegisterLoggersPass
+ */
+ public function addLogger(LoggerInterface $logger, $priority = 0);
+
+}
diff --git a/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php b/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php
new file mode 100644
index 0000000..15d9741
--- /dev/null
+++ b/core/lib/Drupal/Core/Logger/LoggerChannelInterface.php
@@ -0,0 +1,53 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Core\Logger\LoggerChannelInterface.
+ */
+
+namespace Drupal\Core\Logger;
+
+use Drupal\Core\Session\AccountInterface;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Logger channel interface.
+ */
+interface LoggerChannelInterface extends LoggerInterface {
+
+ /**
+ * Sets the request.
+ *
+ * @param \Symfony\Component\HttpFoundation\Request|null $request
+ * The current request object.
+ */
+ public function setRequest(Request $request = NULL);
+
+ /**
+ * Sets the current user.
+ *
+ * @param \Drupal\Core\Session\AccountInterface|null $current_user
+ * The current user object.
+ */
+ public function setCurrentUser(AccountInterface $current_user = NULL);
+
+ /**
+ * Sets the loggers for this channel.
+ *
+ * @param array $loggers
+ * An array of arrays of \Psr\Log\LoggerInterface keyed by priority.
+ */
+ public function setLoggers(array $loggers);
+
+ /**
+ * Adds a logger.
+ *
+ * @param \Psr\Log\LoggerInterface $logger
+ * The PSR-3 logger to add.
+ * @param int $priority
+ * The priority of the logger being added.
+ */
+ public function addLogger(LoggerInterface $logger, $priority = 0);
+
+}
diff --git a/core/lib/Drupal/Core/Routing/UrlGenerator.php b/core/lib/Drupal/Core/Routing/UrlGenerator.php
index dd09330..7028101 100644
--- a/core/lib/Drupal/Core/Routing/UrlGenerator.php
+++ b/core/lib/Drupal/Core/Routing/UrlGenerator.php
@@ -7,8 +7,8 @@
namespace Drupal\Core\Routing;
+use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
-use Symfony\Component\HttpKernel\Log\LoggerInterface;
use Symfony\Component\Routing\Route as SymfonyRoute;
use Symfony\Component\Routing\Exception\RouteNotFoundException;
@@ -88,7 +88,7 @@ class UrlGenerator extends ProviderBasedGenerator implements UrlGeneratorInterfa
* The config factory.
* @param \Drupal\Core\Site\Settings $settings
* The read only settings.
- * @param \Symfony\Component\HttpKernel\Log\LoggerInterface $logger
+ * @param \Psr\Log\LoggerInterface $logger
* An optional logger for recording errors.
*/
public function __construct(RouteProviderInterface $provider, OutboundPathProcessorInterface $path_processor, OutboundRouteProcessorInterface $route_processor, ConfigFactoryInterface $config, Settings $settings, LoggerInterface $logger = NULL) {
diff --git a/core/modules/config/lib/Drupal/config/Form/ConfigSync.php b/core/modules/config/lib/Drupal/config/Form/ConfigSync.php
index 9786fb9..b76e690 100644
--- a/core/modules/config/lib/Drupal/config/Form/ConfigSync.php
+++ b/core/modules/config/lib/Drupal/config/Form/ConfigSync.php
@@ -348,7 +348,7 @@ class ConfigSync extends FormBase {
if (!empty($results['errors'])) {
foreach ($results['errors'] as $error) {
drupal_set_message($error, 'error');
- watchdog('config_sync', $error, NULL, WATCHDOG_ERROR);
+ watchdog('config_sync', $error, array(), WATCHDOG_ERROR);
}
drupal_set_message(\Drupal::translation()->translate('The configuration was imported with errors.'), 'warning');
}
diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module
index 56ce643..1eb61b0 100644
--- a/core/modules/dblog/dblog.module
+++ b/core/modules/dblog/dblog.module
@@ -11,7 +11,6 @@
* @see watchdog()
*/
-use Drupal\Core\Database\Database;
use Symfony\Component\HttpFoundation\Request;
/**
@@ -108,31 +107,6 @@ function _dblog_get_message_types() {
}
/**
- * Implements hook_watchdog().
- *
- * Note: Some values may be truncated to meet database column size restrictions.
- */
-function dblog_watchdog(array $log_entry) {
- // Remove any backtraces since they may contain an unserializable variable.
- unset($log_entry['variables']['backtrace']);
-
- Database::getConnection('default', 'default')->insert('watchdog')
- ->fields(array(
- 'uid' => $log_entry['uid'],
- 'type' => substr($log_entry['type'], 0, 64),
- 'message' => $log_entry['message'],
- 'variables' => serialize($log_entry['variables']),
- 'severity' => $log_entry['severity'],
- 'link' => substr($log_entry['link'], 0, 255),
- 'location' => $log_entry['request_uri'],
- 'referer' => $log_entry['referer'],
- 'hostname' => substr($log_entry['ip'], 0, 128),
- 'timestamp' => $log_entry['timestamp'],
- ))
- ->execute();
-}
-
-/**
* Implements hook_form_FORM_ID_alter() for system_logging_settings().
*/
function dblog_form_system_logging_settings_alter(&$form, $form_state) {
diff --git a/core/modules/dblog/dblog.services.yml b/core/modules/dblog/dblog.services.yml
new file mode 100644
index 0000000..38836e1
--- /dev/null
+++ b/core/modules/dblog/dblog.services.yml
@@ -0,0 +1,6 @@
+services:
+ logger.dblog:
+ class: Drupal\dblog\Logger\DbLog
+ arguments: ['@database', '@logger.log_message_parser']
+ tags:
+ - { name: logger }
diff --git a/core/modules/dblog/lib/Drupal/dblog/Logger/DbLog.php b/core/modules/dblog/lib/Drupal/dblog/Logger/DbLog.php
new file mode 100644
index 0000000..14916b3
--- /dev/null
+++ b/core/modules/dblog/lib/Drupal/dblog/Logger/DbLog.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\dblog\Logger\DbLog.
+ */
+
+namespace Drupal\dblog\Logger;
+
+use Drupal\Core\Database\Connection;
+use Drupal\Core\Logger\LogMessageParserInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LoggerTrait;
+
+/**
+ * Logs events in the watchdog database table.
+ */
+class DbLog implements LoggerInterface {
+ use LoggerTrait;
+
+ /**
+ * The database connection object.
+ *
+ * @var \Drupal\Core\Database\Connection
+ */
+ protected $database;
+
+ /**
+ * The message's placeholders parser.
+ *
+ * @var \Drupal\Core\Logger\LogMessageParserInterface
+ */
+ protected $parser;
+
+ /**
+ * Constructs a DbLog object.
+ *
+ * @param \Drupal\Core\Database\Connection $database
+ * The database connection object.
+ * @param \Drupal\Core\Logger\LogMessageParserInterface $parser
+ * The parser to use when extracting message variables.
+ */
+ public function __construct(Connection $database, LogMessageParserInterface $parser) {
+ $this->database = $database;
+ $this->parser = $parser;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function log($level, $message, array $context = array()) {
+ // Remove any backtraces since they may contain an unserializable variable.
+ unset($context['backtrace']);
+
+ // Convert PSR3-style messages to String::format() style, so they can be
+ // translated too in runtime.
+ $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context);
+
+ $this->database
+ ->insert('watchdog')
+ ->fields(array(
+ 'uid' => $context['uid'],
+ 'type' => substr($context['channel'], 0, 64),
+ 'message' => $message,
+ 'variables' => serialize($message_placeholders),
+ 'severity' => $level,
+ 'link' => substr($context['link'], 0, 255),
+ 'location' => $context['request_uri'],
+ 'referer' => $context['referer'],
+ 'hostname' => substr($context['ip'], 0, 128),
+ 'timestamp' => $context['timestamp'],
+ ))
+ ->execute();
+ }
+
+}
diff --git a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php
index 5b93c34..84c05cf 100644
--- a/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php
+++ b/core/modules/dblog/lib/Drupal/dblog/Tests/DbLogTest.php
@@ -130,7 +130,7 @@ class DbLogTest extends WebTestBase {
// Prepare the fields to be logged
$log = array(
- 'type' => $type,
+ 'channel' => $type,
'message' => 'Log entry added to test the dblog row limit.',
'variables' => array(),
'severity' => $severity,
@@ -145,7 +145,7 @@ class DbLogTest extends WebTestBase {
$message = 'Log entry added to test the dblog row limit. Entry #';
for ($i = 0; $i < $count; $i++) {
$log['message'] = $message . $i;
- dblog_watchdog($log);
+ $this->container->get('logger.dblog')->log($severity, $log['message'], $log);
}
}
@@ -413,7 +413,7 @@ class DbLogTest extends WebTestBase {
// Get a count of how many watchdog entries already exist.
$count = db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField();
$log = array(
- 'type' => 'custom',
+ 'channel' => 'system',
'message' => 'Log entry added to test the doClearTest clear down.',
'variables' => array(),
'severity' => WATCHDOG_NOTICE,
@@ -426,7 +426,7 @@ class DbLogTest extends WebTestBase {
'timestamp' => REQUEST_TIME,
);
// Add a watchdog entry.
- dblog_watchdog($log);
+ $this->container->get('logger.dblog')->log($log['severity'], $log['message'], $log);
// Make sure the table count has actually been incremented.
$this->assertEqual($count + 1, db_query('SELECT COUNT(*) FROM {watchdog}')->fetchField(), format_string('dblog_watchdog() added an entry to the dblog :count', array(':count' => $count)));
// Login the admin user.
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterSettingsTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterSettingsTest.php
index a11db5d..f37d48b 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterSettingsTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterSettingsTest.php
@@ -34,13 +34,11 @@ class FilterSettingsTest extends DrupalUnitTestBase {
*/
function testFilterDefaults() {
$filter_info = $this->container->get('plugin.manager.filter')->getDefinitions();
- $filters = array_fill_keys(array_keys($filter_info), array());
// Create text format using filter default settings.
$filter_defaults_format = entity_create('filter_format', array(
'format' => 'filter_defaults',
'name' => 'Filter defaults',
- 'filters' => $filters,
));
$filter_defaults_format->save();
diff --git a/core/modules/rest/lib/Drupal/rest/Tests/DBLogTest.php b/core/modules/rest/lib/Drupal/rest/Tests/DBLogTest.php
index b4f1779..ca3806e 100644
--- a/core/modules/rest/lib/Drupal/rest/Tests/DBLogTest.php
+++ b/core/modules/rest/lib/Drupal/rest/Tests/DBLogTest.php
@@ -41,9 +41,9 @@ class DBLogTest extends RESTTestBase {
*/
public function testWatchdog() {
// Write a log message to the DB.
- watchdog('rest_test', 'Test message');
+ watchdog('rest', 'Test message');
// Get the ID of the written message.
- $id = db_query_range("SELECT wid FROM {watchdog} WHERE type = :type ORDER BY wid DESC", 0, 1, array(':type' => 'rest_test'))
+ $id = db_query_range("SELECT wid FROM {watchdog} WHERE type = :type ORDER BY wid DESC", 0, 1, array(':type' => 'rest'))
->fetchField();
// Create a user account that has the required permissions to read
@@ -56,7 +56,7 @@ class DBLogTest extends RESTTestBase {
$this->assertHeader('content-type', $this->defaultMimeType);
$log = Json::decode($response);
$this->assertEqual($log['wid'], $id, 'Log ID is correct.');
- $this->assertEqual($log['type'], 'rest_test', 'Type of log message is correct.');
+ $this->assertEqual($log['type'], 'rest', 'Type of log message is correct.');
$this->assertEqual($log['message'], 'Test message', 'Log message text is correct.');
// Request an unknown log entry.
diff --git a/core/modules/syslog/lib/Drupal/syslog/Logger/SysLog.php b/core/modules/syslog/lib/Drupal/syslog/Logger/SysLog.php
new file mode 100644
index 0000000..8dbb618
--- /dev/null
+++ b/core/modules/syslog/lib/Drupal/syslog/Logger/SysLog.php
@@ -0,0 +1,96 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\syslog\Logger\SysLog.
+ */
+
+namespace Drupal\syslog\Logger;
+
+use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\Logger\LogMessageParserInterface;
+use Psr\Log\LoggerInterface;
+use Psr\Log\LoggerTrait;
+
+/**
+ * Redirects logging messages to syslog.
+ */
+class SysLog implements LoggerInterface {
+ use LoggerTrait;
+
+ /**
+ * A configuration object containin syslog settings.
+ *
+ * @var \Drupal\Core\Config\Config
+ */
+ protected $config;
+
+ /**
+ * The message's placeholders parser.
+ *
+ * @var \Drupal\Core\Logger\LogMessageParserInterface
+ */
+ protected $parser;
+
+ /**
+ * Stores whether there is a system logger connection opened or not.
+ *
+ * @var bool
+ */
+ protected $connectionOpened = FALSE;
+
+ /**
+ * Constructs a SysLog object.
+ *
+ * @param \Drupal\Core\Config\ConfigFactory $config_factory
+ * The configuration factory object.
+ * @param \Drupal\Core\Logger\LogMessageParserInterface $parser
+ * The parser to use when extracting message variables.
+ */
+ public function __construct(ConfigFactory $config_factory, LogMessageParserInterface $parser) {
+ $this->config = $config_factory->get('syslog.settings');
+ $this->parser = $parser;
+ }
+
+ /**
+ * Opens a connection to the system logger.
+ */
+ protected function openConnection() {
+ if (!$this->connectionOpened) {
+ $facility = $this->config->get('facility');
+ if ($facility === '') {
+ $facility = defined('LOG_LOCAL0') ? LOG_LOCAL0 : LOG_USER;
+ }
+ $this->connectionOpened = openlog($this->config->get('identity'), LOG_NDELAY, $facility);
+ }
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function log($level, $message, array $context = array()) {
+ global $base_url;
+
+ // Ensure we have a connection available.
+ $this->openConnection();
+
+ // Populate the message placeholders and then replace them in the message.
+ $message_placeholders = $this->parser->parseMessagePlaceholders($message, $context);
+ $message = empty($message_placeholders) ? $message : strtr($message, $message_placeholders);
+
+ $entry = strtr($this->config->get('format'), array(
+ '!base_url' => $base_url,
+ '!timestamp' => $context['timestamp'],
+ '!type' => $context['channel'],
+ '!ip' => $context['ip'],
+ '!request_uri' => $context['request_uri'],
+ '!referer' => $context['referer'],
+ '!uid' => $context['uid'],
+ '!link' => strip_tags($context['link']),
+ '!message' => strip_tags($message),
+ ));
+
+ syslog($level, $entry);
+ }
+
+}
diff --git a/core/modules/syslog/syslog.module b/core/modules/syslog/syslog.module
index ba54118..aff3d56 100644
--- a/core/modules/syslog/syslog.module
+++ b/core/modules/syslog/syslog.module
@@ -89,36 +89,3 @@ function syslog_facility_list() {
LOG_LOCAL7 => 'LOG_LOCAL7',
);
}
-
-/**
- * Implements hook_watchdog().
- */
-function syslog_watchdog(array $log_entry) {
- global $base_url;
-
- $log_init = &drupal_static(__FUNCTION__, FALSE);
- $config = \Drupal::config('syslog.settings');
-
- if (!$log_init) {
- $log_init = TRUE;
- $facility = $config->get('facility');
- if ($facility === '') {
- $facility = defined('LOG_LOCAL0') ? LOG_LOCAL0 : LOG_USER;
- }
- openlog($config->get('identity'), LOG_NDELAY, $facility);
- }
-
- $message = strtr($config->get('format'), array(
- '!base_url' => $base_url,
- '!timestamp' => $log_entry['timestamp'],
- '!type' => $log_entry['type'],
- '!ip' => $log_entry['ip'],
- '!request_uri' => $log_entry['request_uri'],
- '!referer' => $log_entry['referer'],
- '!uid' => $log_entry['uid'],
- '!link' => strip_tags($log_entry['link']),
- '!message' => strip_tags(!isset($log_entry['variables']) ? $log_entry['message'] : strtr($log_entry['message'], $log_entry['variables'])),
- ));
-
- syslog($log_entry['severity'], $message);
-}
diff --git a/core/modules/syslog/syslog.services.yml b/core/modules/syslog/syslog.services.yml
new file mode 100644
index 0000000..78c7d38
--- /dev/null
+++ b/core/modules/syslog/syslog.services.yml
@@ -0,0 +1,6 @@
+services:
+ logger.syslog:
+ class: Drupal\syslog\Logger\SysLog
+ arguments: ['@config.factory', '@logger.log_message_parser']
+ tags:
+ - { name: logger }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiInfoTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiInfoTest.php
index 712b628..252fb09 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiInfoTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityApiInfoTest.php
@@ -48,9 +48,9 @@ class EntityApiInfoTest extends WebTestBase {
/**
* Tests entity info cache after enabling a module with a dependency on an entity providing module.
*
- * @see entity_cache_test_watchdog()
+ * @see entity_cache_test_modules_enabled()
*/
- function testEntityInfoCacheWatchdog() {
+ function testEntityInfoCacheModulesEnabled() {
\Drupal::moduleHandler()->install(array('entity_cache_test'));
$entity_type = \Drupal::state()->get('entity_cache_test');
$this->assertEqual($entity_type->getLabel(), 'Entity Cache Test', 'Entity info label is correct.');
diff --git a/core/modules/system/lib/Drupal/system/Tests/Pager/PagerTest.php b/core/modules/system/lib/Drupal/system/Tests/Pager/PagerTest.php
index dc8ead4..845aa28 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Pager/PagerTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Pager/PagerTest.php
@@ -36,7 +36,7 @@ class PagerTest extends WebTestBase {
// Insert 300 log messages.
for ($i = 0; $i < 300; $i++) {
- watchdog('pager_test', $this->randomString(), NULL, WATCHDOG_DEBUG);
+ watchdog('pager_test', $this->randomString(), array(), WATCHDOG_DEBUG);
}
$this->admin_user = $this->drupalCreateUser(array(
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index c69838a..15f893f 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1181,94 +1181,6 @@ function hook_template_preprocess_default_variables_alter(&$variables) {
}
/**
- * Log an event message.
- *
- * This hook allows modules to route log events to custom destinations, such as
- * SMS, Email, pager, syslog, ...etc.
- *
- * @param array $log_entry
- * An associative array containing the following keys:
- * - type: The type of message for this entry.
- * - user: The user object for the user who was logged in when the event
- * happened.
- * - uid: The user ID for the user who was logged in when the event happened.
- * - request_uri: The request URI for the page the event happened in.
- * - referer: The page that referred the user to the page where the event
- * occurred.
- * - ip: The IP address where the request for the page came from.
- * - timestamp: The UNIX timestamp of the date/time the event occurred.
- * - severity: The severity of the message; one of the following values as
- * defined in @link http://www.faqs.org/rfcs/rfc3164.html RFC 3164: @endlink
- * - WATCHDOG_EMERGENCY: Emergency, system is unusable.
- * - WATCHDOG_ALERT: Alert, action must be taken immediately.
- * - WATCHDOG_CRITICAL: Critical conditions.
- * - WATCHDOG_ERROR: Error conditions.
- * - WATCHDOG_WARNING: Warning conditions.
- * - WATCHDOG_NOTICE: Normal but significant conditions.
- * - WATCHDOG_INFO: Informational messages.
- * - WATCHDOG_DEBUG: Debug-level messages.
- * - link: An optional link provided by the module that called the watchdog()
- * function.
- * - message: The text of the message to be logged. Variables in the message
- * are indicated by using placeholder strings alongside the variables
- * argument to declare the value of the placeholders. See t() for
- * documentation on how the message and variable parameters interact.
- * - variables: An array of variables to be inserted into the message on
- * display. Will be NULL or missing if a message is already translated or if
- * the message is not possible to translate.
- */
-function hook_watchdog(array $log_entry) {
- global $base_url;
- $language_interface = \Drupal::languageManager()->getCurrentLanguage();
-
- $severity_list = array(
- WATCHDOG_EMERGENCY => t('Emergency'),
- WATCHDOG_ALERT => t('Alert'),
- WATCHDOG_CRITICAL => t('Critical'),
- WATCHDOG_ERROR => t('Error'),
- WATCHDOG_WARNING => t('Warning'),
- WATCHDOG_NOTICE => t('Notice'),
- WATCHDOG_INFO => t('Info'),
- WATCHDOG_DEBUG => t('Debug'),
- );
-
- $to = 'someone@example.com';
- $params = array();
- $params['subject'] = t('[@site_name] @severity_desc: Alert from your web site', array(
- '@site_name' => \Drupal::config('system.site')->get('name'),
- '@severity_desc' => $severity_list[$log_entry['severity']],
- ));
-
- $params['message'] = "\nSite: @base_url";
- $params['message'] .= "\nSeverity: (@severity) @severity_desc";
- $params['message'] .= "\nTimestamp: @timestamp";
- $params['message'] .= "\nType: @type";
- $params['message'] .= "\nIP Address: @ip";
- $params['message'] .= "\nRequest URI: @request_uri";
- $params['message'] .= "\nReferrer URI: @referer_uri";
- $params['message'] .= "\nUser: (@uid) @name";
- $params['message'] .= "\nLink: @link";
- $params['message'] .= "\nMessage: \n\n@message";
-
- $params['message'] = t($params['message'], array(
- '@base_url' => $base_url,
- '@severity' => $log_entry['severity'],
- '@severity_desc' => $severity_list[$log_entry['severity']],
- '@timestamp' => format_date($log_entry['timestamp']),
- '@type' => $log_entry['type'],
- '@ip' => $log_entry['ip'],
- '@request_uri' => $log_entry['request_uri'],
- '@referer_uri' => $log_entry['referer'],
- '@uid' => $log_entry['uid'],
- '@name' => $log_entry['user']->name,
- '@link' => strip_tags($log_entry['link']),
- '@message' => strip_tags($log_entry['message']),
- ));
-
- drupal_mail('emaillog', 'entry', $to, $language_interface->id, $params);
-}
-
-/**
* Prepare a message based on parameters; called from drupal_mail().
*
* Note that hook_mail(), unlike hook_mail_alter(), is only called on the
diff --git a/core/modules/system/tests/modules/entity_cache_test/entity_cache_test.module b/core/modules/system/tests/modules/entity_cache_test/entity_cache_test.module
index 9b28815..f91afde 100644
--- a/core/modules/system/tests/modules/entity_cache_test/entity_cache_test.module
+++ b/core/modules/system/tests/modules/entity_cache_test/entity_cache_test.module
@@ -6,7 +6,7 @@
*/
/**
- * Implements hook_watchdog().
+ * Implements hook_modules_installed().
*
* This hook is called during \Drupal\Core\Extension\ModuleHandler::install()
* and since this hook implementation is invoked, we have to expect that this
@@ -14,13 +14,11 @@
* expect to be able to retrieve the entity information that has been registered
* by the required dependency module.
*
- * @see EnableDisableTestCase::testEntityCache()
+ * @see EntityApiInfoTest::testEntityInfoCacheModulesEnabled()
*/
-function entity_cache_test_watchdog($log_entry) {
- if ($log_entry['type'] == 'system' && $log_entry['message'] == '%module module installed.') {
- $info = \Drupal::entityManager()->getDefinition('entity_cache_test');
- // Store the information in a system variable to analyze it later in the
- // test case.
- \Drupal::state()->set('entity_cache_test', $info);
- }
+function entity_cache_test_modules_installed($modules_enabled) {
+ $info = \Drupal::entityManager()->getDefinition('entity_cache_test');
+ // Store the information in a system variable to analyze it later in the
+ // test case.
+ \Drupal::state()->set('entity_cache_test', $info);
}
diff --git a/core/modules/user/user.services.yml b/core/modules/user/user.services.yml
index 03bb4c2..1e8f9b3 100644
--- a/core/modules/user/user.services.yml
+++ b/core/modules/user/user.services.yml
@@ -15,6 +15,11 @@ services:
class: Drupal\user\Access\LoginStatusCheck
tags:
- { name: access_check, applies_to: _user_is_logged_in }
+ authentication.cookie:
+ class: Drupal\Core\Authentication\Provider\Cookie
+ arguments: ['@session_manager']
+ tags:
+ - { name: authentication_provider, priority: 0 }
cache_context.user:
class: Drupal\user\Cache\UserCacheContext
arguments: ['@current_user']
diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/SpecialAttributesRouteSubscriberTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/SpecialAttributesRouteSubscriberTest.php
index 0bb5006..65ba07d 100644
--- a/core/tests/Drupal/Tests/Core/EventSubscriber/SpecialAttributesRouteSubscriberTest.php
+++ b/core/tests/Drupal/Tests/Core/EventSubscriber/SpecialAttributesRouteSubscriberTest.php
@@ -118,7 +118,7 @@ class SpecialAttributesRouteSubscriberTest extends UnitTestCase {
namespace {
if (!function_exists('watchdog')) {
- function watchdog($type, $message, array $args = NULL) {
+ function watchdog($type, $message, array $args = array()) {
}
}
if (!function_exists('drupal_set_message')) {
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index 8b09681..03ba5eb 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -446,6 +446,7 @@ class TestFormInjected extends TestForm implements ContainerInjectionInterface {
namespace {
function test_form_id_custom_submit(array &$form, array &$form_state) {
}
+ // @todo Remove once watchdog() is removed.
if (!defined('WATCHDOG_ERROR')) {
define('WATCHDOG_ERROR', 3);
}
diff --git a/core/tests/Drupal/Tests/Core/Logger/LogMessageParserTest.php b/core/tests/Drupal/Tests/Core/Logger/LogMessageParserTest.php
new file mode 100644
index 0000000..e30f551
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Logger/LogMessageParserTest.php
@@ -0,0 +1,93 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Logger\LogMessageParserTraitTest
+ */
+
+namespace Drupal\Tests\Core\Logger;
+
+use Drupal\Core\Logger\LogMessageParser;
+use Drupal\Tests\UnitTestCase;
+
+/**
+ * Tests the log message parser.
+ *
+ * @see \Drupal\Core\Logger\LogMessageParser
+ * @coversDefaultClass \Drupal\Core\Logger\LogMessageParser
+ *
+ * @group Drupal
+ * @group Logger
+ */
+class LogMessageParserTest extends UnitTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Log message parser',
+ 'description' => 'Unit tests for the log message parser.',
+ 'group' => 'Logger',
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function setUp() {
+ $this->parser = new LogMessageParser();
+ }
+
+ /**
+ * Test for LogMessageParserTrait::parseMessagePlaceholders()
+ *
+ * @param array $value
+ * An array containing:
+ * - message: A string that contains a message with placeholders.
+ * - context: An array with placeholder values.
+ * @param array $expected
+ * An array with the expected values after the test has run.
+ * - message: The expected parsed message.
+ * - context: The expected values of the placeholders.
+ *
+ * @dataProvider providerTestParseMessagePlaceholders
+ * @covers ::parseMessagePlaceholders
+ */
+ public function testParseMessagePlaceholders(array $value, array $expected) {
+ $message_placeholders = $this->parser->parseMessagePlaceholders($value['message'], $value['context']);
+ $this->assertEquals($expected['message'], $value['message']);
+ $this->assertEquals($expected['context'], $message_placeholders);
+ }
+
+ /**
+ * Data provider for testParseMessagePlaceholders().
+ */
+ public function providerTestParseMessagePlaceholders() {
+ return array(
+ // PSR3 only message.
+ array(
+ array('message' => 'User {username} created', 'context' => array('username' => 'Dries')),
+ array('message' => 'User @username created', 'context' => array('@username' => 'Dries')),
+ ),
+ // PSR3 style mixed in a format_string style message.
+ array(
+ array('message' => 'User {username} created @time', 'context' => array('username' => 'Dries', '@time' => 'now')),
+ array('message' => 'User @username created @time', 'context' => array('@username' => 'Dries', '@time' => 'now')),
+ ),
+ // format_string style message only.
+ array(
+ array('message' => 'User @username created', 'context' => array('@username' => 'Dries')),
+ array('message' => 'User @username created', 'context' => array('@username' => 'Dries')),
+ ),
+ // Messsage without placeholders but wildcard characters.
+ array(
+ array('message' => 'User W-\\};~{&! created @', 'context' => array('' => '')),
+ array('message' => 'User W-\\};~{&! created @', 'context' => array()),
+ ),
+ // Messsage with double PSR3 style messages.
+ array(
+ array('message' => 'Test {with} two {encapsuled} strings', 'context' => array('with' => 'together', 'encapsuled' => 'awesome')),
+ array('message' => 'Test @with two @encapsuled strings', 'context' => array('@with' => 'together', '@encapsuled' => 'awesome')),
+ ),
+ );
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Logger/LoggerChannelFactoryTest.php b/core/tests/Drupal/Tests/Core/Logger/LoggerChannelFactoryTest.php
new file mode 100644
index 0000000..82e20b2
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Logger/LoggerChannelFactoryTest.php
@@ -0,0 +1,66 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Logger\LoggerChannelFactoryTest
+ */
+
+namespace Drupal\Tests\Logger;
+
+use Drupal\Core\Logger\LoggerChannelFactory;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+
+// @todo Remove once watchdog() is removed.
+if (!defined('WATCHDOG_EMERGENCY')) {
+ define('WATCHDOG_EMERGENCY', 0);
+ define('WATCHDOG_ALERT', 1);
+ define('WATCHDOG_CRITICAL', 2);
+ define('WATCHDOG_WARNING', 4);
+ define('WATCHDOG_INFO', 6);
+ define('WATCHDOG_DEBUG', 7);
+}
+// WATCHDOG_NOTICE is also defined in FormValidatorTest, so check independently.
+if (!defined('WATCHDOG_NOTICE')) {
+ define('WATCHDOG_NOTICE', 5);
+}
+// WATCHDOG_ERROR is also defined in FormBuilderTest, so check independently.
+if (!defined('WATCHDOG_ERROR')) {
+ define('WATCHDOG_ERROR', 3);
+}
+
+/**
+ * Tests the logger channel factory.
+ *
+ * @see \Drupal\Core\Logger\LoggerChannelFactory
+ * @coversDefaultClass \Drupal\Core\Logger\LoggerChannelFactory
+ *
+ * @group Drupal
+ * @group Logger
+ */
+class LoggerChannelFactoryTest extends UnitTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Logger channel factory',
+ 'description' => 'Unit tests for the logger channel factory object.',
+ 'group' => 'Logger',
+ );
+ }
+
+ /**
+ * Tests LoggerChannelFactory::get().
+ *
+ * @covers ::get
+ */
+ public function testGet() {
+ $factory = new LoggerChannelFactory();
+ $factory->setContainer($this->getMock('Symfony\Component\DependencyInjection\ContainerInterface'));
+
+ // Ensure that when called with the same argument, always the same instance
+ // will be returned.
+ $this->assertEquals($factory->get('test'), $factory->get('test'));
+ }
+
+}
diff --git a/core/tests/Drupal/Tests/Core/Logger/LoggerChannelTest.php b/core/tests/Drupal/Tests/Core/Logger/LoggerChannelTest.php
new file mode 100644
index 0000000..2cc0a50
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Logger/LoggerChannelTest.php
@@ -0,0 +1,158 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\Tests\Core\Logger\LoggerChannelTest
+ */
+
+namespace Drupal\Tests\Logger;
+
+use Drupal\Core\Logger\LoggerChannel;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+
+// @todo Remove once watchdog() is removed.
+if (!defined('WATCHDOG_EMERGENCY')) {
+ define('WATCHDOG_EMERGENCY', 0);
+ define('WATCHDOG_ALERT', 1);
+ define('WATCHDOG_CRITICAL', 2);
+ define('WATCHDOG_WARNING', 4);
+ define('WATCHDOG_INFO', 6);
+ define('WATCHDOG_DEBUG', 7);
+}
+// WATCHDOG_NOTICE is also defined in FormValidatorTest, so check independently.
+if (!defined('WATCHDOG_NOTICE')) {
+ define('WATCHDOG_NOTICE', 5);
+}
+// WATCHDOG_ERROR is also defined in FormBuilderTest, so check independently.
+if (!defined('WATCHDOG_ERROR')) {
+ define('WATCHDOG_ERROR', 3);
+}
+
+/**
+ * Tests the logger channel.
+ *
+ * @see \Drupal\Core\Logger\LoggerChannel
+ * @coversDefaultClass \Drupal\Core\Logger\LoggerChannel
+ *
+ * @group Drupal
+ * @group Logger
+ */
+class LoggerChannelTest extends UnitTestCase {
+
+ public static function getInfo() {
+ return array(
+ 'name' => 'Logger channel',
+ 'description' => 'Unit tests for the logger channel object.',
+ 'group' => 'Logger',
+ );
+ }
+
+ /**
+ * Tests LoggerChannel::log().
+ *
+ * @param callable $expected
+ * An anonymous function to use with $this->callback() of the logger mock.
+ * The function should check the $context array for expected values.
+ * @param \Symfony\Component\HttpFoundation\Request $request
+ * Will be passed to the channel under test if present.
+ * @param \Drupal\Core\Session\AccountInterface $current_user
+ * Will be passed to the channel under test if present.
+ *
+ * @dataProvider providerTestLog
+ * @covers ::log
+ * @covers ::setCurrentUser
+ * @covers ::setRequest
+ */
+ public function testLog(callable $expected, Request $request = NULL, AccountInterface $current_user = NULL) {
+ $channel = new LoggerChannel('test');
+ $message = $this->randomName();
+ $logger = $this->getMock('Psr\Log\LoggerInterface');
+ $logger->expects($this->once())
+ ->method('log')
+ ->with($this->anything(), $message, $this->callback($expected));
+ $channel->addLogger($logger);
+ if ($request) {
+ $channel->setRequest($request);
+ }
+ if ($current_user) {
+ $channel->setCurrentUser($current_user);
+ }
+ $channel->log(rand(0, 7), $message);
+ }
+
+ /**
+ * Tests LoggerChannel::addLoggers().
+ *
+ * @covers ::addLogger
+ * @covers ::sortLoggers
+ */
+ public function testSortLoggers() {
+ $channel = new LoggerChannel($this->randomName());
+ $index_order = '';
+ for ($i = 0; $i < 4; $i++) {
+ $logger = $this->getMock('Psr\Log\LoggerInterface');
+ $logger->expects($this->once())
+ ->method('log')
+ ->will($this->returnCallback(function () use ($i, &$index_order) {
+ // Append the $i to the index order, so that we know the order that
+ // loggers got called with.
+ $index_order .= $i;
+ }));
+ $channel->addLogger($logger, $i);
+ }
+
+ $channel->log(rand(0, 7), $this->randomName());
+ // Ensure that the logger added in the end fired first.
+ $this->assertEquals($index_order, '3210');
+ }
+
+ /**
+ * Data provider for self::testLog().
+ */
+ public function providerTestLog() {
+ $account_mock = $this->getMock('Drupal\Core\Session\AccountInterface');
+ $account_mock->expects($this->exactly(2))
+ ->method('id')
+ ->will($this->returnValue(1));
+
+ $request_mock = $this->getMock('Symfony\Component\HttpFoundation\Request');
+ $request_mock->expects($this->exactly(2))
+ ->method('getClientIp')
+ ->will($this->returnValue('127.0.0.1'));
+ $request_mock->headers = $this->getMock('Symfony\Component\HttpFoundation\ParameterBag');
+
+ // No request or account.
+ $cases [] = array(
+ function ($context) {
+ return $context['channel'] == 'test' && empty($contex['uid']) && empty($context['ip']);
+ },
+ );
+ // With account but not request.
+ $cases [] = array(
+ function ($context) {
+ return $context['uid'] === 1 && empty($context['ip']);
+ },
+ NULL,
+ $account_mock,
+ );
+ // With request but not account.
+ $cases [] = array(
+ function ($context) {
+ return $context['ip'] === '127.0.0.1' && empty($contex['uid']);
+ },
+ $request_mock,
+ );
+ // Both request and account.
+ $cases [] = array(
+ function ($context) {
+ return $context['ip'] === '127.0.0.1' && $context['uid'] === 1;
+ },
+ $request_mock,
+ $account_mock,
+ );
+ return $cases;
+ }
+
+}
diff --git a/core/update.php b/core/update.php
index 3bac378..b6accf3 100644
--- a/core/update.php
+++ b/core/update.php
@@ -226,7 +226,7 @@ function update_info_page() {
function update_access_denied_page() {
drupal_add_http_header('Status', '403 Forbidden');
header(\Drupal::request()->server->get('SERVER_PROTOCOL') . ' 403 Forbidden');
- watchdog('access denied', 'update.php', NULL, WATCHDOG_WARNING);
+ watchdog('access denied', 'update.php', array(), WATCHDOG_WARNING);
$output = '<p>Access denied. You are not authorized to access this page. Log in using either an account with the <em>administer software updates</em> permission or the site maintenance account (the account you created during installation). If you cannot log in, you will have to edit <code>settings.php</code> to bypass this access check. To do this:</p>
<ol>
<li>With a text editor find the settings.php file on your system. From the main Drupal directory that you installed all the files into, go to <code>sites/your_site_name</code> if such directory exists, or else to <code>sites/default</code> which applies otherwise.</li>