Completed
Push — master ( 34e737...1a9402 )
by Nicolaas
01:42
created

ImagesWithStyleSelection::validate()   C

Complexity

Conditions 11
Paths 2

Size

Total Lines 45
Code Lines 32

Duplication

Lines 45
Ratio 100 %

Importance

Changes 0
Metric Value
dl 45
loc 45
c 0
b 0
f 0
rs 5.2653
cc 11
eloc 32
nc 2
nop 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
4
5
class ImagesWithStyleSelection extends DataObject
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...
6
{
7
8
9
    #######################
10
    ### Names Section
11
    #######################
12
13
    private static $singular_name = 'Selection of Images';
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...
14
15
    function i18n_singular_name()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
16
    {
17
        return _t('ImagesWithStyleSelection.SINGULAR_NAME', 'Selection of Images');
18
    }
19
20
    private static $plural_name = 'Selections of Images';
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...
21
22
    function i18n_plural_name()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
23
    {
24
        return _t('ImagesWithStyleSelection.PLURAL_NAME', 'Selections of Images');
25
    }
26
27
28
    #######################
29
    ### Model Section
30
    #######################
31
32
    private static $db = [
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...
33
        'Title' => 'Varchar',
34
        'Description' => 'Text'
35
    ];
36
37
    private static $many_many = [
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 $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...
38
        'StyledImages' => 'ImageWithStyle'
39
    ];
40
41
    private static $many_many_extraFields = [
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 $many_many_extraFields 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...
42
        'StyledImages' => [
43
            'SortOrder' => 'Int',
44
        ]
45
    ];
46
47
48
49
    #######################
50
    ### Further DB Field Details
51
    #######################
52
53
    private static $indexes = [
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...
54
        'Created' => true,
55
        'Title' => 'unique("Title")'
56
    ];
57
58
    private static $defaults = [
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 $defaults 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...
59
        'Title' => ''
60
    ];
61
62
    private static $default_sort = [
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...
63
        'Created' => 'DESC'
64
    ];
65
66
    private static $required_fields = [
0 ignored issues
show
Unused Code introduced by
The property $required_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...
67
        'Title'
68
    ];
69
70
    private static $searchable_fields = [
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...
71
        'Title' => 'PartialMatchFilter'
72
    ];
73
74
75
    #######################
76
    ### Field Names and Presentation Section
77
    #######################
78
79
    private static $field_labels = [
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 $field_labels 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
        'StyledImages' => 'Images to be included'
81
    ];
82
83
    private static $field_labels_right = [
0 ignored issues
show
Unused Code introduced by
The property $field_labels_right 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...
84
        'StyledImages' => 'Select as many as you like and sort them in the right order'
85
    ];
86
87
    private static $summary_fields = [
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...
88
        'Title' => 'Name',
89
        'StyledImages.Count' => 'Number of Images'
90
    ];
91
92
93
    #######################
94
    ### Casting Section
95
    #######################
96
97
98
    #######################
99
    ### can Section
100
    #######################
101
102
103
104
    #######################
105
    ### write Section
106
    #######################
107
108
109
110
111 View Code Duplication
    public function validate()
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...
112
    {
113
        $result = parent::validate();
114
        $fieldLabels = $this->FieldLabels();
115
        $indexes = $this->Config()->get('indexes');
116
        $requiredFields = $this->Config()->get('required_fields');
117
        if(is_array($requiredFields)) {
118
            foreach($requiredFields as $field) {
119
                $value = $this->$field;
120
                if(! $value) {
121
                    $fieldWithoutID = $field;
122
                    if(substr($fieldWithoutID, -2) === 'ID') {
123
                        $fieldWithoutID = substr($fieldWithoutID, 0, -2);
124
                    }
125
                    $myName = isset($fieldLabels[$fieldWithoutID]) ? $fieldLabels[$fieldWithoutID] : $fieldWithoutID;
126
                    $result->error(
127
                        _t(
128
                            'ImagesWithStyleSelection.'.$field.'_REQUIRED',
129
                            $myName.' is required'
130
                        ),
131
                        'REQUIRED_ImagesWithStyleSelection_'.$field
132
                    );
133
                }
134
                if (isset($indexes[$field]) && isset($indexes[$field]['type']) && $indexes[$field]['type'] === 'unique') {
135
                    $id = (empty($this->ID) ? 0 : $this->ID);
136
                    $count = ImagesWithStyleSelection::get()
137
                        ->filter(array($field => $value))
138
                        ->exclude(array('ID' => $id))
139
                        ->count();
140
                    if($count > 0) {
141
                        $myName = $fieldLabels['$field'];
142
                        $result->error(
143
                            _t(
144
                                'ImagesWithStyleSelection.'.$field.'_UNIQUE',
145
                                $myName.' needs to be unique'
146
                            ),
147
                            'UNIQUE_ImagesWithStyleSelection_'.$field
148
                        );
149
                    }
150
                }
151
            }
152
        }
153
154
        return $result;
155
    }
156
157
    public function onBeforeWrite()
158
    {
159
        parent::onBeforeWrite();
160
        //...
161
    }
162
163
    public function onAfterWrite()
164
    {
165
        parent::onAfterWrite();
166
        //...
167
    }
168
169
    public function requireDefaultRecords()
170
    {
171
        parent::requireDefaultRecords();
172
        //...
173
    }
174
175
176
    #######################
177
    ### Import / Export Section
178
    #######################
179
180
    public function getExportFields()
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...
181
    {
182
        //..
183
        return parent::getExportFields();
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class DataObject as the method getExportFields() does only exist in the following sub-classes of DataObject: ImageStyle, ImageWithStyle, ImagesWithStyleSelection. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
184
    }
185
186
187
188
    #######################
189
    ### CMS Edit Section
190
    #######################
191
192
193
    public function CMSEditLink()
194
    {
195
        $controller = singleton("ImageWithStyleAdmin");
196
197
        return $controller->Link().$this->ClassName."/EditForm/field/".$this->ClassName."/item/".$this->ID."/edit";
198
    }
199
200
    public function CMSAddLink()
201
    {
202
        $controller = singleton("ImageWithStyleAdmin");
203
204
        return $controller->Link().$this->ClassName."/EditForm/field/".$this->ClassName."/item/new";
205
    }
206
207
208
    public function getCMSFields()
209
    {
210
        $fields = parent::getCMSFields();
211
212
        //do first??
213
        $rightFieldDescriptions = $this->Config()->get('field_labels_right');
214 View Code Duplication
        foreach($rightFieldDescriptions as $field => $desc) {
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...
215
           $formField = $fields->DataFieldByName($field);
216
           if(! $formField) {
217
            $formField = $fields->DataFieldByName($field.'ID');
218
           }
219
           if($formField) {
220
               $formField->setDescription($desc);
221
           }
222
        }
223
        //...
224
        if($this->exists()) {
225
            $config = GridFieldConfig_RelationEditor::create();
226
            $config->addComponent(new GridFieldSortableRows('SortOrder'));
227
            $fields->removeByName('StyledImages');
228
            $fields->addFieldToTab(
229
                    'Root.Images',
230
                    GridField::create(
231
                        'StyledImages',
232
                        'Images',
233
                        $this->StyledImages(),
0 ignored issues
show
Documentation Bug introduced by
The method StyledImages does not exist on object<ImagesWithStyleSelection>? 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...
234
                        $config
235
                    )
236
                );
237
        }
238
        return $fields;
239
    }
240
241
242
}
243