These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | |||
| 3 | namespace Drupal\mongodb_watchdog\Controller; |
||
| 4 | |||
| 5 | use Drupal\Component\Utility\SafeMarkup; |
||
| 6 | use Drupal\Component\Utility\Unicode; |
||
| 7 | use Drupal\Core\Controller\ControllerBase; |
||
| 8 | use Drupal\Core\Datetime\DateFormatterInterface; |
||
| 9 | use Drupal\Core\Extension\ModuleHandlerInterface; |
||
| 10 | use Drupal\Core\Form\FormBuilderInterface; |
||
| 11 | use Drupal\Core\Link; |
||
| 12 | use Drupal\Core\Logger\RfcLogLevel; |
||
| 13 | use Drupal\mongodb_watchdog\Event; |
||
| 14 | use Drupal\mongodb_watchdog\EventTemplate; |
||
| 15 | use Drupal\mongodb_watchdog\Form\OverviewFilterForm; |
||
| 16 | use Drupal\mongodb_watchdog\Logger; |
||
| 17 | use Psr\Log\LogLevel; |
||
| 18 | use Psr\Log\LoggerInterface; |
||
| 19 | use Symfony\Component\DependencyInjection\ContainerInterface; |
||
| 20 | use Symfony\Component\HttpFoundation\Request; |
||
| 21 | |||
| 22 | /** |
||
| 23 | * Class OverviewController provides the main MongoDB Watchdog report page. |
||
| 24 | */ |
||
| 25 | class OverviewController extends ControllerBase { |
||
| 26 | const EVENT_TYPE_MAP = [ |
||
| 27 | 'typeMap' => [ |
||
| 28 | 'array' => 'array', |
||
| 29 | 'document' => 'array', |
||
| 30 | 'root' => 'Drupal\mongodb_watchdog\Event', |
||
| 31 | ], |
||
| 32 | ]; |
||
| 33 | const SEVERITY_PREFIX = 'mongodb_watchdog__severity_'; |
||
| 34 | const SEVERITY_CLASSES = [ |
||
| 35 | RfcLogLevel::DEBUG => self::SEVERITY_PREFIX . LogLevel::DEBUG, |
||
| 36 | RfcLogLevel::INFO => self::SEVERITY_PREFIX . LogLevel::INFO, |
||
| 37 | RfcLogLevel::NOTICE => self::SEVERITY_PREFIX . LogLevel::NOTICE, |
||
| 38 | RfcLogLevel::WARNING => self::SEVERITY_PREFIX . LogLevel::WARNING, |
||
| 39 | RfcLogLevel::ERROR => self::SEVERITY_PREFIX . LogLevel::ERROR, |
||
| 40 | RfcLogLevel::CRITICAL => self::SEVERITY_PREFIX . LogLevel::CRITICAL, |
||
| 41 | RfcLogLevel::ALERT => self::SEVERITY_PREFIX . LogLevel::ALERT, |
||
| 42 | RfcLogLevel::EMERGENCY => self::SEVERITY_PREFIX . LogLevel::EMERGENCY, |
||
| 43 | ]; |
||
| 44 | |||
| 45 | /** |
||
| 46 | * The core date.formatter service. |
||
| 47 | * |
||
| 48 | * @var \Drupal\Core\Datetime\DateFormatterInterface |
||
| 49 | */ |
||
| 50 | protected $dateFormatter; |
||
| 51 | |||
| 52 | /** |
||
| 53 | * The form builder service. |
||
| 54 | * |
||
| 55 | * @var \Drupal\Core\Form\FormBuilderInterface |
||
| 56 | */ |
||
| 57 | protected $formBuilder; |
||
| 58 | |||
| 59 | /** |
||
| 60 | * The items_per_page configuration value. |
||
| 61 | * |
||
| 62 | * @var int |
||
| 63 | */ |
||
| 64 | protected $itemsPerPage; |
||
| 65 | |||
| 66 | /** |
||
| 67 | * The core logger channel, to log intervening events. |
||
| 68 | * |
||
| 69 | * @var \Psr\Log\LoggerInterface |
||
| 70 | */ |
||
| 71 | protected $logger; |
||
| 72 | |||
| 73 | /** |
||
| 74 | * The module handler service. |
||
| 75 | * |
||
| 76 | * @var \Drupal\Core\Extension\ModuleHandlerInterface |
||
| 77 | */ |
||
| 78 | protected $moduleHandler; |
||
| 79 | |||
| 80 | /** |
||
| 81 | * The length of the disk path to DRUPAL_ROOT. |
||
| 82 | * |
||
| 83 | * @var int |
||
| 84 | * |
||
| 85 | * @see \Drupal\mongodb_watchdog\Controller\OverviewController::getEventSource() |
||
| 86 | */ |
||
| 87 | protected $rootLength; |
||
| 88 | |||
| 89 | /** |
||
| 90 | * The MongoDB logger, to load events. |
||
| 91 | * |
||
| 92 | * @var \Drupal\mongodb_watchdog\Logger |
||
| 93 | */ |
||
| 94 | protected $watchdog; |
||
| 95 | |||
| 96 | /** |
||
| 97 | * Constructor. |
||
| 98 | * |
||
| 99 | * @param \Psr\Log\LoggerInterface $logger |
||
| 100 | * The logger service, to log intervening events. |
||
| 101 | * @param \Drupal\mongodb_watchdog\Logger $watchdog |
||
| 102 | * The MongoDB logger, to load stored events. |
||
| 103 | * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler |
||
| 104 | * A module handler. |
||
| 105 | * @param \Drupal\Core\Form\FormBuilderInterface $form_builder |
||
| 106 | * The form builder service. |
||
| 107 | * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter |
||
| 108 | * The core date_formatter service. |
||
| 109 | * @param int $items_per_page |
||
| 110 | * The items_per_page configuration value. |
||
| 111 | */ |
||
| 112 | public function __construct( |
||
| 113 | LoggerInterface $logger, |
||
| 114 | Logger $watchdog, |
||
| 115 | ModuleHandlerInterface $module_handler, |
||
| 116 | FormBuilderInterface $form_builder, |
||
| 117 | DateFormatterInterface $date_formatter, |
||
| 118 | $items_per_page) { |
||
| 119 | $this->dateFormatter = $date_formatter; |
||
| 120 | $this->formBuilder = $form_builder; |
||
| 121 | $this->logger = $logger; |
||
| 122 | $this->moduleHandler = $module_handler; |
||
| 123 | $this->watchdog = $watchdog; |
||
| 124 | |||
| 125 | $this->itemsPerPage = $items_per_page; |
||
| 126 | |||
| 127 | // Add terminal "/". |
||
| 128 | $this->rootLength = Unicode::strlen(DRUPAL_ROOT); |
||
| 129 | |||
| 130 | } |
||
| 131 | |||
| 132 | /** |
||
| 133 | * {@inheritdoc} |
||
| 134 | */ |
||
| 135 | public static function create(ContainerInterface $container) { |
||
| 136 | /** @var \Drupal\Core\Datetime\DateFormatterInterface $date_formatter */ |
||
| 137 | $date_formatter = $container->get('date.formatter'); |
||
| 138 | |||
| 139 | /** @var \Drupal\Core\Form\FormBuilderInterface $form_builder */ |
||
| 140 | $form_builder = $container->get('form_builder'); |
||
| 141 | |||
| 142 | /** @var \Psr\Log\LoggerInterface $logger */ |
||
| 143 | $logger = $container->get('logger.channel.mongodb_watchdog'); |
||
| 144 | |||
| 145 | /** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */ |
||
| 146 | $module_handler = $container->get('module_handler'); |
||
| 147 | |||
| 148 | /** @var \Drupal\mongodb_watchdog\Logger $logger */ |
||
| 149 | $watchdog = $container->get('mongodb.logger'); |
||
| 150 | |||
| 151 | /** @var \Drupal\Core\Config\ConfigFactoryInterface $config_factory */ |
||
| 152 | $config_factory = $container->get('config.factory'); |
||
| 153 | $items_per_page = $config_factory->get('mongodb_watchdog.settings')->get('items_per_page'); |
||
| 154 | |||
| 155 | return new static($logger, $watchdog, $module_handler, $form_builder, $date_formatter, $items_per_page); |
||
| 156 | } |
||
| 157 | |||
| 158 | /** |
||
| 159 | * Build the link to the event or top report for the event template. |
||
| 160 | * |
||
| 161 | * @param \Drupal\mongodb_watchdog\EventTemplate $template |
||
| 162 | * The event template for which to buildl the link. |
||
| 163 | * |
||
| 164 | * @return string |
||
| 165 | * An internal link in string form. |
||
| 166 | */ |
||
| 167 | protected function getEventLink(EventTemplate $template) { |
||
| 168 | switch ($template->type) { |
||
| 169 | case 'page not found': |
||
| 170 | $cell = Link::createFromRoute(t('( Top 404 )'), 'mongodb_watchdog.reports.top404'); |
||
| 171 | break; |
||
| 172 | |||
| 173 | case 'access denied': |
||
| 174 | $cell = Link::createFromRoute(t('( Top 403 )'), 'mongodb_watchdog.reports.top403'); |
||
| 175 | break; |
||
| 176 | |||
| 177 | default: |
||
| 178 | // Limited-length message. |
||
| 179 | $message = Unicode::truncate(strip_tags(SafeMarkup::format($template->message, [])), 56, TRUE, TRUE); |
||
| 180 | $cell = Link::createFromRoute($message, 'mongodb_watchdog.reports.detail', [ |
||
| 181 | 'event_template' => $template->_id, |
||
| 182 | ]); |
||
| 183 | break; |
||
| 184 | } |
||
| 185 | |||
| 186 | return $cell; |
||
| 187 | } |
||
| 188 | |||
| 189 | /** |
||
| 190 | * Get the location in source code where the event was logged. |
||
| 191 | * |
||
| 192 | * @param \Drupal\mongodb_watchdog\EventTemplate $template |
||
| 193 | * The template for which to find a source location. |
||
| 194 | * |
||
| 195 | * @return array |
||
| 196 | * A render array for the source location, possibly empty or wrong. |
||
| 197 | */ |
||
| 198 | protected function getEventSource(EventTemplate $template) { |
||
| 199 | if (in_array($template->type, TopController::TYPES)) { |
||
| 200 | return ''; |
||
| 201 | } |
||
| 202 | |||
| 203 | $event_collection = $this->watchdog->eventCollection($template->_id); |
||
| 204 | $event = $event_collection->findOne([], static::EVENT_TYPE_MAP); |
||
| 205 | if (!($event instanceof Event)) { |
||
| 206 | return ''; |
||
| 207 | } |
||
| 208 | |||
| 209 | $file = $event->variables['%file'] ?? ''; |
||
| 210 | if ($file && strncmp($file, DRUPAL_ROOT, $this->rootLength) === 0) { |
||
| 211 | $hover = Unicode::substr($file, $this->rootLength + 1); |
||
| 212 | $file = Unicode::truncate(basename($file), 30); |
||
| 213 | } |
||
| 214 | else { |
||
| 215 | $hover = NULL; |
||
| 216 | } |
||
| 217 | |||
| 218 | $line = $event->variables['%line'] ?? NULL; |
||
| 219 | $cell = [ |
||
| 220 | '#type' => 'html_tag', |
||
| 221 | '#tag' => 'span', |
||
| 222 | '#value' => "${file}#${line}", |
||
| 223 | ]; |
||
| 224 | |||
| 225 | if ($hover) { |
||
| 226 | $cell['#attributes'] = [ |
||
| 227 | 'class' => 'mongodb_watchdog__code_path', |
||
| 228 | 'title' => $hover, |
||
| 229 | ]; |
||
| 230 | } |
||
| 231 | |||
| 232 | return $cell; |
||
| 233 | } |
||
| 234 | |||
| 235 | /** |
||
| 236 | * Controller for mongodb_watchdog.overview. |
||
| 237 | * |
||
| 238 | * @return array |
||
| 239 | * A render array. |
||
| 240 | */ |
||
| 241 | public function overview(Request $request) { |
||
| 242 | $page = $this->setupPager($request); |
||
| 243 | |||
| 244 | $ret = [ |
||
| 245 | 'filter_form' => $this->formBuilder->getForm('Drupal\mongodb_watchdog\Form\OverviewFilterForm'), |
||
| 246 | 'rows' => $this->overviewRows($page), |
||
| 247 | 'pager' => [ |
||
| 248 | '#type' => 'pager', |
||
| 249 | ], |
||
| 250 | '#attached' => [ |
||
| 251 | 'library' => ['mongodb_watchdog/styling'], |
||
| 252 | ], |
||
| 253 | ]; |
||
| 254 | |||
| 255 | return $ret; |
||
| 256 | } |
||
| 257 | |||
| 258 | /** |
||
| 259 | * Build a table from the event rows. |
||
| 260 | * |
||
| 261 | * @param int $page |
||
| 262 | * The number of the page to display. |
||
| 263 | * |
||
| 264 | * @return array |
||
| 265 | * A render array. |
||
| 266 | */ |
||
| 267 | public function overviewRows($page) { |
||
| 268 | $header = [ |
||
| 269 | t('#'), |
||
| 270 | t('Latest'), |
||
| 271 | t('Severity'), |
||
| 272 | t('Type'), |
||
| 273 | t('Message'), |
||
| 274 | t('Source'), |
||
| 275 | ]; |
||
| 276 | $rows = []; |
||
| 277 | $levels = RfcLogLevel::getLevels(); |
||
| 278 | $filters = $_SESSION[OverviewFilterForm::SESSION_KEY] ?? NULL; |
||
| 279 | $skip = $page * $this->itemsPerPage; |
||
| 280 | $limit = $this->itemsPerPage; |
||
| 281 | $cursor = $this->watchdog->templates($filters['type'] ?? [], $filters['severity'] ?? [], $skip, $limit); |
||
| 282 | |||
| 283 | /** @var \Drupal\mongodb_watchdog\EventTemplate $template */ |
||
| 284 | foreach ($cursor as $template) { |
||
| 285 | $row = []; |
||
| 286 | $row[] = $template->count; |
||
| 287 | $row[] = $this->dateFormatter->format($template->changed, 'short'); |
||
| 288 | $row[] = [ |
||
| 289 | 'class' => static::SEVERITY_CLASSES[$template->severity], |
||
| 290 | 'data' => $levels[$template->severity], |
||
| 291 | ]; |
||
| 292 | $row[] = $template->type; |
||
| 293 | $row[] = $this->getEventLink($template); |
||
| 294 | $row[] = [ |
||
| 295 | 'data' => $this->getEventSource($template, $row), |
||
| 296 | ]; |
||
| 297 | |||
| 298 | $rows[] = $row; |
||
| 299 | } |
||
| 300 | |||
| 301 | return [ |
||
| 302 | '#type' => 'table', |
||
| 303 | '#header' => $header, |
||
| 304 | '#rows' => $rows, |
||
| 305 | ]; |
||
| 306 | } |
||
| 307 | |||
| 308 | /** |
||
| 309 | * Set up the templates pager. |
||
| 310 | * |
||
| 311 | * @param \Symfony\Component\HttpFoundation\Request $request |
||
| 312 | * The current request. |
||
| 313 | * |
||
| 314 | * @return int |
||
| 315 | * The number of the page to display, starting at 0. |
||
| 316 | */ |
||
| 317 | View Code Duplication | public function setupPager(Request $request) { |
|
|
0 ignored issues
–
show
|
|||
| 318 | $count = $this->watchdog->templatesCount(); |
||
| 319 | $height = $this->itemsPerPage; |
||
| 320 | pager_default_initialize($count, $height); |
||
| 321 | |||
| 322 | $page = intval($request->query->get('page')); |
||
| 323 | if ($page < 0) { |
||
| 324 | $page = 0; |
||
| 325 | } |
||
| 326 | else { |
||
| 327 | $page_max = intval(min(ceil($count / $height), PHP_INT_MAX) - 1); |
||
| 328 | if ($page > $page_max) { |
||
| 329 | $page = $page_max; |
||
| 330 | } |
||
| 331 | } |
||
| 332 | |||
| 333 | return $page; |
||
| 334 | } |
||
| 335 | |||
| 336 | } |
||
| 337 |
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.
You can also find more detailed suggestions in the “Code” section of your repository.