Completed
Push — master ( 96d385...d5a6c2 )
by Vitaly
04:18
created

Material::nestedIDs()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 19
rs 9.4286
cc 2
eloc 11
nc 2
nop 2
1
<?php
2
/**
3
 * Created by Vitaly Iegorov <[email protected]>
4
 * on 07.08.14 at 17:11
5
 */
6
namespace samsoncms\api;
7
8
use samson\activerecord\dbQuery;
9
use \samsonframework\orm\Condition;
10
use samsonframework\orm\Query;
11
use \samsonframework\orm\QueryInterface;
12
13
/**
14
 * SamsonCMS Material database record object.
15
 * This class extends default ActiveRecord material table record functionality.
16
 * @package samson\cms
17
 * @author Vitaly Egorov <[email protected]>
18
 */
19
class Material extends \samson\activerecord\material
20
{
21
    /** Override table attributes for late static binding */
22
    public static $_attributes = array();
23
    public static $_sql_select = array();
24
    public static $_sql_from = array();
25
    public static $_own_group = array();
26
    public static $_map = array();
27
28
    /** @var integer Primary field */
29
    public $MaterialID;
30
31
    /** @var string Unique identifier */
32
    public $Url;
33
34
    /** @var bool Internal existence flag */
35
    public $Active;
36
37
    /**
38
     * Get identifiers collection by field identifier and its value.
39
     * Method is optimized for performance.
40
     *
41
     * @param QueryInterface $query Database query instance
42
     * @param string $fieldID Additional field identifier
43
     * @param string $fieldValue Additional field value for searching
44
     * @param array|null $return Variable where request result would be returned
45
     * @param array $materialIDs Collection of material identifiers for filtering query
46
     * @return bool|array True if material entities has been found and $return is passed
47
     *                      or identifiers collection if only two parameters is passed.
48
     */
49
    public static function idsByFieldValue(
50
        QueryInterface $query,
51
        $fieldID,
52
        $fieldValue,
53
        &$return = array(),
54
        $materialIDs = null
55
    ) {
56
        /** @var Field $fieldRecord We need to have field record */
57
        $fieldRecord = null;
58
        if (Field::byID($query, $fieldID, $fieldRecord)) {
0 ignored issues
show
Documentation introduced by
$fieldRecord is of type object<samsoncms\api\Field>, but the function expects a null|object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
59
            $materials = array();
60
61
            // Get material identifiers by field
62
            $query->entity(CMS::MATERIAL_FIELD_RELATION_ENTITY)
63
                ->where('MaterialID', $materials)
0 ignored issues
show
Documentation introduced by
$materials is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
64
                ->where('Active', 1)
65
                ->where('FieldID', $fieldID)
66
                ->where($fieldRecord->valueFieldName(), $fieldValue);
67
68
            // Add material identifier filter if passed
69
            if (isset($materialIDs)) {
70
                $query->where('MaterialID', $materialIDs);
0 ignored issues
show
Documentation introduced by
$materialIDs is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
71
            }
72
73
            // Perform database query and get only material identifiers collection
74
            $return = $query->fields('MaterialID');
75
        }
76
77
        // If only one argument is passed - return null, otherwise bool
78
        return func_num_args() > 3 ? sizeof($return) : $return;
79
    }
80
81
    /**
82
     * Get current entity identifiers collection by navigation identifier.
83
     *
84
     * @param QueryInterface $query Database query
85
     * @param string $navigationID Navigation identifier
86
     * @param array $return Variable where request result would be returned
87
     * @param array $materialIDs Collection of material identifiers for filtering query
88
     * @return bool|array True if material entities has been found and $return is passed
89
     *                      or collection of identifiers if only two parameters is passed.
90
     */
91 View Code Duplication
    public static function idsByNavigationID(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
92
        QueryInterface $query,
93
        $navigationID,
94
        &$return = array(),
95
        $materialIDs = null
96
    ) {
97
        // Prepare query
98
         $query->entity(CMS::MATERIAL_NAVIGATION_RELATION_ENTITY)
99
            ->where('StructureID', $navigationID)
100
            ->where('Active', 1);
101
102
        // Add material identifier filter if passed
103
        if (isset($materialIDs)) {
104
            $query->where('MaterialID', $materialIDs);
0 ignored issues
show
Documentation introduced by
$materialIDs is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
105
        }
106
107
        // Perform database query and get only material identifiers collection
108
        $return = $query->fields('MaterialID');
109
110
        // If only one argument is passed - return null, otherwise bool
111
        return func_num_args() > 2 ? sizeof($return) : $return;
112
    }
113
114
    /**
115
     * Get current entity instances collection by their identifiers.
116
     * Method can accept different query executors.
117
     *
118
     * @param QueryInterface $query Database query
119
     * @param string|array $materialIDs Material identifier or their colleciton
120
     * @param self[]|array|null $return Variable where request result would be returned
121
     * @param string $executor Method name for query execution
122
     * @return bool|self[] True if material entities has been found and $return is passed
123
     *                      or self[] if only two parameters is passed.
124
     */
125 View Code Duplication
    public static function byIDs(QueryInterface $query, $materialIDs, &$return = array(), $executor = 'exec')
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
126
    {
127
        $return = $query->entity(get_called_class())
128
            ->where('MaterialID', $materialIDs)
0 ignored issues
show
Bug introduced by
It seems like $materialIDs defined by parameter $materialIDs on line 125 can also be of type array; however, samsonframework\orm\QueryInterface::where() does only seem to accept string|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
129
            ->where('Active', 1)
130
            ->where('Published', 1)
131
            ->$executor();
132
133
        // If only one argument is passed - return null, otherwise bool
134
        return func_num_args() > 2 ? sizeof($return) : $return;
135
    }
136
137
    /**
138
     * Get self[] by field identifier and its value.
139
     * Method is optimized for performance.
140
     *
141
     * @param QueryInterface $query Database query instance
142
     * @param string $fieldID Additional field identifier
143
     * @param string $fieldValue Additional field value for searching
144
     * @param self[]|array|null $return Variable where request result would be returned
145
     * @return bool|self[] True if material entities has been found and $return is passed
146
     *                      or self[] if only two parameters is passed.
147
     */
148 View Code Duplication
    public static function byFieldValue(QueryInterface $query, $fieldID, $fieldValue, &$return = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
149
    {
150
        /** @var array $materialIds Collection of entity identifiers filtered by additional field */
151
        $materialIds = null;
152
        if (static::idsByFieldValue($query, $fieldID, $fieldValue, $materialIds)) {
153
            static::byIDs($query, $materialIds, $return);
0 ignored issues
show
Bug introduced by
It seems like $materialIds defined by null on line 151 can also be of type null; however, samsoncms\api\Material::byIDs() does only seem to accept string|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
154
        }
155
156
        // If only one argument is passed - return null, otherwise bool
157
        return func_num_args() > 3 ? sizeof($return) : $return;
158
    }
159
160
    /**
161
     * Get current entity instances collection by navigation identifier.
162
     *
163
     * @param QueryInterface $query Database query
164
     * @param string $navigationID Navigation identifier
165
     * @param self[]|array|null $return Variable where request result would be returned
166
     * @return bool|self[] True if material entities has been found and $return is passed
167
     *                      or self[] if only two parameters is passed.
168
     */
169 View Code Duplication
    public static function byNavigationID(QueryInterface $query, $navigationID, &$return = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
170
    {
171
        /** @var array $materialIds Collection of entity identifiers filtered by additional field */
172
        $materialIds = null;
173
        if (static::idsByNavigationID($query, $navigationID, $materialIds)) {
174
            static::byIDs($query, $materialIds, $return);
175
        }
176
177
        // If only one argument is passed - return null, otherwise bool
178
        return func_num_args() > 2 ? sizeof($return) : $return;
179
    }
180
181
    /**
182
     * Get current entity instances amount by navigation identifier.
183
     *
184
     * @param QueryInterface $query Database query
185
     * @param string $navigationID Navigation identifier
186
     * @param self[]|array|null $return Variable where request result would be returned
187
     * @return bool|self[] True if material entities has been found and $return is passed
188
     *                      or self[] if only two parameters is passed.
189
     */
190 View Code Duplication
    public static function amountByNavigationID(QueryInterface $query, $navigationID, &$return = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
191
    {
192
        /** @var array $materialIds Collection of entity identifiers filtered by additional field */
193
        $materialIds = null;
194
        if (static::idsByNavigationID($query, $navigationID, $materialIds)) {
195
            static::byIDs($query, $materialIds, $return, 'count');
196
        }
197
198
        // If only one argument is passed - return null, otherwise bool
199
        return func_num_args() > 2 ? sizeof($return) : $return;
200
    }
201
202
    /**
203
     * Get current entity instances collection by navigation identifier and additional field value.
204
     *
205
     * @param QueryInterface $query Database query
206
     * @param string $navigationID Navigation identifier
207
     * @param string $fieldID Additional field identifier
208
     * @param string $fieldValue Additional field value for searching
209
     * @param self[]|array|null $return Variable where request result would be returned
210
     * @return bool|self[] True if material entities has been found and $return is passed
211
     *                      or self[] if only two parameters is passed.
212
     */
213 View Code Duplication
    public static function byNavigationIdAndFieldValue(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
214
        QueryInterface $query,
215
        $navigationID,
216
        $fieldID,
217
        $fieldValue,
218
        &$return = array()
219
    ) {
220
        /** @var array $materialIds Collection of entity identifiers filtered by additional field */
221
        $materialIds = null;
222
        if (static::idsByNavigationID($query, $navigationID, $materialIds)) {
223
            if (static::idsByFieldValue($query, $fieldID, $fieldValue, $materialIds, $materialIds)) {
224
                static::byIDs($query, $materialIds, $return);
0 ignored issues
show
Bug introduced by
It seems like $materialIds defined by null on line 221 can also be of type null; however, samsoncms\api\Material::byIDs() does only seem to accept string|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
225
            }
226
        }
227
228
        // If only one argument is passed - return null, otherwise bool
229
        return func_num_args() > 4 ? sizeof($return) : $return;
230
    }
231
232
    /**
233
     * Get current entity instances amount by navigation identifier and additional field value.
234
     *
235
     * @param QueryInterface $query Database query
236
     * @param string $navigationID Navigation identifier
237
     * @param string $fieldID Additional field identifier
238
     * @param string $fieldValue Additional field value for searching
239
     * @param self[]|array|null $return Variable where request result would be returned
240
     * @return bool|self[] True if material entities has been found and $return is passed
241
     *                      or self[] if only two parameters is passed.
242
     */
243 View Code Duplication
    public static function amountByNavigationIdAndFieldValue(
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
244
        QueryInterface $query,
245
        $navigationID,
246
        $fieldID,
247
        $fieldValue,
248
        &$return = array()
249
    ) {
250
        /** @var array $materialIds Collection of entity identifiers filtered by additional field */
251
        $materialIds = null;
252
        if (static::idsByNavigationID($query, $navigationID, $materialIds)) {
253
            if (static::idsByFieldValue($query, $fieldID, $fieldValue, $materialIds, $materialIds)) {
254
                static::byIDs($query, $materialIds, $return, 'count');
0 ignored issues
show
Bug introduced by
It seems like $materialIds defined by null on line 251 can also be of type null; however, samsoncms\api\Material::byIDs() does only seem to accept string|array, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
255
            }
256
        }
257
258
        // If only one argument is passed - return null, otherwise bool
259
        return func_num_args() > 4 ? sizeof($return) : $return;
260
    }
261
262
    /**
263
     * Get material entity by URL(s).
264
     *
265
     * @param QueryInterface $query Object for performing database queries
266
     * @param array|string $url Material URL or collection of material URLs
267
     * @param self|array|null $return Variable where request result would be returned
268
     * @return bool|self True if material entities has been found
269
     */
270 View Code Duplication
    public static function byUrl(QueryInterface $query, $url, & $return = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
    {
272
        // Get entities by filtered identifiers
273
        $return = $query->entity(get_called_class())
274
            ->where('Url', $url)
0 ignored issues
show
Bug introduced by
It seems like $url defined by parameter $url on line 270 can also be of type array; however, samsonframework\orm\QueryInterface::where() does only seem to accept string|null, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
275
            ->where('Active', 1)
276
            ->first();
277
278
        // If only one argument is passed - return null, otherwise bool
279
        return func_num_args() > 2 ? $return !== null : $return;
280
    }
281
282
    /**
283
     * Set additional material field value by field identifier
284
     * @param string $fieldID Field identifier
285
     * @param string $value Value to be stored
286
     * @param string $locale Locale identifier
287
     */
288
    public function setFieldByID($fieldID, $value, $locale = DEFAULT_LOCALE)
289
    {
290
        // TODO: This should be removed
291
        /** @var QueryInterface $query This should be removed to use $this->database*/
292
        $query = dbQuery();
0 ignored issues
show
Bug introduced by
The call to dbQuery() misses a required argument $class_name.

This check looks for function calls that miss required arguments.

Loading history...
293
294
        /** @var Field $fieldRecord Try to find this additional field */
295
        $fieldRecord = null;
296
        if (Field::byID($query, $fieldID, $fieldRecord)) {
0 ignored issues
show
Documentation introduced by
$fieldRecord is of type object<samsoncms\api\Field>, but the function expects a null|object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
297
            /** @var MaterialField[] $materialFieldRecord Try to find additional field value */
298
            $materialFieldRecord = null;
299
            if (!MaterialField::byFieldIDAndMaterialID($query, $this->id, $fieldRecord->id, $materialFieldRecord)) {
300
                // Create new additional field value record if it does not exists
301
                $materialFieldRecord = new MaterialField();
302
                $materialFieldRecord->FieldID = $fieldRecord->id;
303
                $materialFieldRecord->MaterialID = $this->id;
304
                $materialFieldRecord->Active = 1;
0 ignored issues
show
Documentation Bug introduced by
The property $Active was declared of type boolean, but 1 is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
305
                $materialFieldRecord->locale = $locale;
306
            } else { // Get first record(actually it should be only one)
307
                $materialFieldRecord = array_shift($materialFieldRecord);
308
            }
309
310
            // At this point we already have database record instance
311
            $valueFieldName = $fieldRecord->valueFieldName();
312
            $materialFieldRecord->$valueFieldName = $value;
313
            $materialFieldRecord->save();
314
        }
315
    }
316
317
    /**
318
     * Get select additional field text value.
319
     *
320
     * @param string $fieldID Field identifier
321
     * @return string Select field text
322
     */
323
    public function selectText($fieldID)
324
    {
325
        /** @var Field $field */
326
        $field = null;
327
        if (Field::byID(new Query('\samsoncms\api\Field', $this->database), $fieldID, $fieldID)) {
0 ignored issues
show
Documentation introduced by
$fieldID is of type string, but the function expects a null|object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
328
            // If this entity has this field set
329
            if (isset($this[$field->Name]{0})) {
330
                return $field->options($this[$field->Name]);
331
            }
332
        }
333
334
        // Value not set
335
        return '';
336
    }
337
338
    /**
339
     * Get collection of images for material by gallery additional field selector. If none is passed
340
     * all images from gallery table would be returned for this material entity.
341
     *
342
     * @param string|null $fieldSelector Additional field selector value
343
     * @param string $selector Additional field field name to search for
344
     * @return \samsonframework\orm\RecordInterface[] Collection of images in this gallery additional field for material
345
     */
346
    public function &gallery($fieldSelector = null, $selector = 'FieldID')
347
    {
348
        /** @var \samsonframework\orm\RecordInterface[] $images Get material images for this gallery */
349
        $images = array();
350
351
        // Create query
352
        $query = new dbQuery();
353
354
        $query->entity(CMS::MATERIAL_FIELD_RELATION_ENTITY);
355
356
        /* @var Field Get field object if we need to search it by other fields */
357
        $field = null;
358
        if ($selector != 'FieldID' && Field::oneByColumn($query, $selector, $fieldSelector)) {
359
            $fieldSelector = $field->id;
360
        }
361
362
        // Add field filter if present
363
        if (isset($fieldSelector)) {
364
            $query->where("FieldID", $fieldSelector);
365
        }
366
367
        /** @var \samson\activerecord\materialfield $dbMaterialField Find material field gallery record */
368
        $dbMaterialField = null;
369
        if ($query->where('MaterialID', $this->id)->first($dbMaterialField)) {
370
            // Get material images for this materialfield
371
            $images = $query->entity(CMS::MATERIAL_IMAGES_RELATION_ENTITY)
372
                ->where('materialFieldId', $dbMaterialField->id)
373
                ->exec();
374
        }
375
376
        return $images;
377
    }
378
379
    /**
380
     * Copy this material related entities.
381
     *
382
     * @param QueryInterface $query Database query instance
383
     * @param string $entity Entity identifier
384
     * @param string $newIdentifier Copied material idetifier
385
     * @param array $excludedIDs Collection of related entity identifier to exclude from copying
386
     */
387
    protected function copyRelatedEntity(QueryInterface $query, $entity, $newIdentifier, $excludedIDs = array())
388
    {
389
        // Copy additional fields
390
        foreach ($query->entity($entity)
0 ignored issues
show
Bug introduced by
The expression $query->entity($entity)-...is->MaterialID)->exec() of type boolean|object<samsonfra...rk\orm\RecordInterface> is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
391
                     ->where('MaterialID', $this->MaterialID)
392
                     ->exec() as $copiedEntity) {
393
            // Check if field is NOT excluded from copying
394
            if (!in_array($copiedEntity->id, $excludedIDs)) {
395
                /** @var MaterialField $copy Copy instance */
396
                $copy = $copiedEntity->copy();
397
                $copy->MaterialID = $newIdentifier;
0 ignored issues
show
Documentation Bug introduced by
The property $MaterialID was declared of type integer, but $newIdentifier is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
398
                $copy->save();
399
            }
400
        }
401
    }
402
403
    /**
404
     * Create copy of current object.
405
     *
406
     * @param mixed $clone Material for cloning
407
     * @param array $excludedFields Additional fields identifiers not copied
408
     * @returns self New copied instance
409
     */
410
    public function &copy(&$clone = null, $excludedFields = array())
411
    {
412
        /** @var Material $clone Create new instance by copying */
413
        $clone = parent::copy($clone);
414
415
        // Create query
416
        $query = new dbQuery();
417
418
        $this->copyRelatedEntity($query, CMS::MATERIAL_NAVIGATION_RELATION_ENTITY, $clone->id);
419
        $this->copyRelatedEntity($query, CMS::MATERIAL_FIELD_RELATION_ENTITY, $clone->id, $excludedFields);
420
        $this->copyRelatedEntity($query, CMS::MATERIAL_IMAGES_RELATION_ENTITY, $clone->id);
421
422
        return $clone;
423
    }
424
425
    public function nestedIDs($navigationID = null, &$return = array())
426
    {
427
        // Create query
428
        $query = new dbQuery();
429
430
        /** @var array $nestedIDs Get collection of materials by navigation */
431
        $nestedIDs = null;
432
        if (static::idsByNavigationID($query, $navigationID, $nestedIDs)) {
433
            // Get collection of nested materials
434
            $return = $query->entity(get_class($this))
435
                ->where('MaterialID', $nestedIDs)
0 ignored issues
show
Documentation introduced by
$nestedIDs is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
436
                ->where('Active', 1)
437
                ->where('parent_id', $this->id)
438
                ->orderBy('priority')
439
                ->fields('MaterialID');
440
        }
441
442
        return $return;
443
    }
444
445
    /**
446
     * Get material additional fields table.
447
     *
448
     * @param string $navigationID Navigation table identifier
449
     * @param array $tableColumns Columns names list
450
     * @param string $externalHandler External handler to perform some extra code
0 ignored issues
show
Bug introduced by
There is no parameter named $externalHandler. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
451
     * @param array $params External handler params
0 ignored issues
show
Bug introduced by
There is no parameter named $params. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
452
     * @return array Collection of collections of table cells, represented as materialfield objects
453
     */
454
    public function table($navigationID, &$tableColumns = null) {
455
        // Create query
456
        $query = new dbQuery();
457
458
        /** @var array $resultTable Collection of collections of field cells */
459
        $resultTable = array();
460
461
        /** @var array $dbTableFieldsIds Array of table structure column identifiers */
462
        $dbTableFieldsIds = array();
463
        if (Field::byNavigationID($query, $navigationID, $dbTableFieldsIds)) {
464
            // Get localized and not localized fields
465
            $localizedFields = array();
466
            $unlocalizedFields = array();
467
468
            /** @var Field $field Table column */
469
            foreach ($dbTableFieldsIds as $field) {
0 ignored issues
show
Bug introduced by
The expression $dbTableFieldsIds of type array|null is not guaranteed to be traversable. How about adding an additional type check?

There are different options of fixing this problem.

  1. If you want to be on the safe side, you can add an additional type-check:

    $collection = json_decode($data, true);
    if ( ! is_array($collection)) {
        throw new \RuntimeException('$collection must be an array.');
    }
    
    foreach ($collection as $item) { /** ... */ }
    
  2. If you are sure that the expression is traversable, you might want to add a doc comment cast to improve IDE auto-completion and static analysis:

    /** @var array $collection */
    $collection = json_decode($data, true);
    
    foreach ($collection as $item) { /** .. */ }
    
  3. Mark the issue as a false-positive: Just hover the remove button, in the top-right corner of this issue for more options.

Loading history...
470
                /** Add table columns names */
471
                $tableColumns[] = $field->Name;
472 View Code Duplication
                if ($field->local == 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
473
                    $localizedFields[] = $field->id;
474
                } else {
475
                    $unlocalizedFields[] = $field->id;
476
                }
477
            }
478
479
            // Get table row materials
480
            $tableRowsIDs = array();
481
            if ($this->nestedIDs($navigationID, $tableRowsIDs)) {
482
                // Create field condition
483
                $localizationFieldCond = new Condition('or');
484
485
                // Create localized condition
486
                if (sizeof($localizedFields)) {
487
                    $localizedFieldCond = new Condition('and');
488
                    $localizedFieldCond->add('FieldID', $localizedFields)
489
                        ->add('locale', locale());
490
                    // Add this condition to condition group
491
                    $localizationFieldCond->add($localizedFieldCond);
0 ignored issues
show
Bug introduced by
The call to add() misses a required argument $value.

This check looks for function calls that miss required arguments.

Loading history...
Documentation introduced by
$localizedFieldCond is of type object<samsonframework\orm\Condition>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
492
                }
493
494
                // Create not localized condition
495
                if (sizeof($unlocalizedFields)) {
496
                    $localizationFieldCond->add('FieldID', $unlocalizedFields);
497
                }// Create db query
498
                ;
499
500
                // Flip field identifiers as keys
501
                $tableColumnIds = array_flip($dbTableFieldsIds);
502
                $resultTable = array_flip($tableRowsIDs);
503
504
                /** @var \samson\activerecord\material $dbTableRow Material object (table row) */
505
                foreach ($query->entity(CMS::MATERIAL_FIELD_RELATION_ENTITY)
506
                             ->where('MaterialID', $tableRowsIDs)
0 ignored issues
show
Documentation introduced by
$tableRowsIDs is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
507
                             ->whereCondition($localizationFieldCond)->exec() as $mf) {
508 View Code Duplication
                    if (!is_array($resultTable[$mf['MaterialID']])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
509
                        $resultTable[$mf['MaterialID']] = array();
510
                    }
511
512
                    $resultTable[$mf['MaterialID']][$tableColumnIds[$mf->FieldID]] =
513
                        !empty($mf->Value) ? $mf->Value : (!empty($mf->numeric_value) ? $mf->numeric_value : $mf->key_value);
514
                }
515
            }
516
        }
517
518
        return array_values($resultTable);
519
    }
520
521
    /**
522
     * Function to retrieve this material table by specified field
523
     * @param string $tableSelector Selector to identify table structure
524
     * @param string $selector Database field by which search is performed
525
     * @param array $tableColumns Columns names list
526
     * @param string $externalHandler External handler to perform some extra code
527
     * @param array $params External handler params
528
     * @return array Collection of collections of table cells, represented as materialfield objects
529
     * @deprecated Use table()
530
     */
531
    public function getTable(
532
        $tableSelector,
533
        $selector = 'StructureID',
534
        &$tableColumns = null,
535
        $externalHandler = null,
536
        $params = array()
537
    ) {
538
        // Create query
539
        $query = new dbQuery();
0 ignored issues
show
Unused Code introduced by
$query is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
540
541
        /** @var array $resultTable Collection of collections of field cells */
542
        $resultTable = array();
543
        /** @var array $dbTableFieldsIds Array of table structure column identifiers */
544
        $dbTableFieldsIds = array();
545
546
        // Get structure object if we need to search it by other fields
547
        if ($selector != 'StructureID') {
548
            $structure = dbQuery('structure')->cond($selector, $tableSelector)->first();
0 ignored issues
show
Deprecated Code introduced by
The method samson\activerecord\dbQuery::cond() has been deprecated with message: @see self::where()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
549
            $tableSelector = $structure->id;
550
        }
551
552
        /** If this table has columns */
553
        if (dbQuery('structurefield')
0 ignored issues
show
Deprecated Code introduced by
The method samson\activerecord\dbQuery::cond() has been deprecated with message: @see self::where()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
554
            ->cond("StructureID", $tableSelector)
555
            ->fields('FieldID', $dbTableFieldsIds)
0 ignored issues
show
Documentation introduced by
$dbTableFieldsIds is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
556
        ) {
557
            // Get localized and not localized fields
558
            $localizedFields = array();
559
            $unlocalizedFields = array();
560
            /** @var \samson\cms\CMSField $dbTableField Table column */
561
            foreach (dbQuery('field')->order_by('priority')->cond('FieldID', $dbTableFieldsIds)->exec() as $field) {
0 ignored issues
show
Deprecated Code introduced by
The method samson\activerecord\dbQuery::cond() has been deprecated with message: @see self::where()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
562
                /** Add table columns names */
563
                $tableColumns[] = $field->Name;
564 View Code Duplication
                if ($field->local == 1) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
565
                    $localizedFields[] = $field->id;
566
                } else {
567
                    $unlocalizedFields[] = $field->id;
568
                }
569
            }
570
571
            // Query to get table rows(table materials)
572
            $tableQuery = dbQuery('material')
0 ignored issues
show
Deprecated Code introduced by
The method samson\activerecord\dbQuery::cond() has been deprecated with message: @see self::where()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
573
                ->cond('parent_id', $this->MaterialID)
574
                ->cond('Active', '1')
575
                ->join('structurematerial')
576
                ->cond('structurematerial_StructureID', $tableSelector)
577
                ->order_by('priority');
578
579
            // Call user function if exists
580
            if (is_callable($externalHandler)) {
581
                // Give it query as parameter
582
                call_user_func_array($externalHandler, array_merge(array(&$tableQuery), $params));
583
            }
584
585
            // Get table row materials
586
            $tableMaterialIds = array();
587
            if ($tableQuery->fields('MaterialID', $tableMaterialIds)) {
588
                // Create field condition
589
                $localizationFieldCond = new Condition('or');
590
591
                // Create localized condition
592
                if (sizeof($localizedFields)) {
593
                    $localizedFieldCond = new Condition('and');
594
                    $localizedFieldCond->add('materialfield_FieldID', $localizedFields)
595
                        ->add('materialfield_locale', locale());
596
                    // Add this condition to condition group
597
                    $localizationFieldCond->add($localizedFieldCond);
0 ignored issues
show
Bug introduced by
The call to add() misses a required argument $value.

This check looks for function calls that miss required arguments.

Loading history...
Documentation introduced by
$localizedFieldCond is of type object<samsonframework\orm\Condition>, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
598
                }
599
600
                // Create not localized condition
601
                if (sizeof($unlocalizedFields)) {
602
                    $localizationFieldCond->add('materialfield_FieldID', $unlocalizedFields);
603
                }
604
605
                // Create db query
606
                $materialFieldQuery = dbQuery('materialfield')
0 ignored issues
show
Deprecated Code introduced by
The method samson\activerecord\dbQuery::cond() has been deprecated with message: @see self::where()

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
607
                    ->cond('MaterialID', $tableMaterialIds)
0 ignored issues
show
Documentation introduced by
$tableMaterialIds is of type array, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
608
                    ->cond($localizationFieldCond);
0 ignored issues
show
Documentation introduced by
$localizationFieldCond is of type object<samsonframework\orm\Condition>, but the function expects a string|object<samson\act...cord\ArgumentInterface>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
609
610
                // Flip field identifiers as keys
611
                $tableColumnIds = array_flip($dbTableFieldsIds);
612
                $resultTable = array_flip($tableMaterialIds);
613
614
                /** @var \samson\activerecord\material $dbTableRow Material object (table row) */
615
                foreach ($materialFieldQuery->exec() as $mf) {
616 View Code Duplication
                    if (!is_array($resultTable[$mf['MaterialID']])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
617
                        $resultTable[$mf['MaterialID']] = array();
618
                    }
619
620
                    $resultTable[$mf['MaterialID']][$tableColumnIds[$mf->FieldID]] =
621
                        !empty($mf->Value) ? $mf->Value : (!empty($mf->numeric_value) ? $mf->numeric_value : $mf->key_value);
622
                }
623
            }
624
        }
625
626
        return array_values($resultTable);
627
    }
628
}
629