Failed Conditions
Push — master ( 5f60a5...9b80eb )
by Rafael
21:42
created

Relation   D

Complexity

Total Complexity 59

Size/Duplication

Total Lines 450
Duplicated Lines 0 %

Test Coverage

Coverage 89.02%

Importance

Changes 0
Metric Value
wmc 59
dl 0
loc 450
ccs 154
cts 173
cp 0.8902
rs 4.5454
c 0
b 0
f 0

14 Methods

Rating   Name   Duplication   Size   Complexity  
A getRelatedRecords() 0 13 2
A isTcaConfiguredForTablesField() 0 3 1
B cObjGetSingleExt() 0 29 4
B usePagesLanguageOverlayInsteadOfPagesIfPossible() 0 11 5
C resolveRelatedValue() 0 47 7
C getUidOfRecordOverlay() 0 38 8
B getRelatedItems() 0 24 4
A getTranslationOverlay() 0 7 2
A sortByKeyInIN() 0 9 2
A getLocalRecordUidFromOverlay() 0 12 4
C getRelatedItemsFromForeignTable() 0 40 7
A resolveForeignTableLabelField() 0 16 3
A __construct() 0 4 1
C getRelatedItemsFromMMTable() 0 48 9

How to fix   Complexity   

Complex Class

Complex classes like Relation often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Relation, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace ApacheSolrForTypo3\Solr\ContentObject;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2011-2015 Ingo Renner <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 3 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use ApacheSolrForTypo3\Solr\Util;
28
use Doctrine\DBAL\Driver\Statement;
29
use TYPO3\CMS\Core\Database\ConnectionPool;
30
use TYPO3\CMS\Core\Database\Query\QueryBuilder;
31
use TYPO3\CMS\Core\Database\RelationHandler;
32
use TYPO3\CMS\Core\Utility\GeneralUtility;
33
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
34
35
/**
36
 * A content object (cObj) to resolve relations between database records
37
 *
38
 * Configuration options:
39
 *
40
 * localField: the record's field to use to resolve relations
41
 * foreignLabelField: Usually the label field to retrieve from the related records is determined automatically using TCA, using this option the desired field can be specified explicitly
42
 * multiValue: whether to return related records suitable for a multi value field
43
 * singleValueGlue: when not using multiValue, the related records need to be concatenated using a glue string, by default this is ", ". Using this option a custom glue can be specified. The custom value must be wrapped by pipe (|) characters.
44
 * relationTableSortingField: field in an mm relation table to sort by, usually "sorting"
45
 * enableRecursiveValueResolution: if the specified remote table's label field is a relation to another table, the value will be resolve by following the relation recursively.
46
 * removeEmptyValues: Removes empty values when resolving relations, defaults to TRUE
47
 * removeDuplicateValues: Removes duplicate values
48
 *
49
 * @author Ingo Renner <[email protected]>
50
 */
51
class Relation
52
{
53
    const CONTENT_OBJECT_NAME = 'SOLR_RELATION';
54
55
    /**
56
     * Content object configuration
57
     *
58
     * @var array
59
     */
60
    protected $configuration = [];
61
62
    /**
63
     * Constructor.
64
     *
65
     */
66 45
    public function __construct()
67
    {
68 45
        $this->configuration['enableRecursiveValueResolution'] = 1;
69 45
        $this->configuration['removeEmptyValues'] = 1;
70 45
    }
71
72
    /**
73
     * Executes the SOLR_RELATION content object.
74
     *
75
     * Resolves relations between records. Currently supported relations are
76
     * TYPO3-style m:n relations.
77
     * May resolve single value and multi value relations.
78
     *
79
     * @param string $name content object name 'SOLR_RELATION'
80
     * @param array $configuration for the content object
81
     * @param string $TyposcriptKey not used
82
     * @param \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer $parentContentObject parent content object
83
     * @return string serialized array representation of the given list
84
     */
85 45
    public function cObjGetSingleExt(
86
        /** @noinspection PhpUnusedParameterInspection */ $name,
0 ignored issues
show
Unused Code introduced by
The parameter $name is not used and could be removed. ( Ignorable by Annotation )

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

86
        /** @noinspection PhpUnusedParameterInspection */ /** @scrutinizer ignore-unused */ $name,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
87
        array $configuration,
88
        /** @noinspection PhpUnusedParameterInspection */ $TyposcriptKey,
0 ignored issues
show
Unused Code introduced by
The parameter $TyposcriptKey is not used and could be removed. ( Ignorable by Annotation )

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

88
        /** @noinspection PhpUnusedParameterInspection */ /** @scrutinizer ignore-unused */ $TyposcriptKey,

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
89
        $parentContentObject
90
    ) {
91 45
        $this->configuration = array_merge($this->configuration, $configuration);
92
93 45
        $relatedItems = $this->getRelatedItems($parentContentObject);
94
95 45
        if (!empty($this->configuration['removeDuplicateValues'])) {
96
            $relatedItems = array_unique($relatedItems);
97
        }
98
99 45
        if (empty($configuration['multiValue'])) {
100
            // single value, need to concatenate related items
101 2
            $singleValueGlue = ', ';
102
103 2
            if (!empty($configuration['singleValueGlue'])) {
104
                $singleValueGlue = trim($configuration['singleValueGlue'], '|');
105
            }
106
107 2
            $result = implode($singleValueGlue, $relatedItems);
108
        } else {
109
            // multi value, need to serialize as content objects must return strings
110 43
            $result = serialize($relatedItems);
111
        }
112
113 45
        return $result;
114
    }
115
116
    /**
117
     * Gets the related items of the current record's configured field.
118
     *
119
     * @param ContentObjectRenderer $parentContentObject parent content object
120
     * @return array Array of related items, values already resolved from related records
121
     */
122 45
    protected function getRelatedItems(
123
        ContentObjectRenderer $parentContentObject
124
    ) {
125
126 45
        list($localTableNameOrg, $localRecordUid) = explode(':', $parentContentObject->currentRecord);
127 45
        $localFieldName = $this->configuration['localField'];
128
129 45
        if (!$this->isTcaConfiguredForTablesField($localTableNameOrg, $localFieldName)) {
130
            return [];
131
        }
132
133 45
        $localTableName = $this->usePagesLanguageOverlayInsteadOfPagesIfPossible($localTableNameOrg, $localFieldName);
134 45
        $localRecordUid = $this->getUidOfRecordOverlay($localTableNameOrg, $localFieldName, $localRecordUid);
135
136 45
        $localFieldTca = $GLOBALS['TCA'][$localTableName]['columns'][$localFieldName];
137 45
        if (isset($localFieldTca['config']['MM']) && trim($localFieldTca['config']['MM']) !== '') {
138 42
            $relatedItems = $this->getRelatedItemsFromMMTable($localTableName,
139 42
                $localRecordUid, $localFieldTca);
140
        } else {
141 3
            $relatedItems = $this->getRelatedItemsFromForeignTable($localTableName,
142 3
                $localRecordUid, $localFieldTca, $parentContentObject);
143
        }
144
145 45
        return $relatedItems;
146
    }
147
148
    /**
149
     * @param string $localTableName
150
     * @param string $localFieldName
151
     * @return string
152
     * @todo this can be removed when TYPO3 8 support is dropped since pages translations are in pages then as well
153
     */
154 45
    protected function usePagesLanguageOverlayInsteadOfPagesIfPossible(string $localTableName, string $localFieldName) : string
155
    {
156
        // pages has a special overlay table constriction
157 45
        if ($GLOBALS['TSFE']->sys_language_uid > 0
158 45
            && $localTableName === 'pages'
159 45
            && $this->isTcaConfiguredForTablesField('pages_language_overlay', $localFieldName)
160 45
            && Util::getIsTYPO3VersionBelow9()) {
161 1
            return 'pages_language_overlay';
162
        }
163
164 45
        return $localTableName;
165
    }
166
167
    /**
168
     * Checks if TCA is available for column by table
169
     *
170
     * @param string $tableName
171
     * @param string $fieldName
172
     * @return bool
173
     */
174 45
    protected function isTcaConfiguredForTablesField(string $tableName, string $fieldName) : bool
175
    {
176 45
        return isset($GLOBALS['TCA'][$tableName]['columns'][$fieldName]);
177
    }
178
179
    /**
180
     * Gets the related items from a table using a n:m relation.
181
     *
182
     * @param string $localTableName Local table name
183
     * @param int $localRecordUid Local record uid
184
     * @param array $localFieldTca The local table's TCA
185
     * @return array Array of related items, values already resolved from related records
186
     */
187 42
    protected function getRelatedItemsFromMMTable($localTableName, $localRecordUid, array $localFieldTca)
188
    {
189 42
        $relatedItems = [];
190 42
        $foreignTableName = $localFieldTca['config']['foreign_table'];
191 42
        $foreignTableTca = $GLOBALS['TCA'][$foreignTableName];
192 42
        $foreignTableLabelField = $this->resolveForeignTableLabelField($foreignTableTca);
193 42
        $mmTableName = $localFieldTca['config']['MM'];
194
195
        // Remove the first option of foreignLabelField for recursion
196 42
        if (strpos($this->configuration['foreignLabelField'], '.') !== false) {
197
            $foreignTableLabelFieldArr = explode('.', $this->configuration['foreignLabelField']);
198
            unset($foreignTableLabelFieldArr[0]);
199
            $this->configuration['foreignLabelField'] = implode('.', $foreignTableLabelFieldArr);
200
        }
201
202 42
        $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
203 42
        $relationHandler->start('', $foreignTableName, $mmTableName, $localRecordUid, $localTableName, $localFieldTca['config']);
204 42
        $selectUids = $relationHandler->tableArray[$foreignTableName];
205 42
        if (!is_array($selectUids) || count($selectUids) <= 0) {
206 34
            return $relatedItems;
207
        }
208
209 10
        $relatedRecords = $this->getRelatedRecords($foreignTableName, ...$selectUids);
210 10
        foreach ($relatedRecords as $record) {
211 10
            if (isset($foreignTableTca['columns'][$foreignTableLabelField]['config']['foreign_table'])
212 10
                && $this->configuration['enableRecursiveValueResolution']
213
            ) {
214
                if (strpos($this->configuration['foreignLabelField'], '.') !== false) {
215
                    $foreignLabelFieldArr = explode('.', $this->configuration['foreignLabelField']);
216
                    unset($foreignLabelFieldArr[0]);
217
                    $this->configuration['foreignLabelField'] = implode('.', $foreignLabelFieldArr);
218
                }
219
220
                $this->configuration['localField'] = $foreignTableLabelField;
221
222
                $contentObject = GeneralUtility::makeInstance(ContentObjectRenderer::class);
223
                $contentObject->start($record, $foreignTableName);
224
225
                return $this->getRelatedItems($contentObject);
226
            } else {
227 10
                if ($GLOBALS['TSFE']->sys_language_uid > 0) {
228 5
                    $record = $this->getTranslationOverlay($foreignTableName, $record);
229
                }
230 10
                $relatedItems[] = $record[$foreignTableLabelField];
231
            }
232
        }
233
234 10
        return $relatedItems;
235
    }
236
237
    /**
238
     * Resolves the field to use as the related item's label depending on TCA
239
     * and TypoScript configuration
240
     *
241
     * @param array $foreignTableTca The foreign table's TCA
242
     * @return string The field to use for the related item's label
243
     */
244 45
    protected function resolveForeignTableLabelField(array $foreignTableTca)
245
    {
246 45
        $foreignTableLabelField = $foreignTableTca['ctrl']['label'];
247
248
        // when foreignLabelField is not enabled we can return directly
249 45
        if (empty($this->configuration['foreignLabelField'])) {
250 11
            return $foreignTableLabelField;
251
        }
252
253 36
        if (strpos($this->configuration['foreignLabelField'], '.') !== false) {
254 2
            list($foreignTableLabelField) = explode('.', $this->configuration['foreignLabelField'], 2);
255
        } else {
256 36
            $foreignTableLabelField = $this->configuration['foreignLabelField'];
257
        }
258
259 36
        return $foreignTableLabelField;
260
    }
261
262
    /**
263
     * Return the translated record
264
     *
265
     * @param string $tableName
266
     * @param array $record
267
     * @return array
268
     */
269 5
    protected function getTranslationOverlay($tableName, $record)
270
    {
271 5
        if ($tableName === 'pages') {
272 2
            return $GLOBALS['TSFE']->sys_page->getPageOverlay($record, $GLOBALS['TSFE']->sys_language_uid);
273
        }
274
275 4
        return $GLOBALS['TSFE']->sys_page->getRecordOverlay($tableName, $record, $GLOBALS['TSFE']->sys_language_uid);
276
    }
277
278
    /**
279
     * Gets the related items from a table using a 1:n relation.
280
     *
281
     * @param string $localTableName Local table name
282
     * @param int $localRecordUid Local record uid
283
     * @param array $localFieldTca The local table's TCA
284
     * @param ContentObjectRenderer $parentContentObject parent content object
285
     * @return array Array of related items, values already resolved from related records
286
     */
287 3
    protected function getRelatedItemsFromForeignTable(
288
        $localTableName,
289
        $localRecordUid,
290
        array $localFieldTca,
291
        ContentObjectRenderer $parentContentObject
292
    ) {
293 3
        $relatedItems = [];
294 3
        $foreignTableName = $localFieldTca['config']['foreign_table'];
295 3
        $foreignTableTca = $GLOBALS['TCA'][$foreignTableName];
296 3
        $foreignTableLabelField = $this->resolveForeignTableLabelField($foreignTableTca);
297
298
            /** @var $relationHandler RelationHandler */
299 3
        $relationHandler = GeneralUtility::makeInstance(RelationHandler::class);
300
301 3
        $itemList = isset($parentContentObject->data[$this->configuration['localField']]) ?
302 3
                        $parentContentObject->data[$this->configuration['localField']] : '';
303
304 3
        $relationHandler->start($itemList, $foreignTableName, '', $localRecordUid, $localTableName, $localFieldTca['config']);
305 3
        $selectUids = $relationHandler->tableArray[$foreignTableName];
306
307 3
        if (!is_array($selectUids) || count($selectUids) <= 0) {
308
            return $relatedItems;
309
        }
310
311 3
        $relatedRecords = $this->getRelatedRecords($foreignTableName, ...$selectUids);
312
313 3
        foreach ($relatedRecords as $relatedRecord) {
314 3
            $resolveRelatedValue = $this->resolveRelatedValue(
315 3
                $relatedRecord,
316 3
                $foreignTableTca,
317 3
                $foreignTableLabelField,
318 3
                $parentContentObject,
319 3
                $foreignTableName
320
            );
321 3
            if (!empty($resolveRelatedValue) || !$this->configuration['removeEmptyValues']) {
322 3
                $relatedItems[] = $resolveRelatedValue;
323
            }
324
        }
325
326 3
        return $relatedItems;
327
    }
328
329
    /**
330
     * Resolves the value of the related field. If the related field's value is
331
     * a relation itself, this method takes care of resolving it recursively.
332
     *
333
     * @param array $relatedRecord Related record as array
334
     * @param array $foreignTableTca TCA of the related table
335
     * @param string $foreignTableLabelField Field name of the foreign label field
336
     * @param ContentObjectRenderer $parentContentObject cObject
337
     * @param string $foreignTableName Related record table name
338
     *
339
     * @return string
340
     */
341 3
    protected function resolveRelatedValue(
342
        array $relatedRecord,
343
        $foreignTableTca,
344
        $foreignTableLabelField,
345
        ContentObjectRenderer $parentContentObject,
346
        $foreignTableName = ''
347
    ) {
348 3
        if ($GLOBALS['TSFE']->sys_language_uid > 0 && !empty($foreignTableName)) {
349
            $relatedRecord = $this->getTranslationOverlay($foreignTableName, $relatedRecord);
350
        }
351
352 3
        $value = $relatedRecord[$foreignTableLabelField];
353
354
        if (
355 3
            !empty($foreignTableName)
356 3
            && isset($foreignTableTca['columns'][$foreignTableLabelField]['config']['foreign_table'])
357 3
            && $this->configuration['enableRecursiveValueResolution']
358
        ) {
359
            // backup
360 2
            $backupRecord = $parentContentObject->data;
361 2
            $backupConfiguration = $this->configuration;
362
363
            // adjust configuration for next level
364 2
            $this->configuration['localField'] = $foreignTableLabelField;
365 2
            $parentContentObject->data = $relatedRecord;
366 2
            if (strpos($this->configuration['foreignLabelField'], '.') !== false) {
367 2
                list(, $this->configuration['foreignLabelField']) = explode('.',
368 2
                    $this->configuration['foreignLabelField'], 2);
369
            } else {
370 2
                $this->configuration['foreignLabelField'] = '';
371
            }
372
373
            // recursion
374 2
            $relatedItemsFromForeignTable = $this->getRelatedItemsFromForeignTable(
375 2
                $foreignTableName,
376 2
                $relatedRecord['uid'],
377 2
                $foreignTableTca['columns'][$foreignTableLabelField],
378 2
                $parentContentObject
379
            );
380 2
            $value = array_pop($relatedItemsFromForeignTable);
381
382
            // restore
383 2
            $this->configuration = $backupConfiguration;
384 2
            $parentContentObject->data = $backupRecord;
385
        }
386
387 3
        return $parentContentObject->stdWrap($value, $this->configuration);
388
    }
389
390
    /**
391
     * When the record has an overlay we retrieve the uid of the translated record,
392
     * to resolve the relations from the translation.
393
     *
394
     * @param string $localTableName
395
     * @param int $localRecordUid
396
     * @return int
397
     */
398 45
    protected function getUidOfRecordOverlay($localTableName, $localFieldName, $localRecordUid)
399
    {
400
        // when no language is set at all we do not need to overlay
401 45
        if (!isset($GLOBALS['TSFE']->sys_language_uid)) {
402
            return $localRecordUid;
403
        }
404
        // when no language is set we can return the passed recordUid
405 45
        if (!$GLOBALS['TSFE']->sys_language_uid > 0) {
406 43
            return $localRecordUid;
407
        }
408
        // when no TCA configured for pages_language_overlay's field, then use original record Uid
409
        // @todo this can be dropped when TYPO3 8 compatibility is dropped
410 5
        $translatedInPagesLanguageOverlayAndNoTCAPresent = Util::getIsTYPO3VersionBelow9() && !$this->isTcaConfiguredForTablesField('pages_language_overlay', $localFieldName);
411 5
        if ($localTableName === 'pages' && $translatedInPagesLanguageOverlayAndNoTCAPresent) {
412 2
            return $localRecordUid;
413
        }
414
415
        /** @var QueryBuilder $queryBuilder */
416 3
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)
417 3
            ->getQueryBuilderForTable($localTableName);
418
419
        $record = $queryBuilder
420 3
            ->select('*')
421 3
            ->from($localTableName)
422 3
            ->where(
423 3
                $queryBuilder->expr()->eq('uid', $localRecordUid)
424
            )
425 3
            ->execute()
426 3
            ->fetch();
427
428
        // when the overlay is not an array, we return the localRecordUid
429 3
        if (!is_array($record)) {
430
            return $localRecordUid;
431
        }
432
433 3
        $overlayUid = $this->getLocalRecordUidFromOverlay($localTableName, $record);
434 3
        $localRecordUid = ($overlayUid !== 0) ? $overlayUid : $localRecordUid;
435 3
        return $localRecordUid;
436
    }
437
438
    /**
439
     * This method retrieves the _PAGES_OVERLAY_UID or _LOCALIZED_UID from the localized record.
440
     *
441
     * @param string $localTableName
442
     * @param array $overlayRecord
443
     * @return int
444
     */
445 3
    protected function getLocalRecordUidFromOverlay($localTableName, $overlayRecord)
446
    {
447 3
        $overlayRecord = $this->getTranslationOverlay($localTableName, $overlayRecord);
448
449
        // when there is a _PAGES_OVERLAY_UID | _LOCALIZED_UID in the overlay, we return it
450 3
        if ($localTableName === 'pages' && isset($overlayRecord['_PAGES_OVERLAY_UID'])) {
451 1
            return (int)$overlayRecord['_PAGES_OVERLAY_UID'];
452 2
        } elseif (isset($overlayRecord['_LOCALIZED_UID'])) {
453 2
            return (int)$overlayRecord['_LOCALIZED_UID'];
454
        }
455
456
        return 0;
457
    }
458
459
    /**
460
     * Return records via relation.
461
     *
462
     * @param string $foreignTable The table to fetch records from.
463
     * @param int[] ...$uids The uids to fetch from table.
464
     * @return array
465
     */
466 13
    protected function getRelatedRecords($foreignTable, int ...$uids): array
467
    {
468
        /** @var QueryBuilder $queryBuilder */
469 13
        $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)->getQueryBuilderForTable($foreignTable);
470 13
        $queryBuilder->select('*')
471 13
            ->from($foreignTable)
472 13
            ->where($queryBuilder->expr()->in('uid', $uids));
473 13
        if (isset($this->configuration['additionalWhereClause'])) {
474 2
            $queryBuilder->andWhere($this->configuration['additionalWhereClause']);
475
        }
476 13
        $statement = $queryBuilder->execute();
477
478 13
        return $this->sortByKeyInIN($statement, 'uid', ...$uids);
0 ignored issues
show
Bug introduced by
$uids of type integer is incompatible with the type array expected by parameter $arrayWithValuesForIN of ApacheSolrForTypo3\Solr\...lation::sortByKeyInIN(). ( Ignorable by Annotation )

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

478
        return $this->sortByKeyInIN($statement, 'uid', /** @scrutinizer ignore-type */ ...$uids);
Loading history...
Bug introduced by
It seems like $statement can also be of type integer; however, parameter $statement of ApacheSolrForTypo3\Solr\...lation::sortByKeyInIN() does only seem to accept Doctrine\DBAL\Driver\Statement, 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

478
        return $this->sortByKeyInIN(/** @scrutinizer ignore-type */ $statement, 'uid', ...$uids);
Loading history...
479
    }
480
481
    /**
482
     * Sorts the result set by key in array for IN values.
483
     *   Simulates MySqls ORDER BY FIELD(fieldname, COPY_OF_IN_FOR_WHERE)
484
     *   Example: SELECT * FROM a_table WHERE field_name IN (2, 3, 4) SORT BY FIELD(field_name, 2, 3, 4)
485
     *
486
     *
487
     * @param Statement $statement
488
     * @param string $columnName
489
     * @param array $arrayWithValuesForIN
490
     * @return array
491
     */
492 13
    protected function sortByKeyInIN(Statement $statement, string $columnName, ...$arrayWithValuesForIN) : array
493
    {
494 13
        $records = [];
495 13
        while ($record = $statement->fetch()) {
496 13
            $indexNumber = array_search($record[$columnName], $arrayWithValuesForIN);
497 13
            $records[$indexNumber] = $record;
498
        }
499 13
        ksort($records);
500 13
        return $records;
501
    }
502
}
503