Skip to content

Commit 80f3885

Browse files
[Task] refactoring
- move all methods with queries into new repository file - rename Helper to BackendHelper
1 parent ca1783f commit 80f3885

8 files changed

Lines changed: 396 additions & 356 deletions

File tree

Classes/DataHandler/AbstractDataHandler.php

Lines changed: 9 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,8 @@
2525

2626
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
2727
use Doctrine\DBAL\Exception as DBALException;
28-
use EHAERER\PasteReference\Helper\Helper;
28+
use EHAERER\PasteReference\Domain\Repository\TtContentRepository;
2929
use TYPO3\CMS\Core\Database\Connection;
30-
use TYPO3\CMS\Core\Database\ConnectionPool;
31-
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
32-
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
33-
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
34-
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
3530
use TYPO3\CMS\Core\DataHandling\DataHandler;
3631
use TYPO3\CMS\Core\Utility\GeneralUtility;
3732

@@ -47,6 +42,7 @@ abstract class AbstractDataHandler
4742
protected int $pageUid = 0;
4843
protected int $contentUid = 0;
4944
protected ?DataHandler $dataHandler = null;
45+
protected TtContentRepository $ttContentRepository;
5046

5147
/**
5248
* initializes this class
@@ -56,64 +52,23 @@ abstract class AbstractDataHandler
5652
* @param DataHandler $dataHandler
5753
* @throws DBALException|DBALDriverException
5854
*/
59-
public function init(string $table, int $uidPid, DataHandler $dataHandler): void
60-
{
55+
public function init(
56+
string $table,
57+
int $uidPid,
58+
DataHandler $dataHandler
59+
): void {
60+
$this->ttContentRepository = GeneralUtility::makeInstance(TtContentRepository::class);
6161
$this->setTable($table);
6262
if ($table === 'tt_content' && $uidPid < 0) {
6363
$this->setContentUid(abs($uidPid));
64-
$helper = GeneralUtility::makeInstance(Helper::class);
65-
$pageUid = $helper->getPidFromUid($this->getContentUid());
64+
$pageUid = $this->ttContentRepository->getPidFromUid($this->getContentUid());
6665
$this->setPageUid($pageUid);
6766
} else {
6867
$this->setPageUid($uidPid);
6968
}
7069
$this->setDataHandler($dataHandler);
7170
}
7271

73-
/**
74-
* Function to remove any remains of versioned records after finalizing a workspace action
75-
* via 'Discard' or 'Publish' commands
76-
*/
77-
public function cleanupWorkspacesAfterFinalizing(): void
78-
{
79-
$queryBuilder = $this->getQueryBuilder();
80-
$queryBuilder
81-
->delete('tt_content')
82-
->where(
83-
$queryBuilder->expr()->eq(
84-
'pid',
85-
$queryBuilder->createNamedParameter(-1, Connection::PARAM_INT)
86-
),
87-
$queryBuilder->expr()->eq(
88-
't3ver_wsid',
89-
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)
90-
)
91-
)
92-
->executeStatement();
93-
}
94-
95-
/**
96-
* @param string $table
97-
* @return QueryBuilder
98-
*/
99-
public function getQueryBuilder(string $table = 'tt_content'): QueryBuilder
100-
{
101-
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
102-
->getQueryBuilderForTable($table);
103-
$queryBuilder->getRestrictions()
104-
->removeByType(HiddenRestriction::class)
105-
->removeByType(StartTimeRestriction::class)
106-
->removeByType(EndTimeRestriction::class);
107-
108-
return $queryBuilder;
109-
}
110-
111-
public function getConnection(): Connection
112-
{
113-
return GeneralUtility::makeInstance(ConnectionPool::class)
114-
->getConnectionForTable($this->table);
115-
}
116-
11772
/**
11873
* @return string
11974
* usually 'tt_content'

Classes/DataHandler/ProcessCmdmap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public function execute_processCmdmap(
101101
}
102102

103103
if ($table === 'tt_content') {
104-
$this->cleanupWorkspacesAfterFinalizing();
104+
$this->ttContentRepository->cleanupWorkspacesAfterFinalizing();
105105
}
106106
}
107107
}
Lines changed: 256 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,256 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace EHAERER\PasteReference\Domain\Repository;
6+
7+
/***************************************************************
8+
* Copyright notice
9+
* (c) 2026 David Bruchmann <david.bruchmann@gmail.com>
10+
* (c) 2021-2023 Ephraim Härer <mail@ephra.im>
11+
* (c) 2013 Dirk Hoffmann <dirk-hoffmann@telekom.de>
12+
* All rights reserved
13+
* This script is part of the TYPO3 project. The TYPO3 project is
14+
* free software; you can redistribute it and/or modify
15+
* it under the terms of the GNU General Public License as published by
16+
* the Free Software Foundation; either version 2 of the License, or
17+
* (at your option) any later version.
18+
* The GNU General Public License can be found at
19+
* http://www.gnu.org/copyleft/gpl.html.
20+
* This script is distributed in the hope that it will be useful,
21+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
22+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23+
* GNU General Public License for more details.
24+
* This copyright notice MUST APPEAR in all copies of the script!
25+
***************************************************************/
26+
27+
use Doctrine\DBAL\ArrayParameterType;
28+
use Doctrine\DBAL\Exception as DBALException;
29+
use Doctrine\DBAL\Exception\DriverException as DBALDriverException;
30+
use EHAERER\PasteReference\Helper\BackendHelper;
31+
use TYPO3\CMS\Backend\Utility\BackendUtility;
32+
use TYPO3\CMS\Core\Configuration\ExtensionConfiguration;
33+
use TYPO3\CMS\Core\Database\Connection;
34+
use TYPO3\CMS\Core\Database\ConnectionPool;
35+
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
36+
use TYPO3\CMS\Core\Database\Query\Restriction\EndTimeRestriction;
37+
use TYPO3\CMS\Core\Database\Query\Restriction\HiddenRestriction;
38+
use TYPO3\CMS\Core\Database\Query\Restriction\StartTimeRestriction;
39+
use TYPO3\CMS\Core\SingletonInterface;
40+
use TYPO3\CMS\Core\Utility\GeneralUtility;
41+
42+
/**
43+
* Repository class
44+
*
45+
* @author David Bruchmann <david.bruchmann@gmail.com>
46+
* @author Dirk Hoffmann <dirk-hoffmann@telekom.de>
47+
*/
48+
class TtContentRepository implements SingletonInterface
49+
{
50+
protected array $extensionConfiguration = [];
51+
protected bool $showHidden = true;
52+
protected BackendHelper $backendHelper;
53+
protected string $table = 'tt_content';
54+
55+
public function __construct()
56+
{
57+
/** @var array<non-empty-string, string|int|float|bool|null> $emConf */
58+
$emConf = GeneralUtility::makeInstance(ExtensionConfiguration::class)->get('paste_reference') ?? [];
59+
$this->extensionConfiguration = $emConf;
60+
$this->backendHelper = GeneralUtility::makeInstance(BackendHelper::class);
61+
}
62+
63+
/**
64+
* Collects tt_content data from a single page or a page tree starting at a given page
65+
*
66+
* @todo: move this in a repository
67+
*
68+
* @param string $shortcutItem The single page to be used as the tree root
69+
* @param array<int, array<non-empty-string, mixed>> $collectedItems The collected item data rows ordered by parent position, column position and sorting
70+
* @param int $recursive The number of levels for the recursion
71+
* @param int $parentUid uid of the referencing tt_content record
72+
* @param int $language sys_language_uid of the referencing tt_content record
73+
* @throws DBALException
74+
*/
75+
public function collectContentDataFromPages(
76+
string $shortcutItem,
77+
array &$collectedItems,
78+
int $recursive = 0,
79+
int $parentUid = 0,
80+
int $language = 0
81+
): void {
82+
$itemList = str_replace('pages_', '', $shortcutItem);
83+
$itemList = GeneralUtility::intExplode(',', $itemList);
84+
85+
$queryBuilder = $this->getQueryBuilder();
86+
$result = $queryBuilder
87+
->select('*')
88+
->addSelectLiteral($queryBuilder->expr()->inSet(
89+
'pid',
90+
$queryBuilder->createNamedParameter($itemList, ArrayParameterType::INTEGER)
91+
) . ' AS inSet')
92+
->from('tt_content')
93+
->where(
94+
$queryBuilder->expr()->neq(
95+
'uid',
96+
$queryBuilder->createNamedParameter($parentUid, Connection::PARAM_INT)
97+
),
98+
$queryBuilder->expr()->in(
99+
'pid',
100+
$queryBuilder->createNamedParameter($itemList, ArrayParameterType::INTEGER)
101+
),
102+
$queryBuilder->expr()->gte('colPos', $queryBuilder->createNamedParameter(0, Connection::PARAM_INT)),
103+
$queryBuilder->expr()->in(
104+
'sys_language_uid',
105+
$queryBuilder->createNamedParameter([0, -1], ArrayParameterType::INTEGER)
106+
)
107+
)
108+
->orderBy('inSet')
109+
->addOrderBy('colPos')
110+
->addOrderBy('sorting')
111+
->executeQuery();
112+
113+
while ($item = $result->fetchAssociative()) {
114+
/** @var array<non-empty-string, string|int|float|bool|null> $item */
115+
if (!empty($this->extensionConfiguration['overlayShortcutTranslation']) && $language > 0) {
116+
$translatedItem = BackendUtility::getRecordLocalization('tt_content', (int)($item['uid'] ?? 0), $language) ?: [];
117+
if (is_array($translatedItem) && $translatedItem !== []) {
118+
$item = array_shift($translatedItem);
119+
}
120+
}
121+
if ($this->backendHelper->getBackendUser()->workspace > 0) {
122+
unset($item['inSet']);
123+
BackendUtility::workspaceOL('tt_content', $item, $this->backendHelper->getBackendUser()->workspace);
124+
}
125+
$item['tx_paste_reference_container'] = $item['pid'];
126+
$collectedItems[] = $item;
127+
}
128+
}
129+
130+
/**
131+
* Collects tt_content data from a single tt_content element
132+
*
133+
* @todo: move this in a repository
134+
*
135+
* @param string $shortcutItem The tt_content element to fetch the data from
136+
* @param array<int, array<non-empty-string, mixed>> $collectedItems The collected item data row
137+
* @param int $parentUid uid of the referencing tt_content record
138+
* @param int $language sys_language_uid of the referencing tt_content record
139+
* @throws DBALException
140+
*/
141+
public function collectContentData(
142+
string $shortcutItem,
143+
array &$collectedItems,
144+
int $parentUid,
145+
int $language
146+
): void {
147+
$shortcutItem = str_replace('tt_content_', '', $shortcutItem);
148+
if ((int)$shortcutItem !== $parentUid) {
149+
$queryBuilder = $this->getQueryBuilder();
150+
$queryBuilder->getRestrictions()->removeByType(StartTimeRestriction::class);
151+
$queryBuilder->getRestrictions()->removeByType(EndTimeRestriction::class);
152+
if ($this->showHidden) {
153+
$queryBuilder->getRestrictions()->removeByType(HiddenRestriction::class);
154+
}
155+
/** @var array<non-empty-string, string|int|float|bool|null>|false $item */
156+
$item = $queryBuilder
157+
->select('*')
158+
->from('tt_content')
159+
->where(
160+
$queryBuilder->expr()->eq(
161+
'uid',
162+
$queryBuilder->createNamedParameter((int)$shortcutItem, Connection::PARAM_INT)
163+
)
164+
)
165+
->setMaxResults(1)
166+
->executeQuery()
167+
->fetchAssociative();
168+
if (!empty($this->extensionConfiguration['overlayShortcutTranslation']) && $language > 0) {
169+
$translatedItem = BackendUtility::getRecordLocalization('tt_content', (int)($item['uid'] ?? 0), $language) ?: [];
170+
if (is_array($translatedItem) && $translatedItem !== []) {
171+
$item = array_shift($translatedItem);
172+
}
173+
}
174+
175+
if ($this->backendHelper->getBackendUser()->workspace > 0) {
176+
BackendUtility::workspaceOL(
177+
'tt_content',
178+
$item,
179+
$this->backendHelper->getBackendUser()->workspace
180+
);
181+
}
182+
$collectedItems[] = $item;
183+
}
184+
}
185+
186+
/**
187+
* get pid for a ContentElement
188+
*
189+
* @param int $uid the uid value of a tt_content record
190+
*
191+
* @return int
192+
* @throws DBALException|DBALDriverException
193+
*/
194+
public function getPidFromUid(int $uid = 0): int
195+
{
196+
$queryBuilder = $this->getQueryBuilder();
197+
/** @var array<non-empty-string, string|int|float|bool|null> $contentElement */
198+
$contentElement = $queryBuilder
199+
->select('pid')
200+
->from('tt_content')
201+
->where(
202+
$queryBuilder->expr()->eq(
203+
'uid',
204+
$queryBuilder->createNamedParameter(abs($uid), Connection::PARAM_INT)
205+
)
206+
)
207+
->executeQuery()
208+
->fetchAssociative();
209+
$pid = (int)($contentElement['pid'] ?? 0);
210+
return is_array($contentElement) && $pid ? $pid : 0;
211+
}
212+
213+
/**
214+
* Function to remove any remains of versioned records after finalizing a workspace action
215+
* via 'Discard' or 'Publish' commands
216+
*/
217+
public function cleanupWorkspacesAfterFinalizing(): void
218+
{
219+
$queryBuilder = $this->getQueryBuilder();
220+
$queryBuilder
221+
->delete('tt_content')
222+
->where(
223+
$queryBuilder->expr()->eq(
224+
'pid',
225+
$queryBuilder->createNamedParameter(-1, Connection::PARAM_INT)
226+
),
227+
$queryBuilder->expr()->eq(
228+
't3ver_wsid',
229+
$queryBuilder->createNamedParameter(0, Connection::PARAM_INT)
230+
)
231+
)
232+
->executeStatement();
233+
}
234+
235+
/**
236+
* @param string $table
237+
* @return QueryBuilder
238+
*/
239+
public function getQueryBuilder(string $table = 'tt_content'): QueryBuilder
240+
{
241+
$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
242+
->getQueryBuilderForTable($table);
243+
$queryBuilder->getRestrictions()
244+
->removeByType(HiddenRestriction::class)
245+
->removeByType(StartTimeRestriction::class)
246+
->removeByType(EndTimeRestriction::class);
247+
248+
return $queryBuilder;
249+
}
250+
251+
public function getConnection(): Connection
252+
{
253+
return GeneralUtility::makeInstance(ConnectionPool::class)
254+
->getConnectionForTable($this->table);
255+
}
256+
}

0 commit comments

Comments
 (0)