GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Passed
Pull Request — master (#2835)
by
unknown
06:01
created

SectionDatasource::execute()   F

Complexity

Conditions 52
Paths > 20000

Size

Total Lines 204
Code Lines 115

Duplication

Lines 10
Ratio 4.9 %

Importance

Changes 0
Metric Value
cc 52
eloc 115
nc 76808
nop 1
dl 10
loc 204
rs 2
c 0
b 0
f 0

How to fix   Long Method    Complexity   

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
3
/**
4
 * @package data-sources
5
 */
6
/**
7
 * The `SectionDatasource` allows a user to retrieve entries from a given
8
 * section on the Frontend. This datasource type exposes the filtering provided
9
 * by the Fields in the given section to narrow the result set down. The resulting
10
 * entries can be grouped, sorted and allows pagination. Results can be chained
11
 * from other `SectionDatasource`'s using output parameters.
12
 *
13
 * @since Symphony 2.3
14
 * @link http://getsymphony.com/learn/concepts/view/data-sources/
15
 */
16
17
class SectionDatasource extends Datasource
18
{
19
    /**
20
     * An array of Field objects that this Datasource has created to display
21
     * the results.
22
     */
23
    private static $_fieldPool = array();
24
25
    /**
26
     * An array of the Symphony meta data parameters.
27
     */
28
    private static $_system_parameters = array(
29
        'system:id',
30
        'system:author',
31
        'system:creation-date',
32
        'system:modification-date',
33
        'system:date' // deprecated
34
    );
35
36
    /**
37
     * Set's the Section ID that this Datasource will use as it's source
38
     *
39
     * @param integer $source
40
     */
41
    public function setSource($source)
42
    {
43
        $this->_source = (int)$source;
0 ignored issues
show
Bug Best Practice introduced by
The property _source does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
44
    }
45
46
    /**
47
     * Return's the Section ID that this datasource is using as it's source
48
     *
49
     * @return integer
50
     */
51
    public function getSource()
52
    {
53
        return $this->_source;
54
    }
55
56
    /**
57
     * If this Datasource requires System Parameters to be output, this function
58
     * will return true, otherwise false.
59
     *
60
     * @return boolean
61
     */
62
    public function canProcessSystemParameters()
63
    {
64
        if (!is_array($this->dsParamPARAMOUTPUT)) {
65
            return false;
66
        }
67
68
        foreach (self::$_system_parameters as $system_parameter) {
69
            if (in_array($system_parameter, $this->dsParamPARAMOUTPUT) === true) {
70
                return true;
71
            }
72
        }
73
74
        return false;
75
    }
76
77
    /**
78
     * Given a name for the group, and an associative array that
79
     * contains three keys, `attr`, `records` and `groups`. Grouping
80
     * of Entries is done by the grouping Field at a PHP level, not
81
     * through the Database.
82
     *
83
     * @param string $element
84
     *  The name for the XML node for this group
85
     * @param array $group
86
     *  An associative array of the group data, includes `attr`, `records`
87
     *  and `groups` keys.
88
     * @throws Exception
89
     * @return XMLElement
90
     */
91
    public function processRecordGroup($element, array $group)
92
    {
93
        $xGroup = new XMLElement($element, null, $group['attr']);
94
95
        if (is_array($group['records']) && !empty($group['records'])) {
96
            if (isset($group['records'][0])) {
97
                $data = $group['records'][0]->getData();
98
                $pool = (new FieldManager)
99
                    ->select()
100
                    ->fields(array_keys($data))
101
                    ->execute()
102
                    ->rowsIndexedByColumn('id');
103
                self::$_fieldPool += $pool;
104
            }
105
106
            foreach ($group['records'] as $entry) {
107
                $xEntry = $this->processEntry($entry);
108
109
                if ($xEntry instanceof XMLElement) {
110
                    $xGroup->appendChild($xEntry);
111
                }
112
            }
113
        }
114
115
        if (is_array($group['groups']) && !empty($group['groups'])) {
116
            foreach ($group['groups'] as $element => $group) {
0 ignored issues
show
introduced by
$element is overwriting one of the parameters of this function.
Loading history...
117
                foreach ($group as $g) {
118
                    $xGroup->appendChild(
119
                        $this->processRecordGroup($element, $g)
120
                    );
121
                }
122
            }
123
        }
124
125
        if (!$this->_param_output_only) {
126
            return $xGroup;
127
        }
128
    }
129
130
    /**
131
     * Given an Entry object, this function will generate an XML representation
132
     * of the Entry to be returned. It will also add any parameters selected
133
     * by this datasource to the parameter pool.
134
     *
135
     * @param Entry $entry
136
     * @throws Exception
137
     * @return XMLElement|boolean
138
     *  Returns boolean when only parameters are to be returned.
139
     */
140
    public function processEntry(Entry $entry)
141
    {
142
        $data = $entry->getData();
143
144
        $xEntry = new XMLElement('entry');
145
        $xEntry->setAttribute('id', $entry->get('id'));
0 ignored issues
show
Bug introduced by
It seems like $entry->get('id') can also be of type array; however, parameter $value of XMLElement::setAttribute() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

145
        $xEntry->setAttribute('id', /** @scrutinizer ignore-type */ $entry->get('id'));
Loading history...
146
147
        if (!empty($this->_associated_sections)) {
148
            $this->setAssociatedEntryCounts($xEntry, $entry);
149
        }
150
151
        if ($this->_can_process_system_parameters) {
152
            $this->processSystemParameters($entry);
153
        }
154
155
        foreach ($data as $field_id => $values) {
156
            if (!isset(self::$_fieldPool[$field_id]) || !is_object(self::$_fieldPool[$field_id])) {
157
                self::$_fieldPool[$field_id] = (new FieldManager)->select()->field($field_id)->execute()->next();
158
            }
159
160
            $this->processOutputParameters($entry, $field_id, $values);
161
162
            if (!$this->_param_output_only) {
163
                foreach ($this->dsParamINCLUDEDELEMENTS as $handle) {
164
                    list($handle, $mode) = preg_split('/\s*:\s*/', $handle, 2);
165
166
                    if (self::$_fieldPool[$field_id]->get('element_name') == $handle) {
167
                        try {
168
                            self::$_fieldPool[$field_id]->appendFormattedElement($xEntry, $values, ($this->dsParamHTMLENCODE === 'yes' ? true : false), $mode, $entry->get('id'));
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamHTMLENCODE does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
169
                        } catch (Exception $ex) {
170
                            if (Symphony::Log()) {
171
                                Symphony::Log()->pushExceptionToLog($ex, true);
172
                            }
173
                            $this->appendFormattedError($handle, $xEntry, $ex);
174
                        } catch (Throwable $ex) {
175
                            if (Symphony::Log()) {
176
                                Symphony::Log()->pushExceptionToLog($ex, true);
177
                            }
178
                            $this->appendFormattedError($handle, $xEntry, $ex);
179
                        }
180
                    }
181
                }
182
            }
183
        }
184
185
        if ($this->_param_output_only) {
186
            return true;
187
        }
188
189
        // This is deprecated and will be removed in Symphony 3.0.0
190
        if (in_array('system:date', $this->dsParamINCLUDEDELEMENTS)) {
191
            if (Symphony::Log()) {
192
                Symphony::Log()->pushDeprecateWarningToLog('system:date', 'system:creation-date` or `system:modification-date', array(
193
                    'message-format' => __('The `%s` data source field is deprecated.')
194
                ));
195
            }
196
            $xDate = new XMLElement('system-date');
197
            $xDate->appendChild(
198
                General::createXMLDateObject(
0 ignored issues
show
Bug introduced by
It seems like General::createXMLDateOb...ion_date')), 'created') can also be of type false; however, parameter $child of XMLElement::appendChild() does only seem to accept string|XMLElement, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

198
                /** @scrutinizer ignore-type */ General::createXMLDateObject(
Loading history...
199
                    DateTimeObj::get('U', $entry->get('creation_date')),
0 ignored issues
show
Bug introduced by
It seems like $entry->get('creation_date') can also be of type array; however, parameter $timestamp of DateTimeObj::get() does only seem to accept null|string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

199
                    DateTimeObj::get('U', /** @scrutinizer ignore-type */ $entry->get('creation_date')),
Loading history...
Bug introduced by
DateTimeObj::get('U', $e...->get('creation_date')) of type false|string is incompatible with the type integer expected by parameter $timestamp of General::createXMLDateObject(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

199
                    /** @scrutinizer ignore-type */ DateTimeObj::get('U', $entry->get('creation_date')),
Loading history...
200
                    'created'
201
                )
202
            );
203
            $xDate->appendChild(
204
                General::createXMLDateObject(
205
                    DateTimeObj::get('U', $entry->get('modification_date')),
206
                    'modified'
207
                )
208
            );
209
            $xEntry->appendChild($xDate);
210
        }
211
212
        return $xEntry;
213
    }
214
215
    /**
216
     * Given an handle, it will create a XMLElement from its value.
217
     * The Throwable's message will be put into an error node.
218
     * The newly created XMLElement will then be appended to the $xEntry XMLElement.
219
     *
220
     * @param string $handle
221
     *  The name of the new XMLElement
222
     * @param XMLElement $xEntry
223
     *  The XMLElement to append a child intro
224
     * @param Throwable $ex
225
     *  The Throwable's message to use
226
     * @return void
227
     */
228
    private function appendFormattedError($handle, XMLElement &$xEntry, $ex)
229
    {
230
        $xmlField = new XMLElement($handle);
231
        $xmlField->appendChild(new XMLElement('error', General::wrapInCDATA($ex->getMessage())));
232
        $xEntry->appendChild($xmlField);
233
    }
234
235
    /**
236
     * An entry may be associated to other entries from various fields through
237
     * the section associations. This function will set the number of related
238
     * entries as attributes to the main `<entry>` element grouped by the
239
     * related entry's section.
240
     *
241
     * @param XMLElement $xEntry
242
     *  The <entry> XMLElement that the associated section counts will
243
     *  be set on
244
     * @param Entry $entry
245
     *  The current entry object
246
     * @throws Exception
247
     */
248
    public function setAssociatedEntryCounts(XMLElement &$xEntry, Entry $entry)
249
    {
250
        $associated_entry_counts = $entry->fetchAllAssociatedEntryCounts($this->_associated_sections);
251
252
        if (!empty($associated_entry_counts)) {
253
            foreach ($associated_entry_counts as $section_id => $fields) {
254
                foreach ($this->_associated_sections as $section) {
255
                    if ($section['id'] != $section_id) {
256
                        continue;
257
                    }
258
259
                    // For each related field show the count (#2083)
260
                    foreach ($fields as $field_id => $count) {
261
                        $field_handle = FieldManager::fetchHandleFromID($field_id);
262
                        $section_handle = $section['handle'];
263
                        // Make sure attribute does not begin with a digit
264
                        if (preg_match('/^[0-9]/', $section_handle)) {
265
                            $section_handle = 'x-' . $section_handle;
266
                        }
267
                        if ($field_handle) {
268
                            $xEntry->setAttribute($section_handle . '-' . $field_handle, (string)$count);
269
                        }
270
                    }
271
                }
272
            }
273
        }
274
    }
275
276
    /**
277
     * Given an Entry object, this function will iterate over the `dsParamPARAMOUTPUT`
278
     * setting to see any of the Symphony system parameters need to be set.
279
     * The current system parameters supported are `system:id`, `system:author`,
280
     * `system:creation-date` and `system:modification-date`.
281
     * If these parameters are found, the result is added
282
     * to the `$param_pool` array using the key, `ds-datasource-handle.parameter-name`
283
     * For the moment, this function also supports the pre Symphony 2.3 syntax,
284
     * `ds-datasource-handle` which did not support multiple parameters.
285
     *
286
     * @param Entry $entry
287
     *  The Entry object that contains the values that may need to be added
288
     *  into the parameter pool.
289
     */
290
    public function processSystemParameters(Entry $entry)
291
    {
292
        if (!isset($this->dsParamPARAMOUTPUT)) {
293
            return;
294
        }
295
296
        // Support the legacy parameter `ds-datasource-handle`
297
        $key = 'ds-' . $this->dsParamROOTELEMENT;
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamROOTELEMENT does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
298
299
        foreach ($this->dsParamPARAMOUTPUT as $param) {
300
            // The new style of paramater is `ds-datasource-handle.field-handle`
301
            $param_key = $key . '.' . str_replace(':', '-', $param);
302
303
            if ($param === 'system:id') {
304
                $this->_param_pool[$param_key][] = $entry->get('id');
0 ignored issues
show
Bug Best Practice introduced by
The property _param_pool does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
305
306
            } elseif ($param === 'system:author') {
307
                $this->_param_pool[$param_key][] = $entry->get('author_id');
308
309
            } elseif ($param === 'system:creation-date' || $param === 'system:date') {
310
                if ($param === 'system:date' && Symphony::Log()) {
311
                    Symphony::Log()->pushDeprecateWarningToLog('system:date', 'system:creation-date', array(
312
                        'message-format' => __('The `%s` data source output parameter is deprecated.')
313
                    ));
314
                }
315
                $this->_param_pool[$param_key][] = $entry->get('creation_date');
316
317
            } elseif ($param === 'system:modification-date') {
318
                $this->_param_pool[$param_key][] = $entry->get('modification_date');
319
320
            }
321
        }
322
    }
323
324
    /**
325
     * Given an Entry object, a `$field_id` and an array of `$data`, this
326
     * function iterates over the `dsParamPARAMOUTPUT` and will call the
327
     * field's (identified by `$field_id`) `getParameterPoolValue` function
328
     * to add parameters to the `$this->_param_pool`.
329
     *
330
     * @param Entry $entry
331
     * @param integer $field_id
332
     * @param array $data
333
     */
334
    public function processOutputParameters(Entry $entry, $field_id, array $data)
335
    {
336
        if (!isset($this->dsParamPARAMOUTPUT)) {
337
            return;
338
        }
339
340
        // Support the legacy parameter `ds-datasource-handle`
341
        $key = 'ds-' . $this->dsParamROOTELEMENT;
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamROOTELEMENT does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
342
343
        foreach ($this->dsParamPARAMOUTPUT as $param) {
344
            if (self::$_fieldPool[$field_id]->get('element_name') !== $param) {
345
                continue;
346
            }
347
348
            // The new style of parameter is `ds-datasource-handle.field-handle`
349
            $param_key = $key . '.' . str_replace(':', '-', $param);
350
351
            if (!isset($this->_param_pool[$param_key]) || !is_array($this->_param_pool[$param_key])) {
352
                $this->_param_pool[$param_key] = array();
0 ignored issues
show
Bug Best Practice introduced by
The property _param_pool does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
353
            }
354
355
            try {
356
                $param_pool_values = self::$_fieldPool[$field_id]->getParameterPoolValue($data, $entry->get('id'));
357
            } catch (Exception $ex) {
358
                if (Symphony::Log()) {
359
                    Symphony::Log()->pushExceptionToLog($ex, true);
360
                }
361
                $param_pool_values = ['error' => $ex->getMessage()];
362
            } catch (Throwable $ex) {
363
                if (Symphony::Log()) {
364
                    Symphony::Log()->pushExceptionToLog($ex, true);
365
                }
366
                $param_pool_values = ['error' => $ex->getMessage()];
367
            }
368
369
            if (is_array($param_pool_values)) {
370
                $this->_param_pool[$param_key] = array_merge($param_pool_values, $this->_param_pool[$param_key]);
371
372
            } elseif (!is_null($param_pool_values)) {
373
                $this->_param_pool[$param_key][] = $param_pool_values;
374
375
            }
376
        }
377
    }
378
379
    /**
380
     * This function iterates over `dsParamFILTERS` and appends the relevant
381
     * where and join operations.
382
     * This SQL is generated with the Field's query builder.
383
     *
384
     * @see Field::getEntryQueryFieldAdapter()
385
     * @param EntryQuery $entryQuery
386
     * @throws Exception
387
     */
388
    public function processFilters(&$entryQuery)
389
    {
390
        if (!is_array($this->dsParamFILTERS) || empty($this->dsParamFILTERS)) {
391
            return;
392
        }
393
394
        $pool = (new FieldManager)
395
            ->select()
396
            ->fields(array_filter(array_keys($this->dsParamFILTERS), 'is_numeric'))
397
            ->execute()
398
            ->rowsIndexedByColumn('id');
399
        self::$_fieldPool += $pool;
400
401
        foreach ($this->dsParamFILTERS as $field_id => $filter) {
402
            if ((is_array($filter) && empty($filter)) || trim($filter) == '') {
403
                continue;
404
            }
405
406
            if (!is_array($filter)) {
407
                $filter_type = Datasource::determineFilterType($filter);
408
                $value = Datasource::splitFilter($filter_type, $filter);
409
            } else {
410
                $filter_type = Datasource::FILTER_OR;
411
                $value = $filter;
412
            }
413
414
            if (!in_array($field_id, self::$_system_parameters) && $field_id != 'id' && !(self::$_fieldPool[$field_id] instanceof Field)) {
415
                throw new Exception(
416
                    __(
417
                        'Error creating field object with id %1$d, for filtering in data source %2$s. Check this field exists.',
418
                        array($field_id, '<code>' . $this->dsParamROOTELEMENT . '</code>')
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamROOTELEMENT does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
419
                    )
420
                );
421
            }
422
423
            // Support system:id as well as the old 'id'. #1691
424
            if ($field_id === 'system:id' || $field_id === 'id') {
425
                if ($field_id === 'id' && Symphony::Log()) {
426
                    Symphony::Log()->pushDeprecateWarningToLog('id', 'system:id', array(
427
                        'message-format' => __('The `%s` data source filter is deprecated.')
428
                    ));
429
                }
430
                $op = $filter_type === Datasource::FILTER_AND ? 'and' : 'or';
431
                $entryQuery->filter('system:id', $value, $op);
432
            // Dates
433
            } elseif ($field_id === 'system:creation-date' || $field_id === 'system:modification-date' || $field_id === 'system:date') {
434
                if ($field_id === 'system:date' && Symphony::Log()) {
435
                    Symphony::Log()->pushDeprecateWarningToLog('system:date', 'system:creation-date` or `system:modification-date', array(
436
                        'message-format' => __('The `%s` data source filter is deprecated.')
437
                    ));
438
                    $field_id = 'system:creation-date';
439
                }
440
                $op = $filter_type === Datasource::FILTER_AND ? 'and' : 'or';
441
                $entryQuery->filter($field_id, $value, $op);
442
            // Field with EQFA
443
            } elseif (self::$_fieldPool[$field_id]->getEntryQueryFieldAdapter()) {
444
                $op = $filter_type === Datasource::FILTER_AND ? 'and' : 'or';
445
                $entryQuery->filter(self::$_fieldPool[$field_id], $value, $op);
446
            // Compat layer with the old API
447
            } else {
448
                $where = '';
449
                $joins = '';
450
                if (!self::$_fieldPool[$field_id]->buildDSRetrievalSQL($value, $joins, $where, ($filter_type == Datasource::FILTER_AND ? true : false))) {
451
                    $this->_force_empty_result = true;
452
                    return;
453
                }
454
455
                if ($joins) {
456
                    $joins = $entryQuery->replaceTablePrefix($joins);
457
                    $entryQuery->unsafe()->unsafeAppendSQLPart('join', $joins);
458
                }
459
                if ($where) {
460
                    $where = $entryQuery->replaceTablePrefix($where);
461
                    $wherePrefix = $entryQuery->containsSQLParts('where') ? '' : 'WHERE 1 = 1';
462
                    $entryQuery->unsafe()->unsafeAppendSQLPart('where', "$wherePrefix $where");
463
                }
464
465
                if (self::$_fieldPool[$field_id]->requiresSQLGrouping()) {
466
                    $entryQuery->distinct();
467
                }
468
            }
469
        }
470
    }
471
472
    public function execute(array &$param_pool = null)
473
    {
474
        $result = new XMLElement($this->dsParamROOTELEMENT);
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamROOTELEMENT does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
475
        $this->_param_pool = $param_pool;
0 ignored issues
show
Bug Best Practice introduced by
The property _param_pool does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
476
        $requiresPagination = (!isset($this->dsParamPAGINATERESULTS) ||
477
            $this->dsParamPAGINATERESULTS === 'yes')
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamPAGINATERESULTS does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
478
            && isset($this->dsParamLIMIT) && General::intval($this->dsParamLIMIT) >= 0;
479
480
        $section = (new SectionManager)
481
            ->select()
482
            ->section($this->getSource())
483
            ->execute()
484
            ->next();
485
486
        if (!$section) {
0 ignored issues
show
introduced by
$section is of type Section, thus it always evaluated to true.
Loading history...
487
            $about = $this->about();
488
            trigger_error(__('The Section, %s, associated with the Data source, %s, could not be found.', array($this->getSource(), '<code>' . $about['name'] . '</code>')), E_USER_ERROR);
489
        }
490
491
        $sectioninfo = new XMLElement('section', General::sanitize($section->get('name')), array(
0 ignored issues
show
Bug introduced by
It seems like $section->get('name') can also be of type array; however, parameter $source of General::sanitize() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

491
        $sectioninfo = new XMLElement('section', General::sanitize(/** @scrutinizer ignore-type */ $section->get('name')), array(
Loading history...
492
            'id' => $section->get('id'),
493
            'handle' => $section->get('handle')
494
        ));
495
496
        if ($this->_force_empty_result == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
497
            if ($this->dsParamREDIRECTONREQUIRED === 'yes') {
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamREDIRECTONREQUIRED does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
498
                throw new FrontendPageNotFoundException;
499
            }
500
501
            $this->_force_empty_result = false; //this is so the section info element doesn't disappear.
502
            $error = new XMLElement('error', __("Data source not executed, required parameter is missing."), array(
503
                'required-param' => $this->dsParamREQUIREDPARAM
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamREQUIREDPARAM does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
504
            ));
505
            $result->appendChild($error);
506
            $result->prependChild($sectioninfo);
507
508
            return $result;
509
        }
510
511
        if ($this->_negate_result == true) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
512
            if ($this->dsParamREDIRECTONFORBIDDEN === 'yes') {
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamREDIRECTONFORBIDDEN does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
513
                throw new FrontendPageNotFoundException;
514
            }
515
516
            $this->_negate_result = false; //this is so the section info element doesn't disappear.
517
            $result = $this->negateXMLSet();
518
            $result->prependChild($sectioninfo);
519
520
            return $result;
521
        }
522
523
        if (is_array($this->dsParamINCLUDEDELEMENTS)) {
524
            $include_pagination_element = in_array('system:pagination', $this->dsParamINCLUDEDELEMENTS);
525
        } else {
526
            $this->dsParamINCLUDEDELEMENTS = array();
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamINCLUDEDELEMENTS does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
527
        }
528
529
        if (isset($this->dsParamPARAMOUTPUT) && !is_array($this->dsParamPARAMOUTPUT)) {
530
            $this->dsParamPARAMOUTPUT = array($this->dsParamPARAMOUTPUT);
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamPARAMOUTPUT does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
531
        }
532
533
        $this->_can_process_system_parameters = $this->canProcessSystemParameters();
0 ignored issues
show
Bug Best Practice introduced by
The property _can_process_system_parameters does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
534
535
        // combine `INCLUDEDELEMENTS`, `PARAMOUTPUT` and `GROUP` into an
536
        // array of field handles to optimise the `EntryManager` queries
537
        $datasource_schema = $this->dsParamINCLUDEDELEMENTS;
538
539
        if (is_array($this->dsParamPARAMOUTPUT)) {
540
            $datasource_schema = array_merge($datasource_schema, $this->dsParamPARAMOUTPUT);
541
        }
542
543
        if ($this->dsParamGROUP) {
0 ignored issues
show
Bug introduced by
The property dsParamGROUP does not exist on SectionDatasource. Did you mean dsParamSORT?
Loading history...
544
            $datasource_schema[] = FieldManager::fetchHandleFromID($this->dsParamGROUP);
545
        }
546
547
        // Create our query object
548
        $entriesQuery = (new EntryManager)
549
            ->select($datasource_schema)
550
            ->section($this->getSource());
551
552
        // Process Filters
553
        $this->processFilters($entriesQuery);
554
555
        // Process Sorting
556
        $entriesQuery->sort((string)$this->dsParamSORT, $this->dsParamORDER);
557
558
        // Configure pagination in the query
559
        if ($requiresPagination) {
560
            $entriesQuery->paginate($this->dsParamSTARTPAGE, $this->dsParamLIMIT);
561
        }
562
563
        // Execute
564
        $pagination = $entriesQuery->execute()->pagination();
565
        $entries = $pagination->rows();
566
567
        /**
568
         * Immediately after building entries allow modification of the Data Source entries array
569
         *
570
         * @delegate DataSourceEntriesBuilt
571
         * @param string $context
572
         * '/frontend/'
573
         * @param Datasource $datasource
574
         * @param array $entries
575
         * @param array $filters
576
         */
577
        Symphony::ExtensionManager()->notifyMembers('DataSourceEntriesBuilt', '/frontend/', array(
578
            'datasource' => &$this,
579
            'entries' => &$entries,
580
            'filters' => $this->dsParamFILTERS
581
        ));
582
583
        $entries_per_page = $requiresPagination
584
            ? $pagination->pageSize()
585
            : $pagination->totalEntries();
586
587
        if (empty($entries)) {
588
            if ($this->dsParamREDIRECTONEMPTY === 'yes') {
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamREDIRECTONEMPTY does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
589
                throw new FrontendPageNotFoundException;
590
            }
591
592
            $this->_force_empty_result = false;
593
            $result = $this->emptyXMLSet();
594
            $result->prependChild($sectioninfo);
595
596
            if ($include_pagination_element) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $include_pagination_element does not seem to be defined for all execution paths leading up to this point.
Loading history...
597
                $pagination_element = General::buildPaginationElement(0, 0, $entries_per_page);
598
599
                if ($pagination_element instanceof XMLElement && $result instanceof XMLElement) {
0 ignored issues
show
introduced by
$result is always a sub-type of XMLElement.
Loading history...
600
                    $result->prependChild($pagination_element);
601
                }
602
            }
603
        } else {
604
            if (!$this->_param_output_only) {
605
                $result->appendChild($sectioninfo);
606
607
                if ($include_pagination_element) {
608
                    $pagination_element = General::buildPaginationElement(
609
                        $pagination->totalEntries(),
610
                        $pagination->totalPages(),
611
                        $entries_per_page,
612
                        $pagination->currentPage()
613
                    );
614
615
                    if ($pagination_element instanceof XMLElement && $result instanceof XMLElement) {
0 ignored issues
show
introduced by
$result is always a sub-type of XMLElement.
Loading history...
616
                        $result->prependChild($pagination_element);
617
                    }
618
                }
619
            }
620
621
            if (!isset($this->dsParamASSOCIATEDENTRYCOUNTS) || $this->dsParamASSOCIATEDENTRYCOUNTS === 'yes') {
0 ignored issues
show
Bug Best Practice introduced by
The property dsParamASSOCIATEDENTRYCOUNTS does not exist on SectionDatasource. Did you maybe forget to declare it?
Loading history...
622
                $this->_associated_sections = $section->fetchChildAssociations();
0 ignored issues
show
Bug Best Practice introduced by
The property _associated_sections does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
623
            }
624
625
            // If the datasource require's GROUPING
626
            if (isset($this->dsParamGROUP)) {
627
                if (!isset(self::$_fieldPool[$this->dsParamGROUP])) {
628
                    self::$_fieldPool[$this->dsParamGROUP] = (new FieldManager)
629
                        ->select()
630
                        ->field($this->dsParamGROUP)
631
                        ->execute()
632
                        ->next();
633
                }
634
                if (self::$_fieldPool[$this->dsParamGROUP] == null) {
635
                    throw new SymphonyErrorPage(vsprintf("The field used for grouping '%s' cannot be found.", $this->dsParamGROUP));
636
                }
637
638
                $groups = self::$_fieldPool[$this->dsParamGROUP]->groupRecords($entries);
639
640
                foreach ($groups as $element => $group) {
641
                    foreach ($group as $g) {
642
                        $result->appendChild(
643
                            $this->processRecordGroup($element, $g)
644
                        );
645
                    }
646
                }
647
            } else {
648
                if (isset($entries[0])) {
649
                    $data = $entries[0]->getData();
650
                    if (!empty($data)) {
651
                        $pool = (new FieldManager)
652
                            ->select()
653
                            ->fields(array_keys($data))
654
                            ->execute()
655
                            ->rowsIndexedByColumn('id');
656
                        self::$_fieldPool += $pool;
657
                    }
658
                }
659
660
                foreach ($entries as $entry) {
661
                    $xEntry = $this->processEntry($entry);
662
663
                    if ($xEntry instanceof XMLElement) {
664
                        $result->appendChild($xEntry);
665
                    }
666
                }
667
            }
668
        }
669
670
        $param_pool = $this->_param_pool;
671
672
        return $result;
673
    }
674
}
675