Completed
Push — master ( db00dc...830fb6 )
by Vitaly
02:37
created

Material   B

Complexity

Total Complexity 37

Size/Duplication

Total Lines 282
Duplicated Lines 8.51 %

Coupling/Cohesion

Components 2
Dependencies 6

Importance

Changes 4
Bugs 1 Features 3
Metric Value
wmc 37
c 4
b 1
f 3
lcom 2
cbo 6
dl 24
loc 282
rs 8.6

6 Methods

Rating   Name   Duplication   Size   Complexity  
A byUrl() 8 8 2
B setFieldByID() 0 37 5
A selectText() 0 19 4
B gallery() 0 31 5
C copy() 16 42 8
D getTable() 0 89 13

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

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 \samsonframework\orm\QueryInterface;
9
10
/**
11
 * SamsonCMS Material database record object.
12
 * This class extends default ActiveRecord material table record functionality.
13
 * @package samson\cms
14
 * @author Vitaly Egorov <[email protected]>
15
 */
16
class Material extends \samson\activerecord\material
17
{
18
    /** Override table attributes for late static binding */
19
    public static $_attributes = array();
20
    public static $_sql_select = array();
21
    public static $_sql_from = array();
22
    public static $_own_group = array();
23
    public static $_map = array();
24
25
    /**
26
     * Get material entities collection by URL(s).
27
     * @param QueryInterface $query Object for performing database queries
28
     * @param array|string $url Material URL or collection of material URLs
29
     * @param self[]|array|null $return Variable where request result would be returned
30
     * @return bool|self[] True if material entities has been found
31
     */
32 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...
33
    {
34
        // Get field record by identifier column
35
        $return = static::collectionByColumn($query, 'Url', $url);
0 ignored issues
show
Bug introduced by
It seems like $url defined by parameter $url on line 32 can also be of type array; however, samsonframework\orm\Record::collectionByColumn() does only seem to accept string, 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...
36
37
        // If only one argument is passed - return null, otherwise bool
38
        return func_num_args() > 1 ? $return == null : $return;
39
    }
40
41
    /**
42
     * Set additional material field value by field identifier
43
     * @param string $fieldID Field identifier
44
     * @param string $value Value to be stored
45
     * @param string $locale Locale identifier
46
     */
47
    public function setFieldByID($fieldID, $value, $locale = DEFAULT_LOCALE)
48
    {
49
        // TODO: This should be removed
50
        /** @var QueryInterface $query This should be removed to use $this->database*/
51
        $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...
52
53
        /** @var Field $fieldRecord Try to find this additional field */
54
        $fieldRecord = null;
55
        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...
56
            /** @var MaterialField $materialFieldRecord Try to find additional field value */
57
            $materialFieldRecord = null;
58
            if (!MaterialField::byFieldIDAndMaterialID($query, $this->id, $fieldRecord->id, $materialFieldRecord)) {
59
                // Create new additional field value record if it does not exists
60
                $materialFieldRecord = new MaterialField();
61
                $materialFieldRecord->FieldID = $fieldRecord->id;
62
                $materialFieldRecord->MaterialID = $this->id;
63
                $materialFieldRecord->Active = 1;
64
                $materialFieldRecord->locale = $locale;
65
            }
66
67
            // Define which field should be filled
68
            switch ($fieldRecord->Type) {
69
                case 1:
70
                    $valueFieldName = 'numeric_value';
71
                    break;
72
                case 2:
73
                    $valueFieldName = 'key_value';
74
                    break;
75
                default:
76
                    $valueFieldName = 'Value';
77
            }
78
79
            // At this point we already have database record instance
80
            $fieldRecord->$valueFieldName = $value;
81
            $fieldRecord->save();
82
        }
83
    }
84
85
    /**
86
     * Get select additional field text value
87
     * TODO: Find where do we use it
88
     * @return string Select field text
89
     */
90
    public function selectText($fieldID)
91
    {
92
        /** @var \samson\activerecord\field $field */
93
        $field = null;
94
        if (dbQuery('field')->id($fieldID)->first($field)) {
95
            // If this entity has this field set
96
            if (isset($this[$field->Name]{0})) {
97
                $types = array();
98
                foreach (explode(',', $field->Value) as $typeValue) {
0 ignored issues
show
Bug introduced by
The property Value does not seem to exist in samson\activerecord\Field.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
99
                    $typeValue = explode(':', $typeValue);
100
                    $types[$typeValue[0]] = $typeValue[1];
101
                }
102
                return $types[$this[$field->Name]];
0 ignored issues
show
Bug introduced by
The property Name does not seem to exist in samson\activerecord\Field.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
103
            }
104
        }
105
106
        // Value not set
107
        return '';
108
    }
109
110
    /**
111
     * Get collection of images for material by gallery additional field selector. If none is passed
112
     * all images from gallery table would be returned for this material entity.
113
     *
114
     * @param string|null $fieldSelector Additional field selector value
115
     * @param string $selector Additional field field name to search for
116
     * @return \samson\activerecord\gallery[] Collection of images in this gallery additional field for material
117
     */
118
    public function &gallery($fieldSelector = null, $selector = 'FieldID')
119
    {
120
        /** @var \samson\activerecord\gallery[] $images Get material images for this gallery */
121
        $images = array();
122
123
        /* @var \samson\activerecord\field Get field object if we need to search it by other fields */
124
        $field = null;
0 ignored issues
show
Unused Code introduced by
$field 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...
125
        if ($selector != 'FieldID') {
126
            $field = dbQuery('field')->cond($selector, $fieldSelector)->first();
127
            $fieldSelector = $field->id;
128
        }
129
130
        // Create query
131
        $query = dbQuery('materialfield');
132
133
        // Add field filter if present
134
        if (isset($fieldSelector)) {
135
            $query->cond("FieldID", $fieldSelector);
136
        }
137
138
        /** @var \samson\activerecord\materialfield $dbMaterialField Find material field gallery record */
139
        $dbMaterialField = null;
140
        if ($query->cond('MaterialID', $this->id)->first($dbMaterialField)) {
141
            // Get material images for this materialfield
142
            if (dbQuery('gallery')->cond('materialFieldId', $dbMaterialField->id)->exec($images)) {
143
144
            }
145
        }
146
147
        return $images;
148
    }
149
150
    /**
151
     * Create copy of current object
152
     * @param mixed $clone Material for cloning
153
     * @param array $excludedFields excluded from materialfield fields identifiers
154
     * @returns void
155
     */
156
    public function &copy(& $clone = null, $excludedFields = array())
157
    {
158
        // Create new instance by copying
159
        $clone = parent::copy($clone);
160
161
        /** @var \samson\activerecord\structurematerial[] $objects Create structure material relations */
162
        $objects = array();
163 View Code Duplication
        if (dbQuery('structurematerial')->cond('MaterialID', $this->MaterialID)->exec($objects)) {
0 ignored issues
show
Bug introduced by
The property MaterialID does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
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...
164
            foreach ($objects as $cmsNavigation) {
165
                /** @var \samson\activerecord\Record $copy */
166
                $copy = $cmsNavigation->copy();
167
                $copy->MaterialID = $clone->id;
168
                $copy->save();
169
            }
170
        }
171
        /** @var \samson\activerecord\materialfield[] $objects Create material field relations */
172
        $objects = array();
173
        if (dbQuery('materialfield')->cond('MaterialID', $this->MaterialID)->exec($objects)) {
174
            foreach ($objects as $pMaterialField) {
175
                // Check if field is NOT excluded from copying
176
                if (!in_array($pMaterialField->FieldID, $excludedFields)) {
177
                    /** @var \samson\activerecord\dbRecord $copy Copy instance */
178
                    $copy = $pMaterialField->copy();
179
                    $copy->MaterialID = $clone->id;
0 ignored issues
show
Bug introduced by
The property MaterialID does not seem to exist in samson\activerecord\dbRecord.

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
180
                    $copy->save();
181
                }
182
            }
183
        }
184
185
        /** @var \samson\activerecord\gallery[] $objects Create gallery field relations */
186
        $objects = array();
187 View Code Duplication
        if (dbQuery('gallery')->cond('MaterialID', $this->MaterialID)->exec($objects)) {
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...
188
            foreach ($objects as $cmsGallery) {
189
                /** @var \samson\activerecord\Record $copy */
190
                $copy = $cmsGallery->copy();
191
                $copy->MaterialID = $clone->id;
192
                $copy->save();
193
            }
194
        }
195
196
        return $clone;
197
    }
198
199
    /**
200
     * Function to retrieve this material table by specified field
201
     * @param string $tableSelector Selector to identify table structure
202
     * @param string $selector Database field by which search is performed
203
     * @param array $tableColumns Columns names list
204
     * @param string $externalHandler External handler to perform some extra code
205
     * @param array $params External handler params
206
     * @return array Collection of collections of table cells, represented as materialfield objects
207
     */
208
    public function getTable($tableSelector, $selector = 'StructureID', &$tableColumns = null, $externalHandler = null, $params = array())
209
    {
210
        /** @var array $resultTable Collection of collections of field cells */
211
        $resultTable = array();
212
        /** @var array $dbTableFieldsIds Array of table structure column identifiers */
213
        $dbTableFieldsIds = array();
214
215
        // Get structure object if we need to search it by other fields
216
        if ($selector != 'StructureID') {
217
            $structure = dbQuery('structure')->cond($selector, $tableSelector)->first();
218
            $tableSelector = $structure->id;
219
        }
220
221
        /** If this table has columns */
222
        if (dbQuery('structurefield')
223
            ->cond("StructureID", $tableSelector)
224
            ->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...
225
        ) {
226
            // Get localized and not localized fields
227
            $localizedFields = array();
228
            $unlocalizedFields = array();
229
            /** @var \samson\cms\CMSField $dbTableField Table column */
230
            foreach (dbQuery('field')->order_by('priority')->cond('FieldID', $dbTableFieldsIds)->exec() as $field) {
231
                /** Add table columns names */
232
                $tableColumns[] = $field->Name;
233
                if ($field->local == 1) {
234
                    $localizedFields[] = $field->id;
235
                } else {
236
                    $unlocalizedFields[] = $field->id;
237
                }
238
            }
239
240
            // Query to get table rows(table materials)
241
            $tableQuery = dbQuery('material')
242
                ->cond('parent_id', $this->MaterialID)
243
                ->cond('Active', '1')
244
                ->join('structurematerial')
245
                ->cond('structurematerial_StructureID', $tableSelector)
246
                ->order_by('priority');
247
248
            // Call user function if exists
249
            if (is_callable($externalHandler)) {
250
                // Give it query as parameter
251
                call_user_func_array($externalHandler, array_merge(array(&$tableQuery), $params));
252
            }
253
254
            // Get table row materials
255
            $tableMaterialIds = array();
256
            if ($tableQuery->fields('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...
257
                // Create field condition
258
                $localizationFieldCond = new Condition('or');
259
260
                // Create localized condition
261
                if (sizeof($localizedFields)) {
262
                    $localizedFieldCond = new Condition('and');
263
                    $localizedFieldCond->add('materialfield_FieldID', $localizedFields)
264
                        ->add('materialfield_locale', locale());
265
                    // Add this condition to condition group
266
                    $localizationFieldCond->add($localizedFieldCond);
267
                }
268
269
                // Create not localized condition
270
                if (sizeof($unlocalizedFields)) {
271
                    $localizationFieldCond->add('materialfield_FieldID', $unlocalizedFields);
272
                }
273
274
                // Create db query
275
                $materialFieldQuery = dbQuery('materialfield')
276
                    ->cond('MaterialID', $tableMaterialIds)
277
                    ->cond($localizationFieldCond);
278
279
                // Flip field identifiers as keys
280
                $tableColumnIds = array_flip($dbTableFieldsIds);
281
                $resultTable = array_flip($tableMaterialIds);
282
283
                /** @var \samson\activerecord\material $dbTableRow Material object (table row) */
284
                foreach ($materialFieldQuery->exec() as $mf) {
285
                    if (!is_array($resultTable[$mf['MaterialID']])) {
286
                        $resultTable[$mf['MaterialID']] = array();
287
                    }
288
289
                    $resultTable[$mf['MaterialID']][$tableColumnIds[$mf->FieldID]] =
290
                        !empty($mf->Value) ? $mf->Value : (!empty($mf->numeric_value) ? $mf->numeric_value : $mf->key_value);
291
                }
292
            }
293
        }
294
295
        return array_values($resultTable);
296
    }
297
}
298