[FEATURE] Show user who deleted a record in recycler 79/54379/3
authorGeorg Ringer <georg.ringer@gmail.com>
Thu, 12 Oct 2017 11:20:24 +0000 (13:20 +0200)
committerFrank Naegler <frank.naegler@typo3.org>
Mon, 16 Oct 2017 09:12:34 +0000 (11:12 +0200)
Add the user who deleted a record to the recycler information and also
show the avatar of the user.

Resolves: #69340
Releases: master
Change-Id: Id7d86d737b2759c6746baefa4b60659b6e9527eb
Reviewed-on: https://review.typo3.org/54379
Tested-by: TYPO3com <no-reply@typo3.com>
Tested-by: Riccardo De Contardi <erredeco@gmail.com>
Reviewed-by: Frank Naegler <frank.naegler@typo3.org>
Tested-by: Frank Naegler <frank.naegler@typo3.org>
Reviewed-by: Joerg Boesche <typo3@joergboesche.de>
Tested-by: Joerg Boesche <typo3@joergboesche.de>
typo3/sysext/core/Documentation/Changelog/master/Feature-69340-ShowBackendUserWhoDeletedRecord.rst [new file with mode: 0644]
typo3/sysext/recycler/Classes/Controller/DeletedRecordsController.php
typo3/sysext/recycler/Resources/Private/Language/locallang.xlf
typo3/sysext/recycler/Resources/Private/Partials/RecordsTable/DeletedRecord.html

diff --git a/typo3/sysext/core/Documentation/Changelog/master/Feature-69340-ShowBackendUserWhoDeletedRecord.rst b/typo3/sysext/core/Documentation/Changelog/master/Feature-69340-ShowBackendUserWhoDeletedRecord.rst
new file mode 100644 (file)
index 0000000..419eec4
--- /dev/null
@@ -0,0 +1,14 @@
+.. include:: ../../Includes.txt
+
+======================================================
+Feature: #69340 - Show backend user who deleted record
+======================================================
+
+See :issue:`69340`
+
+Description
+===========
+
+Improve the recycler output by showing also the backend user who deleted the record. Furthermore the avatar of the creator and the remover are shown.
+
+.. index:: Backend
index 7c25727..09b9e65 100644 (file)
@@ -1,4 +1,5 @@
 <?php
+
 namespace TYPO3\CMS\Recycler\Controller;
 
 /*
@@ -15,7 +16,9 @@ namespace TYPO3\CMS\Recycler\Controller;
  */
 
 use TYPO3\CMS\Backend\Utility\BackendUtility;
+use TYPO3\CMS\Core\Database\ConnectionPool;
 use TYPO3\CMS\Core\DataHandling\DataHandler;
+use TYPO3\CMS\Core\History\RecordHistoryStore;
 use TYPO3\CMS\Core\Imaging\Icon;
 use TYPO3\CMS\Core\Imaging\IconFactory;
 use TYPO3\CMS\Core\Utility\GeneralUtility;
@@ -64,7 +67,10 @@ class DeletedRecordsController
                 $total += count($deletedRowsArray[$table]);
                 foreach ($rows as $row) {
                     $pageTitle = $this->getPageTitle((int)$row['pid']);
-                    $backendUser = BackendUtility::getRecord('be_users', $row[$GLOBALS['TCA'][$table]['ctrl']['cruser_id']], 'username', '', false);
+                    $backendUserName = $this->getBackendUser((int)$row[$GLOBALS['TCA'][$table]['ctrl']['cruser_id']]);
+
+                    $userIdWhoDeleted = $this->getUserWhoDeleted($table, (int)$row['uid']);
+
                     $jsonArray['rows'][] = [
                         'uid' => $row['uid'],
                         'pid' => $row['pid'],
@@ -73,11 +79,13 @@ class DeletedRecordsController
                         'table' => $table,
                         'crdate' => BackendUtility::datetime($row[$GLOBALS['TCA'][$table]['ctrl']['crdate']]),
                         'tstamp' => BackendUtility::datetime($row[$GLOBALS['TCA'][$table]['ctrl']['tstamp']]),
-                        'owner' => htmlspecialchars($backendUser['username']),
+                        'owner' => htmlspecialchars($backendUserName),
                         'owner_uid' => $row[$GLOBALS['TCA'][$table]['ctrl']['cruser_id']],
                         'tableTitle' => $lang->sL($GLOBALS['TCA'][$table]['ctrl']['title']),
                         'title' => htmlspecialchars(BackendUtility::getRecordTitle($table, $row)),
                         'path' => RecyclerUtility::getRecordPath($row['pid']),
+                        'delete_user_uid' => $userIdWhoDeleted,
+                        'delete_user' => $this->getBackendUser($userIdWhoDeleted),
                         'isParentDeleted' => $table === 'pages' ? RecyclerUtility::isParentPageDeleted($row['pid']) : false
                     ];
                 }
@@ -111,6 +119,64 @@ class DeletedRecordsController
     }
 
     /**
+     * Gets the username of a given backend user
+     *
+     * @param int $userId uid of user
+     * @return string
+     */
+    protected function getBackendUser(int $userId): string
+    {
+        if ($userId === 0) {
+            return '';
+        }
+        $cacheId = 'recycler-user-' . $userId;
+        if ($this->runtimeCache->has($cacheId)) {
+            $username = $this->runtimeCache->get($cacheId);
+        } else {
+            $backendUser = BackendUtility::getRecord('be_users', $userId, 'username', '', false);
+            $username = $backendUser['username'];
+            $this->runtimeCache->set($cacheId, $username);
+        }
+        return $username;
+    }
+
+    /**
+     * Get the user uid of the user who deleted the record
+     *
+     * @param string $table table name
+     * @param int $uid uid of record
+     * @return int
+     */
+    protected function getUserWhoDeleted(string $table, int $uid): int
+    {
+        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
+            ->getQueryBuilderForTable('sys_history');
+        $queryBuilder->select('userid')
+            ->from('sys_history')
+            ->where(
+                $queryBuilder->expr()->eq(
+                    'tablename',
+                    $queryBuilder->createNamedParameter($table, \PDO::PARAM_STR)
+                ),
+                $queryBuilder->expr()->eq(
+                    'usertype',
+                    $queryBuilder->createNamedParameter('BE', \PDO::PARAM_STR)
+                ),
+                $queryBuilder->expr()->eq(
+                    'recuid',
+                    $queryBuilder->createNamedParameter($uid, \PDO::PARAM_INT)
+                ),
+                $queryBuilder->expr()->eq(
+                    'actiontype',
+                    $queryBuilder->createNamedParameter(RecordHistoryStore::ACTION_DELETE, \PDO::PARAM_INT)
+                )
+            )
+            ->setMaxResults(1);
+
+        return (int)$queryBuilder->execute()->fetchColumn(0);
+    }
+
+    /**
      * Returns an instance of LanguageService
      *
      * @return \TYPO3\CMS\Core\Localization\LanguageService
index df72799..e0812d7 100644 (file)
                        <trans-unit id="table.header.owner">
                                <source>Owner</source>
                        </trans-unit>
+                       <trans-unit id="table.header.deletedBy">
+                               <source>Deleted by</source>
+                       </trans-unit>
                        <trans-unit id="table.header.path">
                                <source>Path</source>
                        </trans-unit>
index c42383d..2f84bfa 100644 (file)
@@ -1,3 +1,4 @@
+<html xmlns:be="http://typo3.org/ns/TYPO3/CMS/Backend/ViewHelpers" data-namespace-typo3-fluid="true">
 <tr data-uid="{record.uid}" data-table="{record.table}" data-recordtitle="{record.title}" data-parent-deleted="{record.isParentDeleted}">
        <td class="nowrap">
                <label class="btn btn-default btn-checkbox">
@@ -36,6 +37,7 @@
                                        <th><f:translate key="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:table.header.recordtype" /></th>
                                        <th><f:translate key="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:table.header.crdate" /></th>
                                        <th><f:translate key="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:table.header.owner" /></th>
+                                       <th><f:translate key="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:table.header.deletedBy" /></th>
                                        <th><f:translate key="LLL:EXT:recycler/Resources/Private/Language/locallang.xlf:table.header.path" /></th>
                                </tr>
                        </thead>
                                <tr>
                                        <td>{record.table}</td>
                                        <td>{record.crdate}</td>
-                                       <td>{record.owner} ({record.owner_uid})</td>
+                                       <td><be:avatar backendUser="{record.owner_uid}" showIcon="true" />{record.owner} ({record.owner_uid})</td>
+                                       <td><f:if condition="{record.delete_user}"><be:avatar backendUser="{record.delete_user_uid}" showIcon="true" />{record.delete_user} ({record.delete_user_uid})</f:if></td>
                                        <td><f:format.html>{record.path}</f:format.html></td>
                                </tr>
                        </tbody>
                </table>
        </td>
 </tr>
+</html>