1 | <?php |
||
2 | namespace Qbus\Qbtools\ViewHelpers; |
||
3 | |||
4 | use TYPO3\CMS\Core\Database\Connection; |
||
5 | use TYPO3\CMS\Core\Database\ConnectionPool; |
||
6 | use TYPO3\CMS\Core\Database\Query\Restriction\FrontendRestrictionContainer; |
||
7 | use TYPO3\CMS\Core\Utility\GeneralUtility; |
||
8 | use TYPO3\CMS\Extbase\Object\ObjectManager; |
||
9 | use TYPO3\CMS\Extbase\Persistence\QueryInterface; |
||
10 | use TYPO3\CMS\Extbase\Persistence\Generic\QuerySettingsInterface; |
||
11 | use TYPO3\CMS\Frontend\Page\PageRepository; |
||
0 ignored issues
–
show
|
|||
12 | use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface; |
||
13 | use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractViewHelper; |
||
14 | use TYPO3Fluid\Fluid\Core\ViewHelper\Exception; |
||
15 | use TYPO3Fluid\Fluid\Core\ViewHelper\Traits\CompileWithRenderStatic; |
||
16 | |||
17 | |||
18 | /* ************************************************************** |
||
19 | * Copyright notice |
||
20 | * |
||
21 | * (c) 2014 Benjamin Franzke <[email protected]>, Qbus Internetagentur GmbH |
||
22 | * |
||
23 | * All rights reserved |
||
24 | * |
||
25 | * This script is part of the TYPO3 project. The TYPO3 project is |
||
26 | * free software; you can redistribute it and/or modify |
||
27 | * it under the terms of the GNU General Public License as published by |
||
28 | * the Free Software Foundation; either version 3 of the License, or |
||
29 | * (at your option) any later version. |
||
30 | * |
||
31 | * The GNU General Public License can be found at |
||
32 | * http://www.gnu.org/copyleft/gpl.html. |
||
33 | * |
||
34 | * This script is distributed in the hope that it will be useful, |
||
35 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
36 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
37 | * GNU General Public License for more details. |
||
38 | * |
||
39 | * This copyright notice MUST APPEAR in all copies of the script! |
||
40 | * ************************************************************* */ |
||
41 | |||
42 | /** |
||
43 | * @license http://www.gnu.org/licenses/gpl.html GNU General Public License, version 3 or later |
||
44 | * |
||
45 | * Examples: |
||
46 | * |
||
47 | * Fetches all QbContacts |
||
48 | * <qbtools:fetch model="Qbus\\Qbcontact\\Domain\\Model\\Contact" as="contacts"> |
||
49 | * <f:for each="{contacts}" as="contact"> |
||
50 | * <f:debug>{contact}</f:debug> |
||
51 | * </f:for> |
||
52 | * </qbtools:fetch> |
||
53 | * |
||
54 | * Fetches the record uid from table tt_content |
||
55 | * <qbtools:fetch match="{uid: 5}"> |
||
56 | * ... |
||
57 | * </qbtools> |
||
58 | * |
||
59 | * <qbtools:fetch table="sys_category"> |
||
60 | * <f:for each="{entities}" as="category"> |
||
61 | * <f:debug>{category}</f:debug> |
||
62 | * </f:for> |
||
63 | * </qbtools> |
||
64 | */ |
||
65 | class FetchViewHelper extends AbstractViewHelper |
||
66 | { |
||
67 | use CompileWithRenderStatic; |
||
68 | |||
69 | /** |
||
70 | * @var bool |
||
71 | */ |
||
72 | protected $escapeOutput = false; |
||
73 | |||
74 | /* |
||
75 | * Create a QueryInterface for a given $className |
||
76 | * |
||
77 | * @param string $className |
||
78 | * @param bool $ignoreEnableFields |
||
79 | * @return QueryInterface |
||
80 | */ |
||
81 | protected static function createQuery(string $className, bool $ignoreEnableFields): QueryInterface |
||
82 | { |
||
83 | $objectManager = GeneralUtility::makeInstance(ObjectManager::class); |
||
84 | $query = $objectManager->get(QueryInterface::class, $className); |
||
85 | $querySettings = $objectManager->get(QuerySettingsInterface::class); |
||
86 | |||
87 | $querySettings->setRespectStoragePage(false); |
||
88 | if ($ignoreEnableFields === true) { |
||
89 | $querySettings->setIgnoreEnableFields(true); |
||
90 | } |
||
91 | $query->setQuerySettings($querySettings); |
||
92 | |||
93 | return $query; |
||
94 | } |
||
95 | |||
96 | /* |
||
97 | * Retrieve an extbase domain model in a Repository alike fashion. |
||
98 | * Can be filtered by key-value pairs from $match. |
||
99 | * |
||
100 | * @param string $model |
||
101 | * @param array $match |
||
102 | * @param string $limit |
||
103 | * @param string $sortby |
||
104 | * @param string $sortdirection |
||
105 | * @param bool $ignoreEnableFields |
||
106 | */ |
||
107 | protected static function fetchModels(string $model, array $match, string $limit, string $sortby, string $sortdirection, bool $ignoreEnableFields) |
||
108 | { |
||
109 | $query = self::createQuery($model, $ignoreEnableFields); |
||
110 | if (count($match) > 0) { |
||
111 | $constraints = array(); |
||
112 | foreach ($match as $property => $value) { |
||
113 | $constraints[] = $query->equals($property, $value); |
||
114 | } |
||
115 | |||
116 | $query->matching($query->logicalAnd($constraints)); |
||
117 | } |
||
118 | |||
119 | $query->setOrderings([ |
||
120 | $sortby => ($sortdirection === 'DESC' ? QueryInterface::ORDER_DESCENDING : QueryInterface::ORDER_ASCENDING) |
||
121 | ]); |
||
122 | |||
123 | if (intval($limit) > 0) { |
||
124 | $query->setLimit(intval($limit)); |
||
125 | } |
||
126 | |||
127 | return $query->execute(); |
||
128 | } |
||
129 | |||
130 | /* |
||
131 | * Retrieve an extbase domain model in a Repository alike fashion. |
||
132 | * Can be filtered by key-value pairs from $match. |
||
133 | * |
||
134 | * @param string $model |
||
135 | * @param array $match |
||
136 | * @param string $sortby |
||
137 | * @param string $sortdirection |
||
138 | */ |
||
139 | protected static function fetchRows($table, $match, $limit, $sortby, $sortdirection, $ignoreEnableFields) |
||
140 | { |
||
141 | $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($table); |
||
142 | |||
143 | if ($ignoreEnableFields === false) { |
||
144 | $queryBuilder->setRestrictions(GeneralUtility::makeInstance(FrontendRestrictionContainer::class)); |
||
145 | } |
||
146 | |||
147 | $whereConditions = []; |
||
148 | |||
149 | $languageField = $GLOBALS['TCA'][$table]['ctrl']['languageField'] ?? null; |
||
150 | if ($languageField !== null) { |
||
151 | $whereConditions[] = $queryBuilder->expr()->in('sys_language_uid', $queryBuilder->createNamedParameter([0, -1], Connection::PARAM_INT_ARRAY)); |
||
152 | } |
||
153 | |||
154 | foreach ($match as $key => $value) { |
||
155 | $whereConditions[] = $queryBuilder->expr()->eq($key, $queryBuilder->createNamedParameter($value, \PDO::PARAM_STR)); |
||
156 | } |
||
157 | |||
158 | $queryBuilder |
||
159 | ->select('*') |
||
160 | ->from($table) |
||
161 | ->where( |
||
162 | $queryBuilder->expr()->andX(...$whereConditions) |
||
163 | ); |
||
164 | |||
165 | if (intval($limit) > 0) { |
||
166 | $queryBuilder->setMaxresults(intval($limit)); |
||
167 | } |
||
168 | |||
169 | $queryBuilder->addOrderBy($sortby, $sortdirection === 'DESC' ? 'DESC' : 'ASC'); |
||
170 | |||
171 | $result = $queryBuilder->execute(); |
||
172 | |||
173 | $pageRepository = GeneralUtility::makeInstance(PageRepository::class); |
||
174 | $entities = []; |
||
175 | while ($row = $result->fetch()) { |
||
176 | if (method_exists($pageRepository, 'getLanguageOverlay')) { |
||
177 | // For TYPO3 >= v9 |
||
178 | $row = $pageRepository->getLanguageOverlay($table, $row); |
||
179 | } else { |
||
180 | if ($table === 'pages') { |
||
181 | $row = $pageRepository->getPageOverlay($row); |
||
182 | } else { |
||
183 | $row = $pageRepository->getRecordOverlay($table, $row, $GLOBALS['TSFE']->sys_language_content, $GLOBALS['TSFE']->sys_language_contentOL); |
||
184 | } |
||
185 | } |
||
186 | |||
187 | $entities[] = $row; |
||
188 | } |
||
189 | |||
190 | return $entities; |
||
191 | } |
||
192 | |||
193 | /** |
||
194 | * Initialize arguments |
||
195 | */ |
||
196 | public function initializeArguments() |
||
197 | { |
||
198 | $this->registerArgument('table', 'string', 'e.g. "tt_content"', false, 'tt_content'); |
||
199 | $this->registerArgument('model', 'string', 'Vendor\Ext\Domain\Model\Foo', false, null); |
||
200 | $this->registerArgument('match', 'array', '', false, []); |
||
201 | $this->registerArgument('sortby', 'string', 'column/property to sort by', false, 'sorting'); |
||
202 | $this->registerArgument('sortdirection', 'string', 'ASC or DESC', false, 'ASC'); |
||
203 | $this->registerArgument('limit', 'string', '', false, ''); |
||
204 | $this->registerArgument('hidden', 'bool', '', false, false); |
||
205 | $this->registerArgument('as', 'string', 'variable to render the result into', false, 'entities'); |
||
206 | } |
||
207 | |||
208 | /** |
||
209 | * @param array $arguments |
||
210 | * @param \Closure $renderChildrenClosure |
||
211 | * @param RenderingContextInterface $renderingContext |
||
212 | * @return string |
||
213 | * @throws Exception |
||
214 | */ |
||
215 | public static function renderStatic(array $arguments, \Closure $renderChildrenClosure, RenderingContextInterface $renderingContext): string |
||
216 | { |
||
217 | $entities = null; |
||
218 | |||
219 | $table = (string)$arguments['table']; |
||
220 | $model = $arguments['model'] ?? ''; |
||
221 | $match = $arguments['match']; |
||
222 | $sortby = $arguments['sortby']; |
||
223 | $sortdirection = $arguments['sortdirection']; |
||
224 | $limit = $arguments['limit']; |
||
225 | $hidden = $arguments['hidden']; |
||
226 | $as = $arguments['as']; |
||
227 | |||
228 | if (strlen($model) > 0) { |
||
229 | $entities = self::fetchModels($model, $match, $limit, $sortby, $sortdirection, $hidden); |
||
230 | } else { |
||
231 | $entities = self::fetchRows($table, $match, $limit, $sortby, $sortdirection, $hidden); |
||
232 | } |
||
233 | |||
234 | $renderingContext->getVariableProvider()->add($as, $entities); |
||
235 | $content = $renderChildrenClosure(); |
||
236 | $renderingContext->getVariableProvider()->remove($as); |
||
237 | |||
238 | return $content; |
||
239 | } |
||
240 | } |
||
241 |
The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g.
excluded_paths: ["lib/*"]
, you can move it to the dependency path list as follows:For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths