Completed
Push — master ( 02e059...1bc464 )
by Nicolaas
02:11
created

ProductAttributeType   D

Complexity

Total Complexity 58

Size/Duplication

Total Lines 434
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 16

Importance

Changes 0
Metric Value
wmc 58
lcom 1
cbo 16
dl 0
loc 434
rs 4.5205
c 0
b 0
f 0

16 Methods

Rating   Name   Duplication   Size   Complexity  
A i18n_singular_name() 0 4 1
A i18n_plural_name() 0 4 1
A get_plural_name() 0 5 1
A find_or_make() 0 19 3
B getCMSFields() 0 33 2
A CMSEditLink() 0 8 1
A addValues() 0 5 1
A convertArrayToValues() 0 14 3
B getDropDownField() 0 16 6
B getValuesForDropdown() 0 19 5
A canDelete() 0 14 4
B onBeforeWrite() 0 16 5
C onAfterWrite() 0 61 14
A onBeforeDelete() 0 12 3
C cleanup() 0 25 7
A getFullName() 0 11 1

How to fix   Complexity   

Complex Class

Complex classes like ProductAttributeType 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 ProductAttributeType, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * This class contains list items such as "size", "colour"
5
 * Not XL, Red, etc..., but the lists that contain the
6
 * ProductAttributeValues.
7
 * For a clothing store you will have two entries:
8
 * - Size
9
 * - Colour
10
 *
11
 *
12
 */
13
14
class ProductAttributeType extends DataObject implements EditableEcommerceObject
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
15
{
16
17
    /**
18
     * Standard SS variable.
19
     */
20
    private static $api_access = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $api_access is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
21
        'view' => array(
22
            "Name",
23
            "Label",
24
            "Values"
25
        )
26
    );
27
28
    /**
29
     * Standard SS variable.
30
     */
31
    private static $db = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $db is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
32
        'Name' => 'Varchar', //for back-end use
33
        'Label' => 'Varchar', //for front-end use
34
        'Sort' => 'Int', //for front-end use
35
        'MergeIntoNote' => 'Varchar(255)'
36
        //'Unit' => 'Varchar' //TODO: for future use
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
37
    );
38
39
    /**
40
     * Standard SS variable.
41
     */
42
    private static $has_one = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $has_one is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
43
        'MoreInfoLink' => 'SiteTree',
44
        'MergeInto' => 'ProductAttributeType'
45
    );
46
47
    /**
48
     * Standard SS variable.
49
     */
50
    private static $has_many = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $has_many is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
51
        'Values' => 'ProductAttributeValue'
52
    );
53
54
    /**
55
     * Standard SS variable.
56
     */
57
    private static $summary_fields = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $summary_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
58
        'FullName' => 'Type'
59
    );
60
61
    /**
62
     * Standard SS variable.
63
     */
64
    private static $searchable_fields = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $searchable_fields is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
65
        'Name' => 'PartialMatchFilter',
66
        'Label' => 'PartialMatchFilter'
67
    );
68
69
    /**
70
     * Standard SS variable.
71
     */
72
    private static $belongs_many_many = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $belongs_many_many is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
73
        'Products' => 'Product'
74
    );
75
76
    /**
77
     * Standard SS variable.
78
     */
79
    private static $casting = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $casting is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
80
        'FullName' => 'Varchar'
81
    );
82
83
    /**
84
     * Standard SS variable.
85
     */
86
    private static $indexes = array(
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $indexes is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
87
        "Sort" => true
88
    );
89
90
    /**
91
     * Standard SS variable.
92
     */
93
    private static $default_sort = "\"Sort\" ASC, \"Name\"";
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $default_sort is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
94
95
    private static $dropdown_field_for_orderform = 'DropdownField';
0 ignored issues
show
Unused Code introduced by
The property $dropdown_field_for_orderform is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
96
97
    /**
98
     * Standard SS variable.
99
     */
100
    private static $singular_name = "Variation Attribute Type";
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $singular_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
101
    public function i18n_singular_name()
102
    {
103
        return _t("ProductAttributeType.ATTRIBUTETYPE", "Variation Attribute Type");
104
    }
105
106
    /**
107
     * Standard SS variable.
108
     */
109
    private static $plural_name = "Variation Attribute Types";
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
Unused Code introduced by
The property $plural_name is not used and could be removed.

This check marks private properties in classes that are never used. Those properties can be removed.

Loading history...
110
    public function i18n_plural_name()
111
    {
112
        return _t("ProductAttributeType.ATTRIBUTETYPES", "Variation Attribute Types");
113
    }
114
    public static function get_plural_name()
0 ignored issues
show
Documentation introduced by
The return type could not be reliably inferred; please add a @return annotation.

Our type inference engine in quite powerful, but sometimes the code does not provide enough clues to go by. In these cases we request you to add a @return annotation as described here.

Loading history...
115
    {
116
        $obj = Singleton("ProductAttributeType");
117
        return $obj->i18n_plural_name();
118
    }
119
120
    /**
121
     * finds or makes a ProductAttributeType, based on the lower case Name.
122
     *
123
     * @param String $name
124
     * @param Boolean $create
125
     *
126
     * @return ProductAttributeType
127
     */
128
    public static function find_or_make($name, $create = true)
129
    {
130
        $name = strtolower($name);
131
        $type = DataObject::get_one(
132
            'ProductAttributeType',
133
            'LOWER("Name") = \''.$name.'\'',
134
            $cacheDataObjectGetOne = false
135
        );
136
        if ($type) {
137
            return $type;
138
        }
139
        $type = ProductAttributeType::create();
140
        $type->Name = $name;
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
141
        $type->Label = $name;
0 ignored issues
show
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
142
        if ($create) {
143
            $type->write();
144
        }
145
        return $type;
146
    }
147
148
    /**
149
     * Standard SS Methodd.
150
     */
151
    public function getCMSFields()
152
    {
153
        $fields = parent::getCMSFields();
154
        $nameField = $fields->dataFieldByName("Name");
155
        $nameField->SetRightTitle(_t("ProductAttributeType.NAME_RIGHT_TITLE", "Mainly used for easy recognition in the CMS"));
156
        $valueField = $fields->dataFieldByName("Label");
157
        $valueField->SetRightTitle(_t("ProductAttributeType.VALUE_RIGHT_TITLE", "Mainly used for site users"));
158
        $variationField = $fields->dataFieldByName('Values');
159
        if($variationField) {
160
            $variationField->setConfig(new GridFieldConfigForOrderItems());
0 ignored issues
show
Bug introduced by
The method setConfig() does not exist on FormField. Did you maybe mean config()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
161
        }
162
        $fields->addFieldToTab(
163
            "Root.Main",
164
            new OptionalTreeDropdownField(
165
                "MoreInfoLinkID",
166
                _t("ProductAttributeType.MORE_INFO_LINK", "More info page"),
167
                "SiteTree"
168
            )
169
        );
170
        //TODO: make this a really fast editing interface. Table list field??
171
        //$fields->removeFieldFromTab('Root.Values','Values');
0 ignored issues
show
Unused Code Comprehensibility introduced by
89% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
172
        $fields->AddFieldToTab(
173
            "Root.Advanced",
174
            DropdownField::create(
175
                'MergeIntoID',
176
                _t('ProductAttributeType.MERGE_INTO', 'Merge into ...'),
177
                array(0 => _t('ProductAttributeType.DO_NOT_MERGE', '-- do not merge --')) +
178
                    ProductAttributeType::get()->exclude(array("ID" => $this->ID))->map()->toArray()
179
            )
180
        );
181
        $fields->AddFieldToTab("Root.Advanced", new ReadOnlyField("MergeIntoNote", "Merge Results Notes"));
182
        return $fields;
183
    }
184
185
    /**
186
     * link to edit the record
187
     * @param String | Null $action - e.g. edit
188
     * @return String
189
     */
190
    public function CMSEditLink($action = null)
191
    {
192
        return Controller::join_links(
193
            Director::baseURL(),
194
            "/admin/product-config/".$this->ClassName."/EditForm/field/".$this->ClassName."/item/".$this->ID."/",
195
            $action
196
        );
197
    }
198
199
    /**
200
     * add more values to a type
201
     * array should be an something like red, blue, orange (strings NOT objects)
202
     * @param Array
203
     */
204
    public function addValues(array $values)
205
    {
206
        $avalues = $this->convertArrayToValues($values);
0 ignored issues
show
Unused Code introduced by
$avalues 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...
207
        $this->Values()->addMany($values);
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
208
    }
209
210
    /**
211
     * takes an array of values
212
     * and finds them or creates them.
213
     *
214
     * @param Array $values
215
     * @return ArrayList
216
     */
217
    public function convertArrayToValues(array $values)
218
    {
219
        $set = new ArrayList();
220
        foreach ($values as $value) {
221
            $val = $this->Values()->find('Value', $value);
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
222
            if (!$val) {  //TODO: ignore case, if possible
223
                $val = new ProductAttributeValue();
224
                $val->Value = $value;
225
                $val->write();
226
            }
227
            $set->push($val);
228
        }
229
        return $set;
230
    }
231
232
    /**
233
     *
234
     * @param String $emptyString
0 ignored issues
show
Documentation introduced by
There is no parameter named $emptyString. Did you maybe mean $emptystring?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

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

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

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

Loading history...
Documentation introduced by
Should the type for parameter $emptystring not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
235
     * @param DataList $values
0 ignored issues
show
Documentation introduced by
Should the type for parameter $values not be DataList|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
236
     *
237
     * @return DropdownField | HiddenField
238
     */
239
    public function getDropDownField($emptystring = null, $values = null)
240
    {
241
        //to do, why do switch to "all" the options if there are no values?
242
        $values = $this->getValuesForDropdown($values);
243
        if ($values && is_array($values) && count($values)) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $values of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
244
            $fieldType = $this->Config()->get('dropdown_field_for_orderform');
245
            $field = $fieldType::create('ProductAttributes['.$this->ID.']', $this->Label, $values);
0 ignored issues
show
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
246
            if ($emptystring && count($values) > 1) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $emptystring of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
247
                $field->setEmptyString($emptystring);
248
            }
249
        } else {
250
            $field = new HiddenField('ProductAttributes['.$this->ID.']', 0);
251
        }
252
        $this->extend("updateDropDownField", $field);
253
        return $field;
254
    }
255
256
    private static $_drop_down_values = array();
257
258
    /**
259
     *
260
     * @param DataList $values
0 ignored issues
show
Documentation introduced by
Should the type for parameter $values not be DataList|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
261
     *
262
     * @return array
263
     */
264
    public function getValuesForDropdown($values = null)
265
    {
266
        if(! isset(self::$_drop_down_values[$this->ID])) {
267
            $values = ($values) ? $values : $this->Values();
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
268
            $count = $values->count();
269
            if ($count > 0) {
270
                if($count > 100) {
271
                    $values = $values->limit(1000);
272
                    self::$_drop_down_values[$this->ID] = $values->map('ID', 'Value')->toArray();
273
                } else {
274
                    self::$_drop_down_values[$this->ID] = $values->map('ID', 'ValueForDropdown')->toArray();
275
                }
276
            } else {
277
                self::$_drop_down_values[$this->ID] = array();
278
            }
279
        }
280
281
        return self::$_drop_down_values[$this->ID];
282
    }
283
284
    /**
285
     * It can be deleted if all its Values can be deleted only...
286
     *
287
     * @return Boolean
0 ignored issues
show
Documentation introduced by
Should the return type not be boolean|string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
288
     */
289
    public function canDelete($member = null)
290
    {
291
        $extended = $this->extendedCan(__FUNCTION__, $member);
292
        if ($extended !== null) {
293
            return $extended;
294
        }
295
        $values = $this->Values()->limit(10);
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
296
        foreach ($values as $value) {
297
            if (! $value->canDelete()) {
298
                return false;
299
            }
300
        }
301
        return parent::canDelete($member);
302
    }
303
304
    /**
305
     * standard SS method
306
     * Adds a name if there is no name.
307
     * Adds a label is there is no label.
308
     *
309
     */
310
    public function onBeforeWrite()
311
    {
312
        parent::onBeforeWrite();
313
        $i = 0;
314
        $className = $this->ClassName;
315
        while (!$this->Name || DataObject::get_one($className, 'Name = \''.$this->Name.'\' AND ID != \''.$this->ID.'\'', $cacheDataObjectGetOne = false)) {
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
316
            $this->Name = $this->i18n_singular_name();
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
317
            if ($i) {
318
                $this->Name .= "_".$i;
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
319
            }
320
            $i++;
321
        }
322
        if (!$this->Label) {
0 ignored issues
show
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
323
            $this->Label = $this->Name;
0 ignored issues
show
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
324
        }
325
    }
326
327
    public function onAfterWrite()
328
    {
329
        parent::onAfterWrite();
330
        if ($this->MergeIntoID) {
0 ignored issues
show
Documentation introduced by
The property MergeIntoID does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
331
            $newAttributeType = $this->MergeInto();
0 ignored issues
show
Documentation Bug introduced by
The method MergeInto does not exist on object<ProductAttributeType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
332
            $canDoMerge = true;
333
            if ($this->Values()->count() != $newAttributeType->Values()->count()) {
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
334
                $canDoMerge = false;
335
                $this->MergeIntoNote = "NON-MATCHING VALUE COUNTS";
0 ignored issues
show
Documentation introduced by
The property MergeIntoNote does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
336
            } else {
337
                $mergeMapArray_OLD = array();
338
                $mergeMapArray_NEW = array();
339
                $mergeMapArrayGO = array();
340
                foreach ($this->Values() as $value) {
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
341
                    $mergeMapArray_OLD[] = $value->ID;
342
                }
343
                foreach ($newAttributeType->Values() as $value) {
344
                    $mergeMapArray_NEW[] = $value->ID;
345
                }
346
                foreach ($mergeMapArray_OLD as $key => $id_OLD) {
347
                    $id_NEW = $mergeMapArray_NEW[$key];
348
                    $obj_OLD = ProductAttributeValue::get()->byID($id_OLD);
349
                    $obj_NEW = ProductAttributeValue::get()->byID($id_NEW);
350
                    if ($obj_OLD && $obj_NEW) {
351
                        if ($obj_OLD->Code == $obj_NEW->Code || $obj_OLD->Value == $obj_NEW->Value || 1 == 1) {
352
                            $mergeMapArrayGO[$obj_OLD->ID] = $obj_NEW->ID;
353
                        } else {
354
                            $this->MergeIntoNote = "NON-MATCHINGE VALUES: ".$obj_OLD->Code."!=".$obj_NEW->Code." AND ".$obj_OLD->Value."!=".$obj_NEW->Value;
0 ignored issues
show
Documentation introduced by
The property MergeIntoNote does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
355
                            $canDoMerge = false;
356
                        }
357
                    } else {
358
                        $this->MergeIntoNote = "MISSING OLD OR NEW OBJECT";
0 ignored issues
show
Documentation introduced by
The property MergeIntoNote does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
359
                        $canDoMerge = false;
360
                    }
361
                }
362
            }
363
            if ($canDoMerge) {
364
                foreach ($mergeMapArrayGO as $id_OLD => $id_NEW) {
0 ignored issues
show
Bug introduced by
The variable $mergeMapArrayGO does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
365
                    DB::query("
366
                        UPDATE \"ProductVariation_AttributeValues\"
367
                        SET \"ProductAttributeValueID\" = ".$id_NEW."
368
                        WHERE \"ProductAttributeValueID\" = ".$id_OLD.";
369
                    ");
370
                }
371
                DB::query("
372
                    UPDATE \"Product_VariationAttributes\"
373
                    SET \"ProductAttributeTypeID\" = ".$this->MergeIntoID."
0 ignored issues
show
Documentation introduced by
The property MergeIntoID does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
374
                    WHERE \"ProductAttributeTypeID\" = ".$this->ID.";
375
                ");
376
                $values = ProductAttributeValue::get()->filter(array("TypeID" => $this->ID));
377
                foreach ($values as $value) {
378
                    $value->delete();
379
                }
380
                $this->MergeIntoNote = "Merged successfully into ".$this->MergeInto()->Name." ...";
0 ignored issues
show
Documentation introduced by
The property MergeIntoNote does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation Bug introduced by
The method MergeInto does not exist on object<ProductAttributeType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
381
                $this->Name = "TO BE DELETED ".$this->Name;
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
382
                $this->Label = "TO BE DELETED ".$this->Label;
0 ignored issues
show
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
383
            }
384
            $this->MergeIntoID = 0;
0 ignored issues
show
Documentation introduced by
The property MergeIntoID does not exist on object<ProductAttributeType>. Since you implemented __set, maybe consider adding a @property annotation.

Since your code implements the magic setter _set, this function will be called for any write access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

Since the property has write access only, you can use the @property-write annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
385
            $this->write();
386
        }
387
    }
388
389
    /**
390
     * Delete all the values
391
     * that are related to this type.
392
     */
393
    public function onBeforeDelete()
394
    {
395
        parent::onBeforeDelete();
396
        $values = $this->Values();
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
397
        foreach ($values as $value) {
398
            if ($value->canDelete()) {
399
                $value->delete();
400
                $value->destroy();
401
            }
402
        }
403
        DB::query("DELETE FROM \"Product_VariationAttributes\" WHERE \"ProductAttributeTypeID\" = ".$this->ID);
404
    }
405
406
    public function cleanup()
407
    {
408
        $sql = "
409
            Select \"ProductAttributeTypeID\"
410
            FROM \"Product_VariationAttributes\"
411
            WHERE \"ProductID\" = ".$this->owner->ID;
0 ignored issues
show
Documentation introduced by
The property owner does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
412
        $data = DB::query($sql);
413
        $array = $data->keyedColumn();
414
        if (is_array($array) && count($array)) {
415
            foreach ($array as $key => $productAttributeTypeID) {
416
                //attribute type does not exist.
417
                if (! ProductAttributeType::get()->byID($productAttributeTypeID)) {
418
                    //delete non-existing combinations of Product_VariationAttributes (where the attribute does not exist)
419
                    //DB::query("DELETE FROM \"Product_VariationAttributes\" WHERE \"ProductAttributeTypeID\" = $productAttributeTypeID");
0 ignored issues
show
Unused Code Comprehensibility introduced by
64% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
420
                    //non-existing product attribute values.
421
                    $productAttributeValues = ProductAttributeValue::get()->filter(array("TypeID" => $productAttributeTypeID));
422
                    if ($productAttributeValues->count()) {
423
                        foreach ($productAttributeValues as $productAttributeValue) {
424
                            $productAttributeValue->delete();
425
                        }
426
                    }
427
                }
428
            }
429
        }
430
    }
431
432
    /**
433
     * useful for GridField
434
     * @return String
435
     */
436
    public function getFullName()
437
    {
438
        $fieldLabels = $this->FieldLabels();
0 ignored issues
show
Unused Code introduced by
$fieldLabels 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...
439
        return
440
            $this->Name.', '.
0 ignored issues
show
Documentation introduced by
The property Name does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
441
            $this->Label.
0 ignored issues
show
Documentation introduced by
The property Label does not exist on object<ProductAttributeType>. Since you implemented __get, maybe consider adding a @property annotation.

Since your code implements the magic getter _get, this function will be called for any read access on an undefined variable. You can add the @property annotation to your class or interface to document the existence of this variable.

<?php

/**
 * @property int $x
 * @property int $y
 * @property string $text
 */
class MyLabel
{
    private $properties;

    private $allowedProperties = array('x', 'y', 'text');

    public function __get($name)
    {
        if (isset($properties[$name]) && in_array($name, $this->allowedProperties)) {
            return $properties[$name];
        } else {
            return null;
        }
    }

    public function __set($name, $value)
    {
        if (in_array($name, $this->allowedProperties)) {
            $properties[$name] = $value;
        } else {
            throw new \LogicException("Property $name is not defined.");
        }
    }

}

If the property has read access only, you can use the @property-read annotation instead.

Of course, you may also just have mistyped another name, in which case you should fix the error.

See also the PhpDoc documentation for @property.

Loading history...
442
            ' ('.
443
                $this->Values()->count().' '.Injector::inst()->get('ProductAttributeValue')->i18n_plural_name().', '.
0 ignored issues
show
Bug introduced by
The method Values() does not exist on ProductAttributeType. Did you maybe mean addValues()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
444
                $this->Products()->count().' '.Injector::inst()->get('Product')->i18n_plural_name().
0 ignored issues
show
Documentation Bug introduced by
The method Products does not exist on object<ProductAttributeType>? Since you implemented __call, maybe consider adding a @method annotation.

If you implement __call and you know which methods are available, you can improve IDE auto-completion and static analysis by adding a @method annotation to the class.

This is often the case, when __call is implemented by a parent class and only the child class knows which methods exist:

class ParentClass {
    private $data = array();

    public function __call($method, array $args) {
        if (0 === strpos($method, 'get')) {
            return $this->data[strtolower(substr($method, 3))];
        }

        throw new \LogicException(sprintf('Unsupported method: %s', $method));
    }
}

/**
 * If this class knows which fields exist, you can specify the methods here:
 *
 * @method string getName()
 */
class SomeClass extends ParentClass { }
Loading history...
445
            ')';
446
    }
447
}
448