[FEATURE] Option to globally enable redirect hit count 97/55497/2
authorSusanne Moog <susanne.moog@typo3.com>
Mon, 29 Jan 2018 19:15:27 +0000 (20:15 +0100)
committerOliver Hader <oliver.hader@typo3.org>
Mon, 29 Jan 2018 22:14:53 +0000 (23:14 +0100)
Most websites probably use custom analytics for page
hit statistics or are not interested in the count of
hits on a redirect. Therefor the redirect hit count
has been disabled by default. The option to enable
the hit count globally via LocalConfiguration has been
added.

Change-Id: I71c57784d8c6e0f17c81b1f899aa43e91d37cd76
Resolves: #83677
Releases: master
Reviewed-on: https://review.typo3.org/55497
Tested-by: TYPO3com <no-reply@typo3.com>
Reviewed-by: Oliver Hader <oliver.hader@typo3.org>
Tested-by: Oliver Hader <oliver.hader@typo3.org>
Reviewed-by: Helmut Hummel <typo3@helhum.io>
Reviewed-by: Andreas Wolf <andreas.wolf@typo3.org>
Tested-by: Andreas Wolf <andreas.wolf@typo3.org>
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Feature-83677-GloballyDisableenableRedirectHitStatistics.rst [new file with mode: 0644]
typo3/sysext/redirects/Classes/Controller/ManagementController.php
typo3/sysext/redirects/Classes/Http/RedirectHandler.php
typo3/sysext/redirects/Classes/UserFunctions/HitCountDisplayCondition.php [new file with mode: 0644]
typo3/sysext/redirects/Configuration/TCA/sys_redirect.php
typo3/sysext/redirects/Resources/Private/Templates/Management/Overview.html

index c6bb247..e74dc3a 100644 (file)
@@ -67,7 +67,9 @@ return [
         ],
         'fileCreateMask' => '0664',
         'folderCreateMask' => '2775',
-        'features' => [],
+        'features' => [
+            'redirects.hitCount' => false
+        ],
         'createGroup' => '',
         'sitename' => 'TYPO3',
         'encryptionKey' => '',
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-83677-GloballyDisableenableRedirectHitStatistics.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-83677-GloballyDisableenableRedirectHitStatistics.rst
new file mode 100644 (file)
index 0000000..4335521
--- /dev/null
@@ -0,0 +1,30 @@
+.. include:: ../../Includes.txt
+
+=================================================================
+Feature: #83677 - Globally disable/enable redirect hit statistics
+=================================================================
+
+See :issue:`83677`
+
+Description
+===========
+
+The redirects module provides the optional feature to count hits on redirects. On most installations this will probably be achieved using analytics tools such as Google Analytics, Piwik or alike - for those not using any other ways of measuring, counting hits can be enabled with a feature switch.
+
+
+Impact
+======
+
+Redirect hit counting can be enabled by setting
+
+.. code-block:: php
+
+       'SYS' => [
+               'features' => [
+                       'redirects.hitCount' => true
+               ],
+       ],
+
+Be aware that every hit on a redirect will result in an additional SQL `UPDATE` query.
+
+.. index:: Database, Frontend, LocalConfiguration, NotScanned
\ No newline at end of file
index db8aebd..3dcc9b7 100644 (file)
@@ -21,6 +21,7 @@ use TYPO3\CMS\Backend\Routing\UriBuilder;
 use TYPO3\CMS\Backend\Template\Components\ButtonBar;
 use TYPO3\CMS\Backend\Template\ModuleTemplate;
 use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
+use TYPO3\CMS\Core\Configuration\Features;
 use TYPO3\CMS\Core\Http\HtmlResponse;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
@@ -98,10 +99,12 @@ class ManagementController
 
         $redirects = GeneralUtility::makeInstance(RedirectCacheService::class)->getAllRedirects();
         $defaultUrl = GeneralUtility::makeInstance(UrlService::class)->getDefaultUrl();
+        $showHitCounter = GeneralUtility::makeInstance(Features::class)->isFeatureEnabled('redirects.hitCount');
 
         $this->view->assignMultiple([
             'redirects' => $redirects,
             'defaultUrl' => $defaultUrl,
+            'showHitCounter' => $showHitCounter,
         ]);
     }
 
index 837cb3d..361e273 100644 (file)
@@ -19,6 +19,7 @@ use Psr\Http\Message\ResponseInterface;
 use Psr\Http\Message\UriInterface;
 use Psr\Log\LoggerAwareInterface;
 use Psr\Log\LoggerAwareTrait;
+use TYPO3\CMS\Core\Configuration\Features;
 use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\Http\RedirectResponse;
 use TYPO3\CMS\Core\Http\ServerRequestFactory;
@@ -82,7 +83,7 @@ class RedirectHandler implements LoggerAwareInterface
     protected function incrementHitCount(array $redirectRecord)
     {
         // Track the hit if not disabled
-        if ($redirectRecord['disable_hitcount']) {
+        if (!GeneralUtility::makeInstance(Features::class)->isFeatureEnabled('redirects.hitCount') || $redirectRecord['disable_hitcount']) {
             return;
         }
         $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
diff --git a/typo3/sysext/redirects/Classes/UserFunctions/HitCountDisplayCondition.php b/typo3/sysext/redirects/Classes/UserFunctions/HitCountDisplayCondition.php
new file mode 100644 (file)
index 0000000..6c6c146
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+declare(strict_types=1);
+
+namespace TYPO3\CMS\Redirects\UserFunctions;
+
+/*
+ * This file is part of the TYPO3 CMS project.
+ *
+ * It is free software; you can redistribute it and/or modify it under
+ * the terms of the GNU General Public License, either version 2
+ * of the License, or any later version.
+ *
+ * For the full copyright and license information, please read the
+ * LICENSE.txt file that was distributed with this source code.
+ *
+ * The TYPO3 project - inspiring people to share!
+ */
+
+use TYPO3\CMS\Core\Configuration\Features;
+use TYPO3\CMS\Core\Utility\GeneralUtility;
+
+/**
+ * Display condition evaluating the feature toggle "redirects.hitCount"
+ */
+class HitCountDisplayCondition
+{
+    /**
+     * Check whether the redirects hit count is globally enabled
+     *
+     * @return bool
+     */
+    public function isEnabled()
+    {
+        return GeneralUtility::makeInstance(Features::class)->isFeatureEnabled('redirects.hitCount');
+    }
+}
index 9bc88cf..1a3959d 100644 (file)
@@ -178,6 +178,7 @@ return [
                 'default' => 0,
                 'readOnly' => true
             ],
+            'displayCond' => 'USER:TYPO3\CMS\Redirects\UserFunctions\HitCountDisplayCondition->isEnabled'
         ],
         'lasthiton' => [
             'exclude' => true,
@@ -188,6 +189,7 @@ return [
                 'renderType' => 'inputDateTime',
                 'readOnly' => true
             ],
+            'displayCond' => 'USER:TYPO3\CMS\Redirects\UserFunctions\HitCountDisplayCondition->isEnabled'
         ],
         'disable_hitcount' => [
             'exclude' => true,
@@ -200,6 +202,7 @@ return [
                     ]
                 ]
             ],
+            'displayCond' => 'USER:TYPO3\CMS\Redirects\UserFunctions\HitCountDisplayCondition->isEnabled'
         ],
         'is_regexp' => [
             'exclude' => true,
index 74bcc52..d21cb39 100644 (file)
                                        <th><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:source_host"/></th>
                                        <th><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:source_path"/></th>
                                        <th><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:destination"/></th>
-                                       <th># <f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hits"/></th>
-                                       <th><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_last"/></th>
+                                       <f:if condition="{showHitCounter}">
+                                               <th># <f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hits"/></th>
+                                               <th><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_last"/></th>
+                                       </f:if>
                                        <th></th>
                                </tr>
                        </thead>
                                                                                <a href="{rd:editRecord(command: 'edit', uid: redirect.uid)}" title="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_mod_web_list.xlf:edit')}">{redirect.source_path}</a>
                                                                        </td>
                                                                        <td><f:link.typolink parameter="{redirect.target}" target="_blank"><f:uri.typolink parameter="{redirect.target}"></f:uri.typolink></f:link.typolink> (<f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:destination_status_code"/>: {redirect.target_statuscode})</td>
-                                                                       <td>
-                                                                               <f:if condition="!{redirect.disable_hitcount}">
-                                                                                               <f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit{f:if(condition:'{redirect.hitcount} > 1',then:'s')}_text" arguments="{0:redirect.hitcount}"/>
-                                                                                               <f:if condition="{redirect.hitcount} != 0">
-                                                                                               <a class="t3js-modal-trigger"
-                                                                                                  href="{rd:editRecord(command: 'resetcounter', uid: redirect.uid)}"
-                                                                                                  title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_reset')}"
-                                                                                                  data-title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_reset.confirm.title')}"
-                                                                                                  data-content="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_reset.confirm.content')}"
-                                                                                                  data-button-close-text="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_record.no')}">
-                                                                                               <core:icon identifier="actions-edit-restore" /></a>
+                                                                       <f:if condition="{showHitCounter}">
+                                                                               <td>
+                                                                                       <f:if condition="!{redirect.disable_hitcount}">
+                                                                                                       <f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit{f:if(condition:'{redirect.hitcount} > 1',then:'s')}_text" arguments="{0:redirect.hitcount}"/>
+                                                                                                       <f:if condition="{redirect.hitcount} != 0">
+                                                                                                       <a class="t3js-modal-trigger"
+                                                                                                          href="{rd:editRecord(command: 'resetcounter', uid: redirect.uid)}"
+                                                                                                          title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_reset')}"
+                                                                                                          data-title="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_reset.confirm.title')}"
+                                                                                                          data-content="{f:translate(key: 'LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_reset.confirm.content')}"
+                                                                                                          data-button-close-text="{f:translate(key: 'LLL:EXT:lang/Resources/Private/Language/locallang_alt_doc.xlf:buttons.confirm.delete_record.no')}">
+                                                                                                       <core:icon identifier="actions-edit-restore" /></a>
+                                                                                               </f:if>
                                                                                        </f:if>
-                                                                               </f:if>
-                                                                       <td>
-                                                                               <f:if condition="{redirect.lasthiton}">
-                                                                                       <f:then><f:format.date format="d.m.Y H:i:s">@{redirect.lasthiton}</f:format.date></f:then>
-                                                                                       <f:else><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_last_never"/></f:else>
-                                                                               </f:if>
-                                                                       </td>
+                                                                               <td>
+                                                                                       <f:if condition="{redirect.lasthiton}">
+                                                                                               <f:then><f:format.date format="d.m.Y H:i:s">@{redirect.lasthiton}</f:format.date></f:then>
+                                                                                               <f:else><f:translate key="LLL:EXT:redirects/Resources/Private/Language/locallang_module_redirect.xlf:hit_last_never"/></f:else>
+                                                                                       </f:if>
+                                                                               </td>
+                                                                       </f:if>
                                                                        <td>
                                                                                <div class="btn-group">
                                                                                        <f:if condition="{redirect.is_regexp}">