FetchViewHelper::fetchRows()   B
last analyzed

Complexity

Conditions 9
Paths 64

Size

Total Lines 52
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
cc 9
eloc 30
c 6
b 0
f 0
nc 64
nop 6
dl 0
loc 52
rs 8.0555

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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
Bug introduced by
The type TYPO3\CMS\Frontend\Page\PageRepository was not found. Maybe you did not declare it correctly or list all dependencies?

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:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
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