- Issue created by @kkaya
This isn't something we've experienced. There must be additional steps to reproduce outside of upgrading Core.
Below are the commits and the differences between those versions. Researching a bug will mean:
- Reproducing it. What is the setup of Drupal Core that exhibits the bug?
- What is the specific version of Drupal Core that introduced the bug?
- Identifying the commit that broke the module. A
git bisect
operation on a Drupal Core Git working copy that is set up to exhibit the bug will quickly find the regression commit.
$ git log --oneline 10.2.10...10.3.6 core/modules/dblog 8c274c9f87 Issue #3467294 by quietone, nod_, smustgrave, catch, longwave: Change string 'Modules to enable' to {@inheritdoc} in comments 21396c951e Issue #3469716 by catch, smustgrave: Optimize dblog tests f4930ff629 Issue #3421418 by mstrelan, Spokje, xjm, mondrake, longwave, acbramley: Add void return typehints to all test methods 24e197de0b Issue #3427999 by andypost, Ayesh, bbrala: [PHP 8.4] Fix implicitly nullable type declarations 2c3cb5e89f Issue #3427564 by phenaproxima, Wim Leers, alexpott, omkar.podey, Berdir, smustgrave, larowlan: Require `langcode: …` only for simple config that contains translatable values 442b47177d Issue #3399388 by mstrelan: Add declare(strict_types=1) to all Kernel tests 5786e6e83b Issue #3421000 by sorlov, quietone, smustgrave, larowlan, alexpott: Convert ViewsWizard plugin discovery to attributes a15b012100 Issue #3436671 by narendraR, Wim Leers, phenaproxima: Add validation constraints to system.cron 2ed3680d12 Issue #3426957 by sorlov, smustgrave, mstrelan: Convert ViewsFilter plugin discovery to attributes fc15d5ee53 Issue #3426955 by mstrelan, sorlov, alexpott, smustgrave, godotislate: Convert ViewsField plugin discovery to attributes 67c22284ec Issue #3420994 by kim.pepper: Convert RestResource plugin discovery to attributes a23b6d6768 Issue #3399746 by mstrelan, acbramley: Add declare(strict_types=1) to all Functional tests e5e61dc566 Issue #3309104 by Bhanu951, acbramley, mondrake, ravi.shankar, smustgrave, daffie, alexpott, quietone, mstrelan: Replace REQUEST_TIME in Functional and FunctionalJavascript tests 47e76cea08 Issue #3395631 by phenaproxima, hdnag, borisson_, marvil07, Spokje, Wim Leers, catch, dagmar: Add validation constraints to dblog.settings bf4e65cf04 Revert "Issue #3395631 by hdnag, borisson_, marvil07, dagmar, Wim Leers: Add validation constraints to dblog.settings" 421ade1c80 Issue #3395631 by hdnag, borisson_, marvil07, dagmar, Wim Leers: Add validation constraints to dblog.settings a335588be2 Issue #2481349 by mfb, dagmar, jofitz, smustgrave, vasi, neclimdul, ziomizar, quietone, _utsavsharma, littlepixiez, xjm, fgm, Todd Zebert, hass, dawehner, heddn, webchick, catch: Prevent the use of placeholders that cannot be converted into strings when creating logs 367e57e7bc Issue #2481349 by mfb, dagmar, jofitz, smustgrave, vasi, neclimdul, ziomizar, quietone, _utsavsharma, littlepixiez, xjm, fgm, Todd Zebert, hass, dawehner, heddn, webchick, catch: Prevent the use of placeholders that cannot be converted into strings when creating logs 362a5f61d9 Issue #3412464 by mstrelan, smustgrave, quietone: Fix strict type errors: Convert FormattableMarkup to strings (complex replacement) in core Functional tests 503192fcfe Issue #3412464 by mstrelan, smustgrave: Fix strict type errors: Convert FormattableMarkup to strings (complex replacement) in core Functional tests 526d8ef95e Issue #3415811 by catch: Add @group #slow to more functional tests 379968c4ac Issue #3414263 by quietone, andypost: Change help headings for WCAG 2.0 1e8ae69e1d Issue #3414263 by quietone, andypost: Change help headings for WCAG 2.0 828b4be30c Issue #3404273 by mstrelan, smustgrave: Fix strict type errors: Convert FormattableMarkup to strings (simple replacement) in core Functional tests 061989d481 Issue #3404273 by mstrelan, smustgrave: Fix strict type errors: Convert FormattableMarkup to strings (simple replacement) in core Functional tests 79b5436806 Issue #3333401 by nicxvan, tsquared212, xjm, larowlan, smustgrave, andrewmacpherson, bnjmnm, lauriii, itmaybejj, xurizaemon: Pager h4 causes accessibility flag on many pages d39fc2255a Issue #3402293 by dww, mstrelan, smustgrave: Fix strict type errors: Convert FormattableMarkup to strings (simple replacement) in core/modules/*/tests/src/Kernel/* df70716e5a Issue #3402293 by dww, mstrelan, smustgrave: Fix strict type errors: Convert FormattableMarkup to strings (simple replacement) in core/modules/*/tests/src/Kernel/* 538c90fb10 Issue #3370560 by quietone, bogdog400, daffie: Update failed: dblog_update_10101 (TINYINT) cd9dd26637 Issue #3370560 by quietone, bogdog400, daffie: Update failed: dblog_update_10101 (TINYINT) 83752e6bc0 Issue #3396310 by longwave, Spokje, smustgrave: Use autowiring for core controllers d15c431465 Issue #3391786 by quietone, xjm, smustgrave: Fix spelling of words only misspelled in tests, variable names, part 5 6dc9ce0b01 Issue #3391786 by quietone, xjm, smustgrave: Fix spelling of words only misspelled in tests, variable names, part 5 72d9d9ba16 Issue #3175449 by mfb, super_romeo, smustgrave, _pratik_, Medha Kumari, Nitin shrivastava, quietone, alexpott, xjm, dagmar, longwave: Display backtrace for logged throwables on log message details page d5e0610510 Issue #3175449 by mfb, super_romeo, smustgrave, _pratik_, Medha Kumari, Nitin shrivastava, quietone, alexpott, xjm, dagmar, longwave: Display backtrace for logged throwables on log message details page 14bf457fbf Issue #3398891 by alexpott, Wim Leers: Do not require the config in #config_target to be listed in getEditableConfigNames() c1a42fda67 Issue #3398891 by alexpott, Wim Leers: Do not require the config in #config_target to be listed in getEditableConfigNames()
$ git diff 10.2.10...10.3.6 core/modules/dblog diff --git a/core/modules/dblog/config/optional/views.view.watchdog.yml b/core/modules/dblog/config/optional/views.view.watchdog.yml index a21b0ea386..f6bf0905aa 100644 --- a/core/modules/dblog/config/optional/views.view.watchdog.yml +++ b/core/modules/dblog/config/optional/views.view.watchdog.yml @@ -437,6 +437,7 @@ display: type: mini options: offset: 0 + pagination_heading_level: h4 items_per_page: 50 total_pages: null id: 0 diff --git a/core/modules/dblog/config/schema/dblog.schema.yml b/core/modules/dblog/config/schema/dblog.schema.yml index d7196da6da..cd59a5dd89 100644 --- a/core/modules/dblog/config/schema/dblog.schema.yml +++ b/core/modules/dblog/config/schema/dblog.schema.yml @@ -7,3 +7,8 @@ dblog.settings: row_limit: type: integer label: 'Database log messages to keep' + constraints: + Range: + min: 0 + constraints: + FullyValidatable: ~ diff --git a/core/modules/dblog/dblog.install b/core/modules/dblog/dblog.install index 2a9f05dd39..0a581226b4 100644 --- a/core/modules/dblog/dblog.install +++ b/core/modules/dblog/dblog.install @@ -5,8 +5,6 @@ * Install, update and uninstall functions for the dblog module. */ -use Drupal\Core\Database\Database; - /** * Implements hook_schema(). */ @@ -123,15 +121,15 @@ function dblog_update_10100(&$sandbox = NULL) { * Converts the 'wid' of the 'watchdog' table to a big integer. */ function dblog_update_10101(&$sandbox = NULL) { - $schema = Database::getConnection()->schema(); - - // Increase the size of the field. - $new_specification = [ - 'size' => 'big', - 'type' => 'serial', - 'not null' => TRUE, - 'description' => 'Primary Key: Unique watchdog event ID.', - ]; - $schema->changeField('watchdog', 'wid', 'wid', $new_specification); - + $connection = \Drupal::database(); + if ($connection->databaseType() != 'sqlite') { + // Increase the size of the field. + $new_specification = [ + 'size' => 'big', + 'type' => 'serial', + 'not null' => TRUE, + 'description' => 'Primary Key: Unique watchdog event ID.', + ]; + $connection->schema()->changeField('watchdog', 'wid', 'wid', $new_specification); + } } diff --git a/core/modules/dblog/dblog.module b/core/modules/dblog/dblog.module index aa3f910f9f..ef11460c2c 100644 --- a/core/modules/dblog/dblog.module +++ b/core/modules/dblog/dblog.module @@ -22,9 +22,9 @@ function dblog_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { case 'help.page.dblog': $output = ''; - $output .= '<h3>' . t('About') . '</h3>'; + $output .= '<h2>' . t('About') . '</h2>'; $output .= '<p>' . t('The Database Logging module logs system events in the Drupal database. For more information, see the <a href=":dblog">online documentation for the Database Logging module</a>.', [':dblog' => 'https://www.drupal.org/documentation/modules/dblog']) . '</p>'; - $output .= '<h3>' . t('Uses') . '</h3>'; + $output .= '<h2>' . t('Uses') . '</h2>'; $output .= '<dl>'; $output .= '<dt>' . t('Monitoring your site') . '</dt>'; $output .= '<dd>' . t('The Database Logging module allows you to view an event log on the <a href=":dblog">Recent log messages</a> page. The log is a chronological list of recorded events containing usage data, performance data, errors, warnings and operational information. Administrators should check the log on a regular basis to ensure their site is working properly.', [':dblog' => Url::fromRoute('dblog.overview')->toString()]) . '</dd>'; @@ -104,21 +104,10 @@ function dblog_form_system_logging_settings_alter(&$form, FormStateInterface $fo $form['dblog_row_limit'] = [ '#type' => 'select', '#title' => t('Database log messages to keep'), - '#default_value' => \Drupal::configFactory()->getEditable('dblog.settings')->get('row_limit'), + '#config_target' => 'dblog.settings:row_limit', '#options' => [0 => t('All')] + array_combine($row_limits, $row_limits), '#description' => t('The maximum number of messages to keep in the database log. Requires a <a href=":cron">cron maintenance task</a>.', [':cron' => Url::fromRoute('system.status')->toString()]), ]; - - $form['#submit'][] = 'dblog_logging_settings_submit'; -} - -/** - * Form submission handler for system_logging_settings(). - * - * @see dblog_form_system_logging_settings_alter() - */ -function dblog_logging_settings_submit($form, FormStateInterface $form_state) { - \Drupal::configFactory()->getEditable('dblog.settings')->set('row_limit', $form_state->getValue('dblog_row_limit'))->save(); } /** diff --git a/core/modules/dblog/src/Controller/DbLogController.php b/core/modules/dblog/src/Controller/DbLogController.php index b52ed5015a..134bc22580 100644 --- a/core/modules/dblog/src/Controller/DbLogController.php +++ b/core/modules/dblog/src/Controller/DbLogController.php @@ -17,7 +17,6 @@ use Drupal\Core\Logger\RfcLogLevel; use Drupal\Core\Url; use Drupal\user\Entity\User; -use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\HttpFoundation\Request; use Drupal\Core\Link; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; @@ -48,18 +47,6 @@ class DbLogController extends ControllerBase { */ protected $userStorage; - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('database'), - $container->get('module_handler'), - $container->get('date.formatter'), - $container->get('form_builder') - ); - } - /** * Constructs a DbLogController object. * @@ -291,6 +278,12 @@ public function eventDetails($event_id) { ['data' => ['#markup' => $dblog->link]], ], ]; + if (isset($dblog->backtrace)) { + $rows[] = [ + ['data' => $this->t('Backtrace'), 'header' => TRUE], + $dblog->backtrace, + ]; + } $build['dblog_table'] = [ '#type' => 'table', '#rows' => $rows, @@ -350,6 +343,10 @@ protected function buildFilterQuery(Request $request) { * The record from the watchdog table. The object properties are: wid, uid, * severity, type, timestamp, message, variables, link, name. * + * If the variables contain a @backtrace_string placeholder which is not + * used in the message, the formatted backtrace will be assigned to a new + * backtrace property on the row object which can be displayed separately. + * * @return string|\Drupal\Core\StringTranslation\TranslatableMarkup|false * The formatted log message or FALSE if the message or variables properties * are not set. @@ -372,6 +369,10 @@ public function formatMessage($row) { $variables['@backtrace_string'] = new FormattableMarkup( '<pre class="backtrace">@backtrace_string</pre>', $variables ); + // Save a reference so the backtrace can be displayed separately. + if (!str_contains($row->message, '@backtrace_string')) { + $row->backtrace = $variables['@backtrace_string']; + } } $message = $this->t(Xss::filterAdmin($row->message), $variables); } diff --git a/core/modules/dblog/src/Plugin/rest/resource/DbLogResource.php b/core/modules/dblog/src/Plugin/rest/resource/DbLogResource.php index b1a617b3e1..c3174469e5 100644 --- a/core/modules/dblog/src/Plugin/rest/resource/DbLogResource.php +++ b/core/modules/dblog/src/Plugin/rest/resource/DbLogResource.php @@ -3,6 +3,8 @@ namespace Drupal\dblog\Plugin\rest\resource; use Drupal\Core\Database\Database; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\rest\Attribute\RestResource; use Drupal\rest\Plugin\ResourceBase; use Drupal\rest\ResourceResponse; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; @@ -10,15 +12,14 @@ /** * Provides a resource for database watchdog log entries. - * - * @RestResource( - * id = "dblog", - * label = @Translation("Watchdog database log"), - * uri_paths = { - * "canonical" = "/dblog/{id}" - * } - * ) */ +#[RestResource( + id: "dblog", + label: new TranslatableMarkup("Watchdog database log"), + uri_paths: [ + "canonical" => "/dblog/{id}", + ] +)] class DbLogResource extends ResourceBase { /** diff --git a/core/modules/dblog/src/Plugin/views/field/DblogMessage.php b/core/modules/dblog/src/Plugin/views/field/DblogMessage.php index fd18779f04..2725098332 100644 --- a/core/modules/dblog/src/Plugin/views/field/DblogMessage.php +++ b/core/modules/dblog/src/Plugin/views/field/DblogMessage.php @@ -4,6 +4,7 @@ use Drupal\Component\Render\FormattableMarkup; use Drupal\Core\Form\FormStateInterface; +use Drupal\views\Attribute\ViewsField; use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\ResultRow; use Drupal\views\ViewExecutable; @@ -13,15 +14,14 @@ * Provides a field handler that renders a log event with replaced variables. * * @ingroup views_field_handlers - * - * @ViewsField("dblog_message") */ +#[ViewsField("dblog_message")] class DblogMessage extends FieldPluginBase { /** * {@inheritdoc} */ - public function init(ViewExecutable $view, DisplayPluginBase $display, array &$options = NULL) { + public function init(ViewExecutable $view, DisplayPluginBase $display, ?array &$options = NULL) { parent::init($view, $display, $options); if ($this->options['replace_variables']) { diff --git a/core/modules/dblog/src/Plugin/views/field/DblogOperations.php b/core/modules/dblog/src/Plugin/views/field/DblogOperations.php index 49a47fda81..15fc083374 100644 --- a/core/modules/dblog/src/Plugin/views/field/DblogOperations.php +++ b/core/modules/dblog/src/Plugin/views/field/DblogOperations.php @@ -2,6 +2,7 @@ namespace Drupal\dblog\Plugin\views\field; +use Drupal\views\Attribute\ViewsField; use Drupal\views\Plugin\views\field\FieldPluginBase; use Drupal\views\ResultRow; @@ -9,9 +10,8 @@ * Provides a field handler that renders operation link markup. * * @ingroup views_field_handlers - * - * @ViewsField("dblog_operations") */ +#[ViewsField("dblog_operations")] class DblogOperations extends FieldPluginBase { /** diff --git a/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php b/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php index ed8f547166..b95f5f1038 100644 --- a/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php +++ b/core/modules/dblog/src/Plugin/views/filter/DblogTypes.php @@ -3,13 +3,13 @@ namespace Drupal\dblog\Plugin\views\filter; use Drupal\Core\Form\FormStateInterface; +use Drupal\views\Attribute\ViewsFilter; use Drupal\views\Plugin\views\filter\InOperator; /** * Exposes log types to views module. - * - * @ViewsFilter("dblog_types") */ +#[ViewsFilter("dblog_types")] class DblogTypes extends InOperator { /** diff --git a/core/modules/dblog/src/Plugin/views/wizard/Watchdog.php b/core/modules/dblog/src/Plugin/views/wizard/Watchdog.php index 3a0dad5c86..ac78fe828b 100644 --- a/core/modules/dblog/src/Plugin/views/wizard/Watchdog.php +++ b/core/modules/dblog/src/Plugin/views/wizard/Watchdog.php @@ -2,18 +2,18 @@ namespace Drupal\dblog\Plugin\views\wizard; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\views\Attribute\ViewsWizard; use Drupal\views\Plugin\views\wizard\WizardPluginBase; /** * Defines a wizard for the watchdog table. - * - * @ViewsWizard( - * id = "watchdog", - * module = "dblog", - * base_table = "watchdog", - * title = @Translation("Log entries") - * ) */ +#[ViewsWizard( + id: 'watchdog', + title: new TranslatableMarkup('Log entries'), + base_table: 'watchdog' +)] class Watchdog extends WizardPluginBase { /** diff --git a/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php b/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php index f7845bf605..efd97a84aa 100644 --- a/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php +++ b/core/modules/dblog/tests/src/Functional/DbLogResourceTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Functional; use Drupal\Component\Serialization\Json; diff --git a/core/modules/dblog/tests/src/Functional/DbLogTest.php b/core/modules/dblog/tests/src/Functional/DbLogTest.php index b4ef303d04..b68ce85ad6 100644 --- a/core/modules/dblog/tests/src/Functional/DbLogTest.php +++ b/core/modules/dblog/tests/src/Functional/DbLogTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Functional; use Drupal\Component\Render\FormattableMarkup; @@ -23,9 +25,7 @@ class DbLogTest extends BrowserTestBase { use AssertBreadcrumbTrait; /** - * Modules to enable. - * - * @var array + * {@inheritdoc} */ protected static $modules = [ 'dblog', @@ -80,7 +80,7 @@ protected function setUp(): void { * Database Logging module functionality through both the admin and user * interfaces. */ - public function testDbLog() { + public function testDbLog(): void { // Log in the admin user. $this->drupalLogin($this->adminUser); @@ -102,12 +102,18 @@ public function testDbLog() { // Log in the regular user. $this->drupalLogin($this->webUser); $this->verifyReports(403); + + $this->testLogEventNotFoundPage(); + $this->testLogEventPageWithMissingInfo(); + $this->test403LogEventPage(); + $this->testMessageParsing(); + $this->testOverviewLinks(); } /** * Tests individual log event page. */ - public function testLogEventPage() { + public function testLogEventPage(): void { // Login the admin user. $this->drupalLogin($this->adminUser); @@ -120,7 +126,7 @@ public function testLogEventPage() { 'channel' => 'testing', 'link' => 'foo/bar', 'ip' => '0.0.1.0', - 'timestamp' => REQUEST_TIME, + 'timestamp' => \Drupal::time()->getRequestTime(), ]; \Drupal::service('logger.dblog')->log(RfcLogLevel::NOTICE, 'Test message', $context); $query = Database::getConnection()->select('watchdog'); @@ -142,10 +148,40 @@ public function testLogEventPage() { $this->assertSession()->pageTextContains('Notice'); } + /** + * Tests that the details page displays the backtrace for a logged \Throwable. + */ + public function testOnError(): void { + // Log in as the admin user. + $this->drupalLogin($this->adminUser); + + // Load a page that throws an exception in the controller, and includes its + // function arguments in the exception backtrace. + $this->drupalGet('error-test/trigger-exception'); + + // Load the details page for the most recent event logged by the "php" + // logger. + $query = Database::getConnection()->select('watchdog') + ->condition('type', 'php'); + $query->addExpression('MAX([wid])'); + $wid = $query->execute()->fetchField(); + $this->drupalGet('admin/reports/dblog/event/' . $wid); + + // Verify the page displays a dblog-event table with a "Type" header. + $table = $this->assertSession()->elementExists('xpath', "//table[@class='dblog-event']"); + $type = "//tr/th[contains(text(), 'Type')]/../td"; + $this->assertSession()->elementsCount('xpath', $type, 1, $table); + + // Verify that the backtrace row exists and is HTML-encoded. + $backtrace = "//tr//pre[contains(@class, 'backtrace')]"; + $this->assertCount(1, $table->findAll('xpath', $backtrace)); + $this->assertSession()->responseContains('<script>alert('xss')</script>'); + } + /** * Tests that a 403 event is logged with the exception triggering it. */ - public function test403LogEventPage() { + protected function test403LogEventPage(): void { $assert_session = $this->assertSession(); $uri = 'admin/reports'; @@ -185,7 +221,7 @@ public function test403LogEventPage() { /** * Tests not-existing log event page. */ - public function testLogEventNotFoundPage() { + protected function testLogEventNotFoundPage(): void { // Login the admin user. $this->drupalLogin($this->adminUser); @@ -204,7 +240,7 @@ public function testLogEventNotFoundPage() { * - Incorrect location: When location attribute is incorrect uri which can * not be used to generate a valid link. */ - public function testLogEventPageWithMissingInfo() { + protected function testLogEventPageWithMissingInfo(): void { $this->drupalLogin($this->adminUser); $connection = Database::getConnection(); @@ -247,7 +283,7 @@ public function testLogEventPageWithMissingInfo() { /** * Test that twig errors are displayed correctly. */ - public function testMessageParsing() { + protected function testMessageParsing(): void { $this->drupalLogin($this->adminUser); // Log a common twig error with {{ }} and { } variables. \Drupal::service('logger.factory')->get("php") @@ -273,11 +309,12 @@ private function verifyRowLimit($row_limit) { $edit['dblog_row_limit'] = $row_limit; $this->drupalGet('admin/config/development/logging'); $this->submitForm($edit, 'Save configuration'); + $this->assertSession()->statusMessageContains('The configuration options have been saved.'); $this->assertSession()->statusCodeEquals(200); // Check row limit variable. $current_limit = $this->config('dblog.settings')->get('row_limit'); - $this->assertEquals($current_limit, $row_limit, new FormattableMarkup('[Cache] Row limit variable of @count equals row limit of @limit', ['@count' => $current_limit, '@limit' => $row_limit])); + $this->assertEquals($current_limit, $row_limit, "[Cache] Row limit variable of $current_limit equals row limit of $row_limit"); } /** @@ -399,7 +436,7 @@ private function verifyEvents() { * @param string $order * The order by which the table should be sorted. */ - public function verifySort($sort = 'asc', $order = 'Date') { + protected function verifySort($sort = 'asc', $order = 'Date') { $this->drupalGet('admin/reports/dblog', ['query' => ['sort' => $sort, 'order' => $order]]); $this->assertSession()->statusCodeEquals(200); $this->assertSession()->pageTextContains('Recent log messages'); @@ -443,7 +480,7 @@ private function doUser() { $this->assertSession()->statusCodeEquals(200); // Retrieve the user object. $user = user_load_by_name($name); - $this->assertNotNull($user, new FormattableMarkup('User @name was loaded', ['@name' => $name])); + $this->assertNotNull($user, "User $name was loaded"); // pass_raw property is needed by drupalLogin. $user->passRaw = $pass; // Log in user. @@ -456,7 +493,7 @@ private function doUser() { $ids[] = $row->wid; } $count_before = (isset($ids)) ? count($ids) : 0; - $this->assertGreaterThan(0, $count_before, new FormattableMarkup('DBLog contains @count records for @name', ['@count' => $count_before, '@name' => $user->getAccountName()])); + $this->assertGreaterThan(0, $count_before, "DBLog contains $count_before records for {$user->getAccountName()}"); // Log in the admin user. $this->drupalLogin($this->adminUser); @@ -531,7 +568,7 @@ private function doNode($type) { $this->assertSession()->statusCodeEquals(200); // Retrieve the node object. $node = $this->drupalGetNodeByTitle($title); - $this->assertNotNull($node, new FormattableMarkup('Node @title was loaded', ['@title' => $title])); + $this->assertNotNull($node, "Node $title was loaded"); // Edit the node. $edit = [ 'body[0][value]' => $this->randomMachineName(32), @@ -583,7 +620,7 @@ private function doNode($type) { * Logs in the admin user, creates a database log event, and tests the * functionality of clearing the database log through the admin interface. */ - public function testDBLogAddAndClear() { + public function testDBLogAddAndClear(): void { global $base_root; $connection = Database::getConnection(); // Get a count of how many watchdog entries already exist. @@ -598,12 +635,12 @@ public function testDBLogAddAndClear() { 'request_uri' => $base_root . \Drupal::request()->getRequestUri(), 'referer' => \Drupal::request()->server->get('HTTP_REFERER'), 'ip' => '127.0.0.1', - 'timestamp' => REQUEST_TIME, + 'timestamp' => \Drupal::time()->getRequestTime(), ]; // Add a watchdog entry. $this->container->get('logger.dblog')->log($log['severity'], $log['message'], $log); // Make sure the table count has actually been incremented. - $this->assertEquals($count + 1, (int) $connection->select('watchdog')->countQuery()->execute()->fetchField(), new FormattableMarkup('\Drupal\dblog\Logger\DbLog->log() added an entry to the dblog :count', [':count' => $count])); + $this->assertEquals($count + 1, (int) $connection->select('watchdog')->countQuery()->execute()->fetchField(), '\Drupal\dblog\Logger\DbLog->log() added an entry to the dblog ' . $count); // Log in the admin user. $this->drupalLogin($this->adminUser); // Post in order to clear the database table. @@ -612,13 +649,13 @@ public function testDBLogAddAndClear() { $this->submitForm([], 'Confirm'); // Count the rows in watchdog that previously related to the deleted user. $count = $connection->select('watchdog')->countQuery()->execute()->fetchField(); - $this->assertEquals(0, $count, new FormattableMarkup('DBLog contains :count records after a clear.', [':count' => $count])); + $this->assertEquals(0, $count, "DBLog contains $count records after a clear."); } /** * Tests the database log filter functionality at admin/reports/dblog. */ - public function testFilter() { + public function testFilter(): void { $this->drupalLogin($this->adminUser); // Clear the log to ensure that only generated entries will be found. @@ -794,16 +831,16 @@ protected function assertLogMessage(string $log_message, string $message): void /** * Tests that the details page displays correctly for a temporary user. */ - public function testTemporaryUser() { + public function testTemporaryUser(): void { // Create a temporary user. - $tempuser = $this->drupalCreateUser(); - $tempuser_uid = $tempuser->id(); + $temporary_user = $this->drupalCreateUser(); + $temporary_user_uid = $temporary_user->id(); // Log in as the admin user. $this->drupalLogin($this->adminUser); // Generate a single watchdog entry. - $this->generateLogEntries(1, ['user' => $tempuser, 'uid' => $tempuser_uid]); + $this->generateLogEntries(1, ['user' => $temporary_user, 'uid' => $temporary_user_uid]); $query = Database::getConnection()->select('watchdog'); $query->addExpression('MAX([wid])'); $wid = $query->execute()->fetchField(); @@ -813,8 +850,8 @@ public function testTemporaryUser() { $this->assertSession()->pageTextContains('Dblog test log message'); // Delete the user. - $tempuser->delete(); - $this->drupalGet('user/' . $tempuser_uid); + $temporary_user->delete(); + $this->drupalGet('user/' . $temporary_user_uid); $this->assertSession()->statusCodeEquals(404); // Check if the full message displays on the details page. @@ -825,7 +862,7 @@ public function testTemporaryUser() { /** * Make sure HTML tags are filtered out in the log overview links. */ - public function testOverviewLinks() { + protected function testOverviewLinks(): void { $this->drupalLogin($this->adminUser); // cSpell:disable-next-line $this->generateLogEntries(1, ['message' => "<script>alert('foo');</script><strong>Lorem</strong> ipsum dolor sit amet, consectetur adipiscing & elit."]); @@ -848,7 +885,7 @@ public function testOverviewLinks() { /** * Tests sorting for entries with the same timestamp. */ - public function testSameTimestampEntries() { + public function testSameTimestampEntries(): void { $this->drupalLogin($this->adminUser); $this->generateLogEntries(1, ['timestamp' => 1498062000, 'type' => 'same_time', 'message' => 'First']); @@ -866,7 +903,7 @@ public function testSameTimestampEntries() { /** * Tests that the details page displays correctly backtrace. */ - public function testBacktrace() { + public function testBacktrace(): void { $this->drupalLogin($this->adminUser); $this->drupalGet('/error-test/generate-warnings'); diff --git a/core/modules/dblog/tests/src/Functional/DbLogViewsTest.php b/core/modules/dblog/tests/src/Functional/DbLogViewsTest.php index d6794a01c4..284803fb29 100644 --- a/core/modules/dblog/tests/src/Functional/DbLogViewsTest.php +++ b/core/modules/dblog/tests/src/Functional/DbLogViewsTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Functional; use Drupal\views\Views; @@ -14,9 +16,7 @@ class DbLogViewsTest extends DbLogTest { /** - * Modules to enable. - * - * @var array + * {@inheritdoc} */ protected static $modules = [ 'dblog', @@ -56,7 +56,7 @@ protected function filterLogsEntries($type = NULL, $severity = NULL) { /** * Tests the empty text for the watchdog view is not using an input format. */ - public function testEmptyText() { + public function testEmptyText(): void { $view = Views::getView('watchdog'); $data = $view->storage->toArray(); $area = $data['display']['default']['display_options']['empty']['area']; diff --git a/core/modules/dblog/tests/src/Functional/FakeLogEntries.php b/core/modules/dblog/tests/src/Functional/FakeLogEntries.php index fa44d55939..66c8777d85 100644 --- a/core/modules/dblog/tests/src/Functional/FakeLogEntries.php +++ b/core/modules/dblog/tests/src/Functional/FakeLogEntries.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Functional; use Drupal\Core\Logger\RfcLogLevel; @@ -50,7 +52,7 @@ private function generateLogEntries($count, $options = []) { 'request_uri' => $base_root . \Drupal::request()->getRequestUri(), 'referer' => \Drupal::request()->server->get('HTTP_REFERER'), 'ip' => '127.0.0.1', - 'timestamp' => REQUEST_TIME, + 'timestamp' => \Drupal::time()->getRequestTime(), ]; $logger = $this->container->get('logger.dblog'); diff --git a/core/modules/dblog/tests/src/Functional/GenericTest.php b/core/modules/dblog/tests/src/Functional/GenericTest.php index 4a05f749ed..c6bfe5e608 100644 --- a/core/modules/dblog/tests/src/Functional/GenericTest.php +++ b/core/modules/dblog/tests/src/Functional/GenericTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Functional; use Drupal\Tests\system\Functional\Module\GenericModuleTestBase; diff --git a/core/modules/dblog/tests/src/Functional/UpdatePathTest.php b/core/modules/dblog/tests/src/Functional/UpdatePathTest.php index 165a394864..6d76590b88 100644 --- a/core/modules/dblog/tests/src/Functional/UpdatePathTest.php +++ b/core/modules/dblog/tests/src/Functional/UpdatePathTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Functional; use Drupal\Core\Database\Database; @@ -25,7 +27,7 @@ protected function setDatabaseDumpFiles() { /** * Tests that, after update 10101, the 'wid' column can be a 64-bit integer. */ - public function testLogEntryWithBigId() { + public function testLogEntryWithBigId(): void { if (PHP_INT_SIZE < 8) { $this->markTestSkipped('This test can only be run on a system that supports 64-bit integers (i.e., PHP_INT_SIZE is 8).'); } diff --git a/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php b/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php index 5364e134de..afb79e42b2 100644 --- a/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php +++ b/core/modules/dblog/tests/src/Kernel/ConnectionFailureTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel; use Drupal\Core\Database\Database; @@ -20,7 +22,7 @@ class ConnectionFailureTest extends KernelTestBase { /** * Tests logging of connection failures. */ - public function testConnectionFailureLogging() { + public function testConnectionFailureLogging(): void { $this->installSchema('dblog', ['watchdog']); // MySQL errors like "1153 - Got a packet bigger than 'max_allowed_packet' diff --git a/core/modules/dblog/tests/src/Kernel/DbLogControllerTest.php b/core/modules/dblog/tests/src/Kernel/DbLogControllerTest.php index 8c74084544..327751f651 100644 --- a/core/modules/dblog/tests/src/Kernel/DbLogControllerTest.php +++ b/core/modules/dblog/tests/src/Kernel/DbLogControllerTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel; use Drupal\dblog\Controller\DbLogController; @@ -29,7 +31,7 @@ protected function setUp(): void { /** * Tests links with non latin characters. */ - public function testNonLatinCharacters() { + public function testNonLatinCharacters(): void { $link = 'hello- 科州的小九寨沟绝美高山湖泊酱凉拌素鸡照烧鸡黄玫瑰 @@ -62,7 +64,7 @@ public function testNonLatinCharacters() { /** * Tests corrupted log entries can still display available data. */ - public function testDbLogCorrupted() { + public function testDbLogCorrupted(): void { $dblog_controller = DbLogController::create($this->container); // Check message with properly serialized data. diff --git a/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php b/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php index 778315048c..bb5251b730 100644 --- a/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php +++ b/core/modules/dblog/tests/src/Kernel/DbLogFormInjectionTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel; use Drupal\Core\DependencyInjection\DependencySerializationTrait; @@ -26,9 +28,7 @@ class DbLogFormInjectionTest extends KernelTestBase implements FormInterface { protected $logger; /** - * Modules to enable. - * - * @var array + * {@inheritdoc} */ protected static $modules = ['system', 'dblog', 'user']; @@ -91,7 +91,7 @@ protected function setUp(): void { /** * Tests db log injection serialization. */ - public function testLoggerSerialization() { + public function testLoggerSerialization(): void { $form_state = new FormState(); // Forms are only serialized during POST requests. diff --git a/core/modules/dblog/tests/src/Kernel/DbLogTest.php b/core/modules/dblog/tests/src/Kernel/DbLogTest.php index 08d4c37173..9bdc36cb98 100644 --- a/core/modules/dblog/tests/src/Kernel/DbLogTest.php +++ b/core/modules/dblog/tests/src/Kernel/DbLogTest.php @@ -1,8 +1,9 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel; -use Drupal\Component\Render\FormattableMarkup; use Drupal\Core\Database\Database; use Drupal\KernelTests\KernelTestBase; use Drupal\Tests\dblog\Functional\FakeLogEntries; @@ -34,13 +35,13 @@ protected function setUp(): void { /** * Tests that cron correctly applies the database log row limit. */ - public function testDbLogCron() { + public function testDbLogCron(): void { $row_limit = 100; // Generate additional log entries. $this->generateLogEntries($row_limit + 10); // Verify that the database log row count exceeds the row limit. $count = Database::getConnection()->select('watchdog')->countQuery()->execute()->fetchField(); - $this->assertGreaterThan($row_limit, $count, new FormattableMarkup('Dblog row count of @count exceeds row limit of @limit', ['@count' => $count, '@limit' => $row_limit])); + $this->assertGreaterThan($row_limit, $count, "Dblog row count of $count exceeds row limit of $row_limit"); // Get the number of enabled modules. Cron adds a log entry for each module. $implementation_count = 0; @@ -52,12 +53,28 @@ function (callable $hook, string $module) use (&$implementation_count) { ); $cron_detailed_count = $this->runCron(); - $this->assertEquals($implementation_count + 2, $cron_detailed_count, new FormattableMarkup('Cron added @count of @expected new log entries', ['@count' => $cron_detailed_count, '@expected' => $implementation_count + 2])); + $expected_count = $implementation_count + 2; + $this->assertEquals($expected_count, $cron_detailed_count, "Cron added $cron_detailed_count of $expected_count new log entries"); // Test disabling of detailed cron logging. - $this->config('system.cron')->set('logging', 0)->save(); + $this->config('system.cron')->set('logging', FALSE)->save(); $cron_count = $this->runCron(); - $this->assertEquals(1, $cron_count, new FormattableMarkup('Cron added @count of @expected new log entries', ['@count' => $cron_count, '@expected' => 1])); + $this->assertEquals(1, $cron_count, "Cron added $cron_count of 1 new log entries"); + } + + /** + * Tests that only valid placeholders are stored in the variables column. + */ + public function testInvalidPlaceholders(): void { + \Drupal::logger('my_module')->warning('Hello @string @array @object', ['@string' => '', '@array' => [], '@object' => new \stdClass()]); + $variables = \Drupal::database() + ->select('watchdog', 'w') + ->fields('w', ['variables']) + ->orderBy('wid', 'DESC') + ->range(0, 1) + ->execute() + ->fetchField(); + $this->assertSame(serialize(['@string' => '']), $variables); } /** diff --git a/core/modules/dblog/tests/src/Kernel/Migrate/d6/MigrateDblogConfigsTest.php b/core/modules/dblog/tests/src/Kernel/Migrate/d6/MigrateDblogConfigsTest.php index 1856d5cc75..0e02c879c0 100644 --- a/core/modules/dblog/tests/src/Kernel/Migrate/d6/MigrateDblogConfigsTest.php +++ b/core/modules/dblog/tests/src/Kernel/Migrate/d6/MigrateDblogConfigsTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel\Migrate\d6; use Drupal\Tests\SchemaCheckTestTrait; @@ -35,7 +37,7 @@ protected function setUp(): void { /** * Tests migration of dblog variables to dblog.settings.yml. */ - public function testDblogSettings() { + public function testDblogSettings(): void { $config = $this->config('dblog.settings'); $this->assertSame(10000, $config->get('row_limit')); $this->assertConfigSchema(\Drupal::service('config.typed'), 'dblog.settings', $config->get()); diff --git a/core/modules/dblog/tests/src/Kernel/Migrate/d7/MigrateDblogConfigsTest.php b/core/modules/dblog/tests/src/Kernel/Migrate/d7/MigrateDblogConfigsTest.php index f88dbd3543..92e338cebc 100644 --- a/core/modules/dblog/tests/src/Kernel/Migrate/d7/MigrateDblogConfigsTest.php +++ b/core/modules/dblog/tests/src/Kernel/Migrate/d7/MigrateDblogConfigsTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel\Migrate\d7; use Drupal\Tests\migrate_drupal\Kernel\d7\MigrateDrupal7TestBase; @@ -28,7 +30,7 @@ protected function setUp(): void { /** * Tests migration of dblog variables to dblog.settings.yml. */ - public function testDblogSettings() { + public function testDblogSettings(): void { $config = $this->config('dblog.settings'); $this->assertSame(10000, $config->get('row_limit')); } diff --git a/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php b/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php index 6ab50e91ec..ee75d0738b 100644 --- a/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php +++ b/core/modules/dblog/tests/src/Kernel/Views/ViewsIntegrationTest.php @@ -1,5 +1,7 @@ <?php +declare(strict_types=1); + namespace Drupal\Tests\dblog\Kernel\Views; use Drupal\Component\Render\FormattableMarkup; @@ -48,7 +50,7 @@ protected function setUp($import_test_views = TRUE): void { /** * Tests the messages escaping functionality. */ - public function testMessages() { + public function testMessages(): void { // Remove the watchdog entries added by the potential batch process. $this->container->get('database')->truncate('watchdog')->execute(); @@ -92,7 +94,7 @@ public function testMessages() { /** * Tests the relationship with the users_field_data table. */ - public function testRelationship() { + public function testRelationship(): void { $view = Views::getView('dblog_integration_test'); $view->setDisplay('page_1'); // The uid relationship should now join to the {users_field_data} table. @@ -105,7 +107,7 @@ public function testRelationship() { /** * Tests views can be filtered by severity and log type. */ - public function testFiltering() { + public function testFiltering(): void { // Remove the watchdog entries added by the potential batch process. $this->container->get('database')->truncate('watchdog')->execute(); $this->createLogEntries();
- 🇺🇸United States kkaya
Thank you very much @cilefen! Taking steps to reproduce, it looks like a conflict with the monolog module, so can close this ticket. Appreciate your help.