[TASK] Reduce SQL queries of page tree in workspaces
[Packages/TYPO3.CMS.git] / typo3 / sysext / workspaces / Classes / Hook / DataHandlerHook.php
1 <?php
2 namespace TYPO3\CMS\Workspaces\Hook;
3
4 /*
5 * This file is part of the TYPO3 CMS project.
6 *
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
10 *
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
13 *
14 * The TYPO3 project - inspiring people to share!
15 */
16
17 use TYPO3\CMS\Backend\Utility\BackendUtility;
18
19 /**
20 * Tcemain service
21 */
22 class DataHandlerHook {
23
24 /**
25 * In case a sys_workspace_stage record is deleted we do a hard reset
26 * for all existing records in that stage to avoid that any of these end up
27 * as orphan records.
28 *
29 * @param string $command
30 * @param string $table
31 * @param string $id
32 * @param string $value
33 * @param \TYPO3\CMS\Core\DataHandling\DataHandler $tcemain
34 * @return void
35 */
36 public function processCmdmap_postProcess($command, $table, $id, $value, \TYPO3\CMS\Core\DataHandling\DataHandler $tcemain) {
37 if ($command === 'delete') {
38 if ($table === \TYPO3\CMS\Workspaces\Service\StagesService::TABLE_STAGE) {
39 $this->resetStageOfElements($id);
40 } elseif ($table === \TYPO3\CMS\Workspaces\Service\WorkspaceService::TABLE_WORKSPACE) {
41 $this->flushWorkspaceElements($id);
42 }
43 }
44 }
45
46 /**
47 * hook that is called AFTER all commands of the commandmap was
48 * executed
49 *
50 * @param \TYPO3\CMS\Core\DataHandling\DataHandler $tcemainObj reference to the main tcemain object
51 * @return void
52 */
53 public function processCmdmap_afterFinish(\TYPO3\CMS\Core\DataHandling\DataHandler $tcemainObj) {
54 $this->flushWorkspaceCacheEntriesByWorkspaceId($tcemainObj->BE_USER->workspace);
55 }
56
57 /**
58 * In case a sys_workspace_stage record is deleted we do a hard reset
59 * for all existing records in that stage to avoid that any of these end up
60 * as orphan records.
61 *
62 * @param int $stageId Elements with this stage are resetted
63 * @return void
64 */
65 protected function resetStageOfElements($stageId) {
66 $fields = array('t3ver_stage' => \TYPO3\CMS\Workspaces\Service\StagesService::STAGE_EDIT_ID);
67 foreach ($this->getTcaTables() as $tcaTable) {
68 if (BackendUtility::isTableWorkspaceEnabled($tcaTable)) {
69 $where = 't3ver_stage = ' . (int)$stageId;
70 $where .= ' AND t3ver_wsid > 0 AND pid=-1';
71 $where .= BackendUtility::deleteClause($tcaTable);
72 $GLOBALS['TYPO3_DB']->exec_UPDATEquery($tcaTable, $where, $fields);
73 }
74 }
75 }
76
77 /**
78 * Flushes elements of a particular workspace to avoid orphan records.
79 *
80 * @param int $workspaceId The workspace to be flushed
81 * @return void
82 */
83 protected function flushWorkspaceElements($workspaceId) {
84 $command = array();
85 foreach ($this->getTcaTables() as $tcaTable) {
86 if (BackendUtility::isTableWorkspaceEnabled($tcaTable)) {
87 $where = '1=1';
88 $where .= BackendUtility::getWorkspaceWhereClause($tcaTable, $workspaceId);
89 $where .= BackendUtility::deleteClause($tcaTable);
90 $records = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows('uid', $tcaTable, $where, '', '', '', 'uid');
91 if (is_array($records)) {
92 foreach ($records as $recordId => $_) {
93 $command[$tcaTable][$recordId]['version']['action'] = 'flush';
94 }
95 }
96 }
97 }
98 if (!empty($command)) {
99 $tceMain = $this->getTceMain();
100 $tceMain->start(array(), $command);
101 $tceMain->process_cmdmap();
102 }
103 }
104
105 /**
106 * Gets all defined TCA tables.
107 *
108 * @return array
109 */
110 protected function getTcaTables() {
111 return array_keys($GLOBALS['TCA']);
112 }
113
114 /**
115 * @return \TYPO3\CMS\Core\DataHandling\DataHandler
116 */
117 protected function getTceMain() {
118 $tceMain = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\DataHandling\DataHandler::class);
119 $tceMain->stripslashes_values = 0;
120 return $tceMain;
121 }
122
123 /**
124 * Flushes the workspace cache for current workspace and for the virtual "all workspaces" too.
125 *
126 * @param int $workspaceId The workspace to be flushed in cache
127 * @return void
128 */
129 protected function flushWorkspaceCacheEntriesByWorkspaceId($workspaceId) {
130 $workspacesCache = \TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\TYPO3\CMS\Core\Cache\CacheManager::class)->getCache('workspaces_cache');
131 $workspacesCache->flushByTag($workspaceId);
132 $workspacesCache->flushByTag(\TYPO3\CMS\Workspaces\Service\WorkspaceService::SELECT_ALL_WORKSPACES);
133 }
134
135 }