View source
<?php
namespace Drupal\redirect_404;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Database\Connection;
class SqlRedirectNotFoundStorage implements RedirectNotFoundStorageInterface {
const MAX_PATH_LENGTH = 191;
protected $database;
protected $configFactory;
public function __construct(Connection $database, ConfigFactoryInterface $config_factory) {
$this->database = $database;
$this->configFactory = $config_factory;
}
public function logRequest($path, $langcode) {
if (mb_strlen($path) > static::MAX_PATH_LENGTH) {
return;
}
if (!Unicode::validateUtf8($path)) {
return;
}
$this->database
->merge('redirect_404')
->key('path', $path)
->key('langcode', $langcode)
->expression('count', 'count + 1')
->expression('daily_count', 'daily_count + 1')
->fields([
'timestamp' => \Drupal::time()
->getRequestTime(),
'count' => 1,
'daily_count' => 1,
'resolved' => 0,
])
->execute();
}
public function resolveLogRequest($path, $langcode) {
$this->database
->update('redirect_404')
->fields([
'resolved' => 1,
])
->condition('path', $path)
->condition('langcode', $langcode)
->execute();
}
public function purgeOldRequests() {
$row_limit = $this->configFactory
->get('redirect_404.settings')
->get('row_limit');
if ($row_limit == 0) {
return;
}
$query = $this->database
->select('redirect_404', 'r404');
$query
->fields('r404', [
'timestamp',
]);
if ($this->database
->driver() == 'mysql' || $this->database
->driver() == 'pgsql') {
$query
->addExpression('floor(log(10, count))', 'count_log');
$query
->orderBy('count_log', 'DESC');
}
$query
->orderBy('timestamp', 'DESC');
$cutoff = $query
->range($row_limit, 1)
->execute()
->fetchAssoc();
if (!empty($cutoff)) {
$delete_query = $this->database
->delete('redirect_404');
if ($this->database
->driver() == 'mysql' || $this->database
->driver() == 'pgsql') {
$and_condition = $delete_query
->andConditionGroup()
->where('floor(log(10, count)) = :count_log2', [
':count_log2' => $cutoff['count_log'],
])
->condition('timestamp', $cutoff['timestamp'], '<=');
$condition = $delete_query
->orConditionGroup()
->where('floor(log(10, count)) < :count_log1', [
':count_log1' => $cutoff['count_log'],
])
->condition($and_condition);
$delete_query
->condition($condition);
}
else {
$delete_query
->condition('timestamp', $cutoff['timestamp'], '<=');
}
$delete_query
->execute();
}
}
public function listRequests(array $header = [], $search = NULL) {
$query = $this->database
->select('redirect_404', 'r404')
->extend('Drupal\\Core\\Database\\Query\\TableSortExtender')
->orderByHeader($header)
->extend('Drupal\\Core\\Database\\Query\\PagerSelectExtender')
->limit(25)
->fields('r404');
if ($search) {
$wildcard = '%' . trim(preg_replace('!\\*+!', '%', $this->database
->escapeLike($search)), '%') . '%';
$query
->condition('path', $wildcard, 'LIKE');
}
$results = $query
->condition('resolved', 0, '=')
->execute()
->fetchAll();
return $results;
}
public function resetDailyCount() {
$this->database
->update('redirect_404')
->fields([
'daily_count' => 0,
])
->execute();
}
}