qbus-agentur /
qbtools
| 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