Completed
Push — master ( 3bb114...d7178b )
by Nicolaas
01:40
created

BuildController::ClassNameForObject()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 0
1
<?php
2
3
4
namespace SunnySideUp\BuildDataObject;
5
6
7
8
abstract class BuildController extends \Controller {
9
10
11
    private static $form_data_session_variable = 'SunnySideUp\BuildDataObject\DataObjectBuildController';
0 ignored issues
show
Unused Code introduced by
The property $form_data_session_variable 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...
12
13
    private static $url_segment = 'build';
0 ignored issues
show
Unused Code introduced by
The property $url_segment 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
    private static $allowed_actions = [
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 $allowed_actions 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...
16
        'primaryformstart' => true,
17
        'PrimaryForm' => true,
18
        'doprimaryform' => true,
19
        'secondaryformstart' => true,
20
        'SecondaryForm' => true,
21
        'dosecondaryform' => true,
22
        'results' => true,
23
        'startover' => true,
24
        'debug' => true
25
    ];
26
27
    protected $myBaseClass = 'DataObject';
28
29
    protected $apiProvider = 'SunnySideUp\BuildDataObject\API';
30
31
    abstract protected function primaryThingsToBuild();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
32
33
    abstract protected function secondaryThingsToBuild();
0 ignored issues
show
Documentation introduced by
For interfaces and abstract methods it is generally a good practice to add a @return annotation even if it is just @return void or @return null, so that implementors know what to do in the overridden method.

For interface and abstract methods, it is impossible to infer the return type from the immediate code. In these cases, it is generally advisible to explicitly annotate these methods with a @return doc comment to communicate to implementors of these methods what they are expected to return.

Loading history...
34
35
    public function Link($action = null)
36
    {
37
        if($action) {
38
            $action .= '/';
39
        }
40
        return
41
            '/'.$this->Config()->get('url_segment').
42
            '/'.strtolower($this->myBaseClass).
43
            '/'.$action;
44
    }
45
46
    public function Title()
47
    {
48
        return 'Build a '.$this->myBaseClass.' - Step '.$this->step.' of 2';
49
    }
50
51
52
    public function jQueryLink()
53
    {
54
        return \Director::absoluteURL('/framework/thirdparty/jquery/jquery.js');
55
    }
56
57
    public function startover()
58
    {
59
        $this->saveData('_PrimaryForm', null);
60
        $this->saveData('_SecondaryForm', null);
61
        return $this->redirect($this->link('primaryformstart'));
62
    }
63
64
    /**
65
     *
66
     * @var Form
67
     */
68
    protected $step = 1;
69
70
    /**
71
     *
72
     * @var Form
73
     */
74
    protected $form = null;
75
76
    /**
77
     *
78
     * @var Form
79
     */
80
    protected $prevLink = null;
81
82
    /**
83
     *
84
     * @var ArrayList
85
     */
86
    protected $finalData = null;
87
88
    function index()
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...
89
    {
90
        return $this->redirect($this->Link('primaryformstart'));
91
    }
92
93 View Code Duplication
    function primaryformstart()
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...
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...
94
    {
95
        $this->PrimaryForm();
96
        $this->prevLink = $this->Link('startover');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->Link('startover') of type string is incompatible with the declared type object<SunnySideUp\BuildDataObject\Form> of property $prevLink.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
97
        \SSViewer::set_source_file_comments(false);
0 ignored issues
show
Deprecated Code introduced by
The method SSViewer::set_source_file_comments() has been deprecated with message: 4.0 Use the "SSViewer.source_file_comments" config setting instead

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

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

Loading history...
98
99
        return $this->renderWith('BuildControllerForm');
100
    }
101
102
    function PrimaryForm()
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...
103
    {
104
        $this->form = $this->createForm('PrimaryForm', 'Build Model');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createForm('PrimaryForm', 'Build Model') of type object<Form> is incompatible with the declared type object<SunnySideUp\BuildDataObject\Form> of property $form.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
105
106
        return $this->form;
107
    }
108
109
    function doprimaryform($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

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

Loading history...
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...
110
    {
111
        $this->saveData('_PrimaryForm', $data);
112
113
        return $this->redirect($this->Link('secondaryformstart'));
114
    }
115
116
117 View Code Duplication
    function secondaryformstart()
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...
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...
118
    {
119
        $this->step = 2;
0 ignored issues
show
Documentation Bug introduced by
It seems like 2 of type integer is incompatible with the declared type object<SunnySideUp\BuildDataObject\Form> of property $step.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
120
        $this->SecondaryForm();
121
        $this->prevLink = $this->Link('primaryformstart');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->Link('primaryformstart') of type string is incompatible with the declared type object<SunnySideUp\BuildDataObject\Form> of property $prevLink.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
122
        \SSViewer::set_source_file_comments(false);
0 ignored issues
show
Deprecated Code introduced by
The method SSViewer::set_source_file_comments() has been deprecated with message: 4.0 Use the "SSViewer.source_file_comments" config setting instead

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

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

Loading history...
123
124
        return $this->renderWith('BuildControllerForm');
125
    }
126
127
    function SecondaryForm()
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...
128
    {
129
        $this->form = $this->createForm('SecondaryForm', 'Download Example Class');
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->createForm('Secon...ownload Example Class') of type object<Form> is incompatible with the declared type object<SunnySideUp\BuildDataObject\Form> of property $form.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
130
131
        return $this->form;
132
    }
133
134
135
    function dosecondaryform($data, $form)
0 ignored issues
show
Unused Code introduced by
The parameter $form is not used and could be removed.

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

Loading history...
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...
136
    {
137
        $this->saveData('_SecondaryForm', $data);
138
139
        return $this->redirect($this->Link('results'));
140
    }
141
142
    function results()
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...
143
    {
144
        $this->finalData = $this->processedFormData($this->retrieveData());
145
        \SSViewer::set_source_file_comments(false);
0 ignored issues
show
Deprecated Code introduced by
The method SSViewer::set_source_file_comments() has been deprecated with message: 4.0 Use the "SSViewer.source_file_comments" config setting instead

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

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

Loading history...
146
147
        return \SS_HTTPRequest::send_file(
148
            $this->renderWith($this->resultsTemplateForBuilder()),
149
            $this->finalData->Name.'.php'
150
        );
151
    }
152
153
    function debug()
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...
154
    {
155
        $this->finalData = $this->processedFormData($this->retrieveData());
156
        print_r($this->CanMethodBuilder('canEdit'));
0 ignored issues
show
Bug introduced by
The method CanMethodBuilder() does not exist on SunnySideUp\BuildDataObject\BuildController. Did you maybe mean MyCanMethodBuilder()?

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...
157
        print_r($this->finalData);
158
        die('-----------------------------');
0 ignored issues
show
Coding Style Compatibility introduced by
The method debug() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
159
    }
160
161
    function Form()
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...
162
    {
163
        return $this->form;
164
    }
165
166
    function FinalData()
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...
167
    {
168
        return $this->finalData;
169
    }
170
171
    function PrevLink()
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...
172
    {
173
        return $this->prevLink;
174
    }
175
176
    protected function ClassNameForObject()
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...
177
    {
178
        if(isset($this->finalData->Name)) {
179
            return $this->finalData->Name;
180
        } else {
181
            return 'self::$class';
182
        }
183
    }
184
185
    function MyCanMethodBuilder($type, $value) {
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed.

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

Loading history...
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...
186
        if($value === 'parent') {
187
            return null;
188
        } elseif($value === 'one') {
189
            $str = 'DataObject::get_one($this->class) ? false : true;';
190
        } elseif($value === 'true') {
191
            $str = 'true;';
192
        } elseif($value === 'false') {
193
            $str = 'false;';
194
        } else {
195
            $str = 'Permission::check(\''.$value.'\', \'any\', $member);';
196
        }
197
198
        return \DBField::create_field('Varchar', $str);
199
    }
200
201
202
    protected function createForm($formName, $actionTitle)
203
    {
204
        if($formName === 'PrimaryForm') {
205
            $isPrimary = true;
206
            $isSecond = false;
0 ignored issues
show
Unused Code introduced by
$isSecond 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
        } elseif($formName === 'SecondaryForm') {
208
            $isPrimary = false;
209
            $isSecond = true;
0 ignored issues
show
Unused Code introduced by
$isSecond 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...
210
        } else {
211
            user_error('Set right form type: '.$formName.' is not valid');
212
        }
213
214
        $finalFields = \FieldList::create();
215
216
        if($isPrimary) {
0 ignored issues
show
Bug introduced by
The variable $isPrimary 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...
217
            $toBuild = $this->primaryThingsToBuild();
218
            $finalFields->push(\HeaderField::create('Name your '.$this->myBaseClass));
219
            $finalFields->push(\TextField::create('Name', ''));
220
            $finalFields->push(\HeaderField::create('Extends'));
221
            $possibleExtensions = $this->myAPI()->PossibleRelationsWithBaseClass($this->myBaseClass);
222
            asort($possibleExtensions);
223
            $finalFields->push(
224
                \DropdownField::create(
225
                    'Extends',
226
                    '',
227
                    $possibleExtensions
228
                )
229
            );
230
            $additionalFields = $this->additionalPrimaryFields();
231
            foreach($additionalFields as $additionalField) {
232
                $finalFields->push($additionalField);
233
            }
234
        } else {
235
            $toBuild = $this->secondaryThingsToBuild();
236
        }
237
        $formFields = [];
238
        $formFieldsWithMultiple = [];
239
240
        $count = 0;
241
        //build fields ...
242
        foreach($toBuild as $item) {
243
            $name = $item[0];
244
            $sourceMethod1 = $item[1];
245
            $sourceMethod2 = $item[2];
246
            $isMultiple = $item[3];
247
248
249
            //work out style
250
            $hasKeyAndValue = false;
251
            if($sourceMethod1 && $sourceMethod2) {
252
                $hasKeyAndValue = true;
253
            }
254
            $formFields[$count] = [];
255
            if($isMultiple) {
256
                $max = 12;
257
            } else {
258
                $max = 1;
259
            }
260
            $formFields[$count][0] = [
261
                $name.'_HEADER',
262
                'HeaderField',
263
                $name
264
            ];
265
266
267
            //work out sources
268
            if($sourceMethod1 && $this->myAPI()->hasMethod($sourceMethod1)) {
269
                $source1 = $this->myAPI()->$sourceMethod1();
270
            } else {
271
                $source1 = null;
272
            }
273
            if($sourceMethod2 && $this->myAPI()->hasMethod($sourceMethod2)) {
274
                $source2 = $this->myAPI()->$sourceMethod2();
275
            } elseif($sourceMethod2) {
276
                $source2 = null;
277
            } else {
278
                $source2 = 'ignore';
279
            }
280
281
            //work out field names
282
283
            for($i = 1; $i <= $max; $i++) {
284
                if($hasKeyAndValue) {
285
                    if($isMultiple) {
286
                        $nameKey = $name.'__KEY__'.$i;
287
                        $nameValue = $name.'__VALUE__'.$i;
288
                        $formFieldsWithMultiple[$nameKey] = $nameKey;
289
                    } else {
290
                        $nameKey = $name.'__KEY__';
291
                        $nameValue = $name.'__VALUE__';
292
                    }
293
                } else {
294
                    if($isMultiple) {
295
                        $nameKey = $name.$i;
296
                        $nameValue = '';
297
                        $formFieldsWithMultiple[$nameKey] = $nameKey;
298
                    } else {
299
                        $nameKey = $name;
300
                        $nameValue = '';
301
                    }
302
                }
303
                if($hasKeyAndValue) {
304
                    //key field
305 View Code Duplication
                    if($source1) {
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...
306
                        $formFields[$count][$i]['KEY'] = [
307
                            $nameKey,
308
                            'DropdownField',
309
                            $source1
310
                        ];
311
                    } else {
312
                        $formFields[$count][$i]['KEY'] = [
313
                            $nameKey,
314
                            'TextField'
315
                        ];
316
                    }
317
318
                    //value field
319 View Code Duplication
                    if($source2) {
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...
320
                        $formFields[$count][$i]['VALUE'] = [
321
                            $nameValue,
322
                            'DropdownField',
323
                            $source2
324
                        ];
325
                    } else {
326
                        $formFields[$count][$i]['VALUE'] = [
327
                            $nameValue,
328
                            'TextField'
329
                        ];
330
                    }
331
                } else {
332
                    //keys only!
333
                    if($source1) {
334
                        $formFields[$count][$i] = [
335
                            $nameKey,
336
                            'DropdownField',
337
                            $source1
338
                        ];
339
                    } else {
340
                        $formFields[$count][$i] = [
341
                            $nameKey,
342
                            'TextField'
343
                        ];
344
                    }
345
                }
346
            }
347
            if($i > 2) {
348
                $formFields[$count][$i + 1] = [
349
                    $name.'_ADD_'.$i,
350
                    'LiteralField',
351
                    '
352
                    <div class="CompositeField add-and-remove">
353
                        <a href="#" class="add first-add"><i class="material-icons">add_circle_outline</i></a>
354
                        <a href="#" class="remove"><i class="material-icons">remove_circle_outline</i></a>
355
                    </div>
356
                    '
357
                ];
358
            }
359
            $count++;
360
        }
361
        //create fields ...
362
        $count = 0;
363
        foreach($formFields as $outerCount => $subFieldList) {
364
            $count++;
365
            $compositeField = \CompositeField::create();
366
            $compositeField->addExtraClass('OuterComposite pos'.$count);
367
            $innerCount = 0;
368
            foreach($subFieldList as $innerCount => $fieldDetails) {
369
                $innerCount++;
370
                if(isset($fieldDetails['KEY']) && isset($fieldDetails['VALUE'])) {
371
                    $subCompositeField = \CompositeField::create();
372
                    $subCompositeField->addExtraClass('InnerComposite pos'.$innerCount);
373
                    foreach($fieldDetails as $fieldDetailsInner) {
374
                        $fieldName = $fieldDetailsInner[0];
375
                        $fieldType = $fieldDetailsInner[1];
376
                        $additionalClasses = [];
377
                        if(strpos($fieldName, '__KEY__')) {
378
                            $additionalClasses[] = 'mykey';
379
                        }
380
                        if(strpos($fieldName, '__VALUE__')) {
381
                            $additionalClasses[] = 'myvalue';
382
                        }
383
                        if(isset($fieldDetailsInner[2])) {
384
                            $source = $fieldDetailsInner[2];
385
                            asort($source);
386
                            $source = $this->prependNullOption( $source );
387
                            $tempField = $fieldType::create($fieldName, '', $source);
388
                        } else {
389
                            $tempField = $fieldType::create($fieldName, '');
390
                        }
391
                        if(count($additionalClasses)) {
392
                            $classes = implode(' ', $additionalClasses);
393
                            $tempField->addExtraClass($classes);
394
                        }
395
                        $subCompositeField->push($tempField);
396
                    }
397
                    $compositeField->push($subCompositeField);
398
                } else {
399
                    $fieldName = $fieldDetails[0];
400
                    if(isset($formFieldsWithMultiple[$fieldName])) {
401
                        $subCompositeField = \CompositeField::create();
402
                        $subCompositeField->addExtraClass('InnerComposite pos'.$innerCount);
403
                    } else {
404
                        $subCompositeField = null;
405
                    }
406
                    $fieldType = $fieldDetails[1];
407
                    if($fieldType === 'DropdownField') {
408
                        $source = $fieldDetails[2];
409
                        asort($source);
410
                        $source = $this->prependNullOption($source);
411
                        $myTempfield = $fieldType::create($fieldName, '', $source);
412
                    } elseif($fieldType === 'HeaderField') {
413
                        $title = str_replace('_', ' ', $fieldDetails[2]);
414
                        $myTempfield = $fieldType::create($fieldName, $title);
415
                    } elseif($fieldType === 'LiteralField') {
416
                        $title = $fieldDetails[2];
417
                        $myTempfield = $fieldType::create($fieldName, $title);
418
                    } else {
419
                        $myTempfield = $fieldType::create($fieldName, '');
420
                    }
421
                    if($subCompositeField) {
422
                        $subCompositeField->push($myTempfield);
423
                        $compositeField->push($subCompositeField);
424
                    } else {
425
                        $compositeField->push($myTempfield);
426
                    }
427
                }
428
            }
429
            $finalFields->push($compositeField);
430
        }
431
        $actions = \FieldList::create(
432
            [\FormAction::create('do'.strtolower($formName), $actionTitle)]
433
        );
434
435
        $form = \Form::create($this, $formName, $finalFields, $actions);
436
        $form->setFormAction($this->Link($formName));
437
        $form->loadDataFrom($this->retrieveData());
438
439
        return $form;
440
    }
441
442
    /**
443
     * returns an array of fields
444
     * @return array
445
     */
446
    protected function additionalPrimaryFields()
447
    {
448
        return [];
449
    }
450
451
    protected function saveData($name, $data)
452
    {
453
        $var = $this->Config()->get('form_data_session_variable');
454
        \Session::set($var.$name, $data);
455
        \Session::save();
456
    }
457
458
    private $_data = null;
459
460
    protected function retrieveData()
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...
461
    {
462
        if(! $this->_data) {
463
            $var = $this->Config()->get('form_data_session_variable');
464
            $retrieveDataPrimary = \Session::get($var.'_PrimaryForm');
465
            if ($retrieveDataPrimary && (is_array($retrieveDataPrimary) || is_object($retrieveDataPrimary))) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
466
                //do nothing
467
            } else {
468
                $retrieveDataPrimary = [];
469
            }
470
            $retrieveDataSecondary = \Session::get($var.'_SecondaryForm');
471
            if ($retrieveDataSecondary && (is_array($retrieveDataSecondary) || is_object($retrieveDataSecondary))) {
0 ignored issues
show
Unused Code introduced by
This if statement is empty and can be removed.

This check looks for the bodies of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These if bodies can be removed. If you have an empty if but statements in the else branch, consider inverting the condition.

if (rand(1, 6) > 3) {
//print "Check failed";
} else {
    print "Check succeeded";
}

could be turned into

if (rand(1, 6) <= 3) {
    print "Check succeeded";
}

This is much more concise to read.

Loading history...
472
                //do nothing
473
            } else {
474
                $retrieveDataSecondary = [];
475
            }
476
            $this->_data = $retrieveDataPrimary + $retrieveDataSecondary;
477
        }
478
479
        return $this->_data;
480
    }
481
482
    private $_processed_data = null;
483
484
    protected function processedFormData($data = null) {
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...
485
        if(! $this->_processed_data) {
486
            if(! $data) {
487
                $data = $this->retrieveData();
488
            }
489
            $array = [];
490
            foreach($data as $key => $value) {
491
                if($key && $value) {
492
                    if(
493
                        strpos($key, '__KEY__') ||
494
                        strpos($key, '__VALUE__')
495
                    ) {
496
                        $parts = explode('__', $key);
497
                        if(!isset($array[$parts[0]])) {
498
                            $array[$parts[0]] = [];
499
                        }
500
                        if(! isset($array[$parts[0]][$parts[2]])) {
501
                            $array[$parts[0]][$parts[2]] = [];
502
                        }
503
                        $array[$parts[0]][$parts[2]][$parts[1]] = $value;
504
                    } elseif(substr($key, 0, 3) === 'can') {
505
                        $array[$key] = $this->MyCanMethodBuilder($key, $value);
506
                    } else {
507
                        $array[$key] = $value;
508
                    }
509
                }
510
            }
511
            foreach($array as $field => $values) {
512
                $alInner = \ArrayList::create();
513
                if(is_array($values)) {
514
                    foreach($values as $key => $valuePairs) {
515
                        if(isset($valuePairs['KEY']) && isset($valuePairs['VALUE'])) {
516
                            if($valuePairs['VALUE'] == 'true') {
517
                                $valuePairArray = [
518
                                    'Key' => $valuePairs['KEY'],
519
                                    'UnquotedValue' => $valuePairs['VALUE'],
520
                                ];
521
                            } else {
522
                                $valuePairArray = [
523
                                    'Key' => $valuePairs['KEY'],
524
                                    'Value' => $valuePairs['VALUE'],
525
                                ];
526
                            }
527
                            $alInner->push(\ArrayData::create($valuePairArray));
528
                        }
529
                    }
530
                    $array[$field] = $alInner;
531
                } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
532
                    //do nothing
533
                }
534
            }
535
            $this->_processed_data = \ArrayData::create($array);
536
        }
537
538
        return $this->_processed_data;
539
    }
540
541
542
    protected function resultsTemplateForBuilder()
543
    {
544
        return str_replace(__NAMESPACE__ .'\\', '', $this->class).'Results';
545
    }
546
547
548
    protected function prependNullOption($source)
549
    {
550
        $source = ['' => '--- Please Select ---'] + $source;
551
552
        return $source;
553
    }
554
555
556
    protected function myAPI()
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...
557
    {
558
        $class = $this->apiProvider;
559
560
        return $class::inst($this->myBaseClass, $this->processedFormData());
561
    }
562
563
564
}
565