Make dblog entities
37 open threads
37 open threads
Merge request reports
Activity
added 2 commits
added 1 commit
- 829bef17 - Fix MediaSourceOEmbedVideoTest related dblog test. Add alias for dblog.formatter service
added 303 commits
-
829bef17...b155910d - 302 commits from branch
project:11.x
- ee48cc64 - Merge branch drupal:11.x into 2401463-dblog-entities-D11
-
829bef17...b155910d - 302 commits from branch
60 60 * The form builder service. 61 61 */ 62 62 public function __construct(Connection $database, ModuleHandlerInterface $module_handler, DateFormatterInterface $date_formatter, FormBuilderInterface $form_builder) { 63 @trigger_error(__CLASS__ . ' is deprecated in drupal:10.1.0 and is removed from drupal:11.0.0. Use the \Drupal\dblog\DblogEntryListBuilder class instead. See https://www.drupal.org/node/3236383', E_USER_DEPRECATED); 41 } 42 43 /** 44 * Shows the most frequent log messages of a given event type. 45 * 46 * Messages are not truncated on this page because events detailed herein do 47 * not have links to a detailed view. 48 * 49 * @param string $type 50 * Type of database log events to display (e.g., 'search'). 51 * 52 * @return array 53 * A build array in the format expected by 54 * \Drupal\Core\Render\RendererInterface::render(). 55 */ 56 public function list(string $type) { - core/modules/dblog/src/Entity/DblogEntry.php 0 → 100644
44 * internal = TRUE, 45 * entity_keys = { 46 * "id" = "wid", 47 * }, 48 * links = { 49 * "canonical" = "/admin/reports/dblog/event/{dblog}", 50 * "collection" = "/admin/reports/dblog", 51 * } 52 * ) 53 */ 54 final class DblogEntry extends ContentEntityBase implements DblogEntryInterface { 55 56 /** 57 * {@inheritdoc} 58 */ 59 public static function baseFieldDefinitions(EntityTypeInterface $entity_type) { 5 use Drupal\Core\Access\AccessResult; 6 use Drupal\Core\Entity\EntityAccessControlHandler; 7 use Drupal\Core\Entity\EntityInterface; 8 use Drupal\Core\Session\AccountInterface; 9 10 /** 11 * Defines the access control handler for the dblog entry entity type. 12 * 13 * @see \Drupal\dblog\Entity\DblogEntry 14 */ 15 class DblogEntryAccessControllerHandler extends EntityAccessControlHandler { 16 17 /** 18 * {@inheritdoc} 19 */ 20 protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { 12 * 13 * @see \Drupal\dblog\Entity\DblogEntry 14 */ 15 class DblogEntryAccessControllerHandler extends EntityAccessControlHandler { 16 17 /** 18 * {@inheritdoc} 19 */ 20 protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { 21 return AccessResult::allowedIfHasPermission($account, 'access site reports'); 22 } 23 24 /** 25 * {@inheritdoc} 26 */ 27 public function createAccess($entity_bundle = NULL, ?AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) { 27 public function createAccess($entity_bundle = NULL, ?AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE) { 27 public function createAccess($entity_bundle = NULL, ?AccountInterface $account = NULL, array $context = [], $return_as_object = FALSE): AccessResultInterface {
63 * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type 64 * The entity type definition. 65 * @param \Drupal\Core\Entity\EntityStorageInterface $storage 66 * The entity storage class. 67 * @param \Symfony\Component\HttpFoundation\Request $current_request 68 * The current request. 69 * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter 70 * The date formatter service. 71 * @param \Drupal\dblog\DblogFormatterInterface $dblog_formatter 72 * The dblog formatter service. 73 * @param \Drupal\Core\Form\FormBuilderInterface $form_builder 74 * The form builder. 75 * @param \Drupal\Core\Entity\EntityStorageInterface $user_storage 76 * The user storage service. 77 */ 78 public function __construct(EntityTypeInterface $entity_type, EntityStorageInterface $storage, Request $current_request, DateFormatterInterface $date_formatter, DblogFormatterInterface $dblog_formatter, FormBuilderInterface $form_builder, EntityStorageInterface $user_storage) { 121 if ($this->currentRequest->query->has('order')) { 122 // Allow the entity query to sort using the table header. 123 $header = $this->buildHeader(); 124 $query->tableSort($header); 125 } 126 else { 127 $query->sort('wid', 'DESC'); 128 } 129 130 return $query->execute(); 131 } 132 133 /** 134 * {@inheritdoc} 135 */ 136 public function buildHeader() { 91 public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { 92 return new static( 93 $entity_type, 94 $container->get('entity_type.manager')->getStorage($entity_type->id()), 95 $container->get('request_stack')->getCurrentRequest(), 96 $container->get('date.formatter'), 97 $container->get('dblog.formatter'), 98 $container->get('form_builder'), 99 $container->get('entity_type.manager')->getStorage('user'), 100 ); 101 } 102 103 /** 104 * {@inheritdoc} 105 */ 106 protected function getEntityIds() { 159 ], 160 'uid' => [ 161 'data' => $this->t('User'), 162 'class' => [RESPONSIVE_PRIORITY_MEDIUM], 163 'specifier' => 'uid', 164 'field' => 'uid', 165 ], 166 ]; 167 168 return $header + parent::buildHeader(); 169 } 170 171 /** 172 * {@inheritdoc} 173 */ 174 public function buildRow(EntityInterface $entity) { 51 */ 52 protected $dblogFormatter; 53 54 /** 55 * Constructs a new dblog entry view builder. 56 * 57 * @param \Drupal\Core\Render\RendererInterface $renderer 58 * The renderer service. 59 * @param \Drupal\Core\Entity\EntityStorageInterface $user_storage 60 * The user storage service. 61 * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter 62 * The date formatter service. 63 * @param \Drupal\dblog\DblogFormatterInterface $dblog_formatter 64 * The dblog formatter service. 65 */ 66 public function __construct(RendererInterface $renderer, EntityStorageInterface $user_storage, DateFormatterInterface $date_formatter, DblogFormatterInterface $dblog_formatter) { 160 public function getCacheTags() { 161 // Intentionally empty. 162 return []; 163 } 164 165 /** 166 * Creates a Link object if the provided URI is valid. 167 * 168 * @param string|null $uri 169 * The uri string to convert into link if valid. 170 * 171 * @return \Drupal\Core\Link|string|null 172 * Return a Link object if the uri can be converted as a link. In case of 173 * empty uri or invalid, fallback to the provided $uri. 174 */ 175 protected function createLink($uri) { 15 16 /** 17 * {@inheritdoc} 18 */ 19 protected function setDatabaseDumpFiles() { 20 $this->databaseDumpFiles = [ 21 __DIR__ . '/../../../../../system/tests/fixtures/update/drupal-10.3.0.filled.standard.php.gz', 22 ]; 23 } 24 25 /** 26 * Tests that dblog view row style is updated properly. 27 * 28 * @group legacy 29 */ 30 public function testSeverityUpdate() { 4 5 namespace Drupal\Tests\dblog\Functional\Update; 6 7 use Drupal\FunctionalTests\Update\UpdatePathTestBase; 8 9 /** 10 * Tests the upgrade path for modifying dblog row styles. 11 * 12 * @group Update 13 */ 14 class DblogViewSeverityUpdateTest extends UpdatePathTestBase { 15 16 /** 17 * {@inheritdoc} 18 */ 19 protected function setDatabaseDumpFiles() { 25 protected static $modules = ['dblog', 'system', 'user']; 26 27 /** 28 * {@inheritdoc} 29 */ 30 protected function setUp(): void { 31 parent::setUp(); 32 33 $this->installSchema('dblog', ['watchdog']); 34 $this->installConfig(['system']); 35 } 36 37 /** 38 * Tests creation of log entries. 39 */ 40 public function testCreate() { 63 64 $this->assertEquals('', $log->getReferer()); 65 66 $this->assertEquals('127.0.0.1', $log->getHostname()); 67 68 $this->assertEquals(1632269259, $log->getTimestamp()); 69 70 $this->expectException(EntityStorageException::class); 71 $this->expectExceptionMessage('Use dblog.logger service to create log entities.'); 72 $log->save(); 73 } 74 75 /** 76 * Tests loading a log entry. 77 */ 78 public function testLoad() { 75 /** 76 * Tests loading a log entry. 77 */ 78 public function testLoad() { 79 $this->generateLogEntries(1); 80 $log = DblogEntry::load(1); 81 82 $this->assertEquals(1, $log->id()); 83 $this->assertEquals('Dblog test log message Entry #0', $log->get('message')->getString()); 84 $this->assertEquals(RfcLogLevel::NOTICE, $log->getSeverity()); 85 } 86 87 /** 88 * Tests deletion of log entries. 89 */ 90 public function testDelete() { 85 } 86 87 /** 88 * Tests deletion of log entries. 89 */ 90 public function testDelete() { 91 $this->generateLogEntries(1); 92 $log = DblogEntry::load(1); 93 $log->delete(); 94 $this->assertNull(DblogEntry::load(1)); 95 } 96 97 /** 98 * Tests that the log entries cannot be updated once created. 99 */ 100 public function testUpdate() { 98 * Tests that the log entries cannot be updated once created. 99 */ 100 public function testUpdate() { 101 $this->generateLogEntries(1); 102 $log = DblogEntry::load(1); 103 104 $this->expectException(EntityStorageException::class); 105 $this->expectExceptionMessage('Dblog entries are read only entities. Saving them once created is not allowed.'); 106 107 $log->save(); 108 } 109 110 /** 111 * Tests common dblog fields. 112 */ 113 public function testHasField() { 123 'referer', 124 'hostname', 125 'timestamp', 126 ]; 127 $log = DblogEntry::create(); 128 foreach ($fields as $field_name) { 129 $this->assertTrue($log->hasField($field_name)); 130 } 131 132 $this->assertFalse($log->hasField('field_message')); 133 } 134 135 /** 136 * Tests field definitions. 137 */ 138 public function testFieldDefinition() { 176 'message' => '<script>Test</script>', 177 'variables' => serialize([]), 178 ]); 179 $this->assertEquals($log->getFormattedMessage($dblog_formatter), 'Test'); 180 181 $log = DblogEntry::create([ 182 'message' => 'Testing @module module', 183 'variables' => serialize(['@module' => 'dblog']), 184 ]); 185 $this->assertEquals($log->getFormattedMessage($dblog_formatter), 'Testing dblog module'); 186 } 187 188 /** 189 * Tests validate methods. 190 */ 191 public function testValidate() { 10 11 /** 12 * Test the dblog entries storage. 13 * 14 * @group dblog 15 */ 16 class DbLogEntryStorageTest extends KernelTestBase { 17 18 use FakeLogEntries; 19 20 /** 21 * The dblog storage. 22 * 23 * @var \Drupal\dblog\DblogEntryStorageInterface 24 */ 25 protected $storage; 17 18 use FakeLogEntries; 19 20 /** 21 * The dblog storage. 22 * 23 * @var \Drupal\dblog\DblogEntryStorageInterface 24 */ 25 protected $storage; 26 27 /** 28 * The dblog formatter service. 29 * 30 * @var \Drupal\dblog\DblogFormatterInterface 31 */ 32 protected $dblogFormatter; 39 /** 40 * {@inheritdoc} 41 */ 42 protected function setUp(): void { 43 parent::setUp(); 44 45 $this->installSchema('dblog', ['watchdog']); 46 $this->installConfig(['system']); 47 $this->storage = \Drupal::entityTypeManager()->getStorage('dblog'); 48 $this->dblogFormatter = \Drupal::service('dblog.formatter'); 49 } 50 51 /** 52 * Tests createInstance method. 53 */ 54 public function testCreateInstance() { 47 $this->storage = \Drupal::entityTypeManager()->getStorage('dblog'); 48 $this->dblogFormatter = \Drupal::service('dblog.formatter'); 49 } 50 51 /** 52 * Tests createInstance method. 53 */ 54 public function testCreateInstance() { 55 $this->assertEquals('dblog', $this->storage->getEntityTypeId()); 56 $this->assertEquals('Dblog entry', $this->storage->getEntityType()->getLabel()); 57 } 58 59 /** 60 * Tests deleteAll and hasData methods. 61 */ 62 public function testDeleteAll() { 69 $this->assertFalse($this->storage->hasData()); 70 71 $this->generateLogEntries(5); 72 // Delete all but the first log entry. 73 $this->storage->deleteAll(1); 74 $this->assertTrue($this->storage->hasData()); 75 $this->assertCount(1, $this->storage->loadMultiple()); 76 77 $this->expectException(\InvalidArgumentException::class); 78 $this->storage->deleteAll(-1); 79 } 80 81 /** 82 * Tests messageType method. 83 */ 84 public function testMessageTypes() { 84 public function testMessageTypes() { 85 $this->assertEquals([], $this->storage->messageTypes()); 86 $this->generateLogEntries(5); 87 $this->assertEquals(['custom' => 'custom'], $this->storage->messageTypes()); 88 89 $this->generateLogEntries(1, ['channel' => 'system']); 90 $this->assertEquals([ 91 'custom' => 'custom', 92 'system' => 'system', 93 ], $this->storage->messageTypes()); 94 } 95 96 /** 97 * Tests loadMultiple method. 98 */ 99 public function testLoadMultiple() { 118 $c = array_pop($logs); 119 $b = array_pop($logs); 120 121 // Logs can be loaded in a particular order as well. 122 $this->assertEquals('Dblog test log message Entry #1', $b->getFormattedMessage($this->dblogFormatter)); 123 $this->assertEquals('Dblog test log message Entry #0', $c->getFormattedMessage($this->dblogFormatter)); 124 $this->assertEquals('Dblog test log message Entry #2', $a->getFormattedMessage($this->dblogFormatter)); 125 126 $logs = $this->storage->loadMultiple([$a->id(), $a->id(), $a->id()]); 127 $this->assertCount(1, $logs, 'Duplicated logs id are loaded once'); 128 } 129 130 /** 131 * Tests load and loadUnchanged methods. 132 */ 133 public function testLoad() { 134 $this->generateLogEntries(3); 135 $logs = $this->storage->loadMultiple(); 136 137 $third = array_pop($logs); 138 $second = array_pop($logs); 139 $first = array_pop($logs); 140 141 $this->assertEquals($second, $this->storage->load($second->id())); 142 $this->assertNull($this->storage->load(100)); 143 $this->assertEquals($second, $this->storage->loadUnchanged($second->id())); 144 } 145 146 /** 147 * Tests loadByProperties method. 148 */ 149 public function testLoadByProperties() { 164 $logs = $this->storage->loadByProperties([ 165 'type' => 'php', 166 'severity' => RfcLogLevel::WARNING, 167 ]); 168 $this->assertCount(0, $logs); 169 170 $logs = $this->storage->loadByProperties([ 171 'type' => ['php', 'page not found'], 172 ]); 173 $this->assertCount(3, $logs); 174 } 175 176 /** 177 * Tests hasData method. 178 */ 179 public function testHasData() { 173 $this->assertCount(3, $logs); 174 } 175 176 /** 177 * Tests hasData method. 178 */ 179 public function testHasData() { 180 $this->assertFalse($this->storage->hasData()); 181 $this->generateLogEntries(1); 182 $this->assertTrue($this->storage->hasData()); 183 } 184 185 /** 186 * Tests aggregated query and get query methods. 187 */ 188 public function testAggregateCount() { 186 * Tests aggregated query and get query methods. 187 */ 188 public function testAggregateCount() { 189 $this->generateLogEntries(2); 190 191 $result = (int) $this->storage->getQuery()->count()->accessCheck(FALSE)->execute(); 192 $this->assertEquals(2, $result); 193 194 $result = (int) $this->storage->getAggregateQuery()->count()->accessCheck(FALSE)->execute(); 195 $this->assertEquals(2, $result); 196 } 197 198 /** 199 * Tests mostFrequentLogEntries method. 200 */ 201 public function testMostFrequentLogs() { 209 } 210 } 211 $this->generateLogEntries(3, ['channel' => 'access denied']); 212 213 $most_frequent = $this->storage->mostFrequentLogEntries('page not found'); 214 $this->assertCount(2, $most_frequent, 'There are 2 aggregated log entries for type: page not found'); 215 $this->assertEquals(5, $most_frequent[0]['count']); 216 $this->assertEquals('/other', $most_frequent[0]['entry']->getFormattedMessage($this->dblogFormatter), 'Most frequent page not found log entry is: /other'); 217 $this->assertEquals(2, $most_frequent[1]['count']); 218 $this->assertEquals('/something_else', $most_frequent[1]['entry']->getFormattedMessage($this->dblogFormatter)); 219 } 220 221 /** 222 * Tests loadMostRecent method. 223 */ 224 public function testLoadMostRecent() { 19 19 * - options: Array of options for the select list for the filter. 20 20 */ 21 21 function dblog_filters() { 22 @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. See https://www.drupal.org/node/3236383', E_USER_DEPRECATED); 122 'base_table' => 'watchdog', 123 'entity_keys' => [ 124 'id' => 'wid', 125 ], 126 ]); 127 $field_storage_definitions = DblogEntry::baseFieldDefinitions($entity_type); 128 $entity_definition_update_manager->installFieldableEntityType($entity_type, $field_storage_definitions); 129 130 return t('The "Dblog entry" entity type has been installed.'); 131 } 132 } 133 134 /** 135 * Changes class used by dblog to indicate severity icons. 136 */ 137 function dblog_update_11001() { 92 76 * List of uniquely defined database log message types. 93 77 */ 94 78 function _dblog_get_message_types() { 95 return \Drupal::database()->query('SELECT DISTINCT([type]) FROM {watchdog} ORDER BY [type]') 96 ->fetchAllKeyed(0, 0); 79 @trigger_error(__FUNCTION__ . '() is deprecated in drupal:11.0.0 and is removed from drupal:12.0.0. See https://www.drupal.org/node/3236383', E_USER_DEPRECATED); 118 102 $view->element['#attached']['library'][] = 'dblog/drupal.dblog'; 119 103 } 120 104 } 105 106 /** 107 * Implements hook_module_preuninstall(). 108 */ 109 function dblog_module_preuninstall($module) {
Please register or sign in to reply