diff --git a/src/services/Redirects.php b/src/services/Redirects.php index 32e8eebd..c78118b0 100644 --- a/src/services/Redirects.php +++ b/src/services/Redirects.php @@ -16,6 +16,7 @@ use craft\base\ElementInterface; use craft\base\Plugin; use craft\db\Query; +use craft\errors\ElementNotFoundException; use craft\errors\SiteNotFoundException; use craft\helpers\Db; use craft\helpers\StringHelper; @@ -24,9 +25,11 @@ use nystudio107\retour\events\RedirectResolvedEvent; use nystudio107\retour\events\ResolveRedirectEvent; use nystudio107\retour\fields\ShortLink; +use nystudio107\retour\helpers\Text as TextHelper; use nystudio107\retour\helpers\UrlHelper; use nystudio107\retour\models\StaticRedirects as StaticRedirectsModel; use nystudio107\retour\Retour; +use Throwable; use yii\base\ExitException; use yii\base\InvalidConfigException; use yii\base\InvalidRouteException; @@ -303,7 +306,7 @@ public function findRedirectMatch(string $fullUrl, string $pathOnly, $siteId = n $siteId = $currentSite->id; } else { $primarySite = Craft::$app->getSites()->primarySite; - $siteId = $primarySite->id; + $siteId = $primarySite->id; } } // Try getting the full URL redirect from the cache @@ -467,11 +470,11 @@ public function getStaticRedirect(string $fullUrl, string $pathOnly, $siteId, bo 'or', ['and', ['redirectSrcMatch' => 'pathonly'], - ['redirectSrcUrlParsed' => $pathOnly], + ['redirectSrcUrlParsed' => TextHelper::cleanupText($pathOnly)], ], ['and', ['redirectSrcMatch' => 'fullurl'], - ['redirectSrcUrlParsed' => $fullUrl], + ['redirectSrcUrlParsed' => TextHelper::cleanupText($fullUrl)], ], ]; @@ -565,38 +568,6 @@ public function getAllExactMatchRedirects(int $limit = null, int $siteId = null, return $this->getRedirectsByMatchType($limit, $siteId, 'exactmatch', $enabledOnly); } - /** - * @param int|null $limit - * @param int|null $siteId - * @param string $type - * @return array - */ - protected function getRedirectsByMatchType(int $limit = null, int $siteId = null, string $type, bool $enabledOnly = false): array - { - // Query the db table - $query = (new Query()) - ->from(['{{%retour_static_redirects}}']) - ->orderBy('redirectMatchType ASC, priority ASC'); - - if ($siteId) { - $query - ->where(['siteId' => $siteId]) - ->orWhere(['siteId' => null]); - } - - if ($limit) { - $query->limit($limit); - } - - $query->andWhere(['redirectMatchType' => $type]); - - if ($enabledOnly) { - $query->andWhere(['enabled' => 1]); - } - - return $query->all(); - } - /** * @param int|null $limit * @param int|null $siteId @@ -996,34 +967,6 @@ public function deleteRedirectById(int $id): int return $result; } - /** - * Updates an associated element short link value. - * - * @param array $redirectConfig - * @param array $existingData - */ - protected function updateAssociatedElementShortLink(array $redirectConfig, array $existingData): void - { - if (empty($redirectConfig['associatedElementId'])) { - return; - } - // Get the element and set the scenario - $associatedElement = Craft::$app->getElements()->getElementById($redirectConfig['associatedElementId']); - - if (!$associatedElement) { - return; - } - - $fieldUpdated = $this->setShortLinkFieldValue($associatedElement, $existingData['redirectSrcUrl'], $redirectConfig['redirectSrcUrl']); - - if ($fieldUpdated) { - // Prevent element from triggering an infinite loop. - ShortLink::preventShortLinkUpdates(); - Craft::$app->getElements()->saveElement($associatedElement); - ShortLink::allowShortLinkUpdates(); - } - } - /** * Save an element redirect. * @@ -1100,8 +1043,8 @@ public function getRedirectsByElementId(int $elementId, int $siteId = null) /** * Delete a short link by its ID. * - * @throws \Throwable - * @throws \craft\errors\ElementNotFoundException + * @throws Throwable + * @throws ElementNotFoundException * @throws \yii\base\Exception */ public function deleteShortlinkById(int $redirectId): bool @@ -1286,7 +1229,7 @@ public function getRedirectByRedirectSrcUrl(string $redirectSrcUrl, int $siteId // Query the db table $query = (new Query()) ->from(['{{%retour_static_redirects}}']) - ->where(['redirectSrcUrl' => $redirectSrcUrl]); + ->where(['redirectSrcUrl' => TextHelper::cleanupText($redirectSrcUrl)]); if ($siteId) { $query ->andWhere(['or', [ @@ -1321,6 +1264,66 @@ public function invalidateCaches(): void ); } + /** + * @param int|null $limit + * @param int|null $siteId + * @param string $type + * @return array + */ + protected function getRedirectsByMatchType(int $limit = null, int $siteId = null, string $type, bool $enabledOnly = false): array + { + // Query the db table + $query = (new Query()) + ->from(['{{%retour_static_redirects}}']) + ->orderBy('redirectMatchType ASC, priority ASC'); + + if ($siteId) { + $query + ->where(['siteId' => $siteId]) + ->orWhere(['siteId' => null]); + } + + if ($limit) { + $query->limit($limit); + } + + $query->andWhere(['redirectMatchType' => $type]); + + if ($enabledOnly) { + $query->andWhere(['enabled' => 1]); + } + + return $query->all(); + } + + /** + * Updates an associated element short link value. + * + * @param array $redirectConfig + * @param array $existingData + */ + protected function updateAssociatedElementShortLink(array $redirectConfig, array $existingData): void + { + if (empty($redirectConfig['associatedElementId'])) { + return; + } + // Get the element and set the scenario + $associatedElement = Craft::$app->getElements()->getElementById($redirectConfig['associatedElementId']); + + if (!$associatedElement) { + return; + } + + $fieldUpdated = $this->setShortLinkFieldValue($associatedElement, $existingData['redirectSrcUrl'], $redirectConfig['redirectSrcUrl']); + + if ($fieldUpdated) { + // Prevent element from triggering an infinite loop. + ShortLink::preventShortLinkUpdates(); + Craft::$app->getElements()->saveElement($associatedElement); + ShortLink::allowShortLinkUpdates(); + } + } + /** * Find all short link fields on an element that have a matching redirect source url and update the value * diff --git a/src/services/Statistics.php b/src/services/Statistics.php index ab1be1db..a09ac9c1 100644 --- a/src/services/Statistics.php +++ b/src/services/Statistics.php @@ -17,6 +17,7 @@ use craft\helpers\Db; use craft\helpers\UrlHelper; use DateTime; +use nystudio107\retour\helpers\Text as TextHelper; use nystudio107\retour\models\Stats as StatsModel; use nystudio107\retour\Retour; use yii\db\Exception; @@ -194,7 +195,7 @@ public function incrementStatistics(string $url, bool $handled = false, $siteId // Find any existing retour_stats record $statsConfig = (new Query()) ->from(['{{%retour_stats}}']) - ->where(['redirectSrcUrl' => $stats->redirectSrcUrl]) + ->where(['redirectSrcUrl' => TextHelper::cleanupText($stats->redirectSrcUrl)]) ->one(); // If no record is found, initialize some values if ($statsConfig === null) { @@ -275,28 +276,6 @@ public function saveStatistics(array $statsConfig): void } } - /** - * Don't trim more than a given interval, so that performance is not affected - * - * @return bool - */ - protected function rateLimited(): bool - { - $limited = false; - $now = round(microtime(true) * 1000); - $cache = Craft::$app->getCache(); - $then = $cache->get(self::LAST_STATISTICS_TRIM_CACHE_KEY); - if (($then !== false) && ($now - (int)$then < Retour::$settings->statisticsRateLimitMs)) { - $limited = true; - } - $cache->set(self::LAST_STATISTICS_TRIM_CACHE_KEY, $now, 0); - - return $limited; - } - - // Protected Methods - // ========================================================================= - /** * Trim the retour_stats db table based on the statsStoredLimit config.php * setting @@ -364,4 +343,26 @@ public function trimStatistics(int $limit = null): int return $affectedRows; } + + // Protected Methods + // ========================================================================= + + /** + * Don't trim more than a given interval, so that performance is not affected + * + * @return bool + */ + protected function rateLimited(): bool + { + $limited = false; + $now = round(microtime(true) * 1000); + $cache = Craft::$app->getCache(); + $then = $cache->get(self::LAST_STATISTICS_TRIM_CACHE_KEY); + if (($then !== false) && ($now - (int)$then < Retour::$settings->statisticsRateLimitMs)) { + $limited = true; + } + $cache->set(self::LAST_STATISTICS_TRIM_CACHE_KEY, $now, 0); + + return $limited; + } }