This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * This class reviews all of the static configurations in e-commerce for review |
||
5 | * (a) which configs are set, but not required |
||
6 | * (b) which configs are required, but not set |
||
7 | * (c) review of set configs. |
||
8 | * |
||
9 | * @TODO: compare to default |
||
10 | * |
||
11 | * shows you the link to remove the current cart |
||
12 | * |
||
13 | * @authors: Nicolaas [at] Sunny Side Up .co.nz |
||
14 | * @package: ecommerce |
||
15 | * @sub-package: tasks |
||
16 | * @inspiration: Silverstripe Ltd, Jeremy |
||
17 | **/ |
||
18 | class EcommerceTaskCheckConfiguration extends BuildTask |
||
19 | { |
||
20 | /** |
||
21 | * Default Location for Configuration File. |
||
22 | * |
||
23 | * @var string |
||
24 | */ |
||
25 | protected $defaultLocation = 'ecommerce/_config/ecommerce.yml'; |
||
26 | |||
27 | /** |
||
28 | * Standard (required) SS variable for BuildTasks. |
||
29 | * |
||
30 | * @var string |
||
31 | */ |
||
32 | protected $title = 'Check Configuration'; |
||
33 | |||
34 | /** |
||
35 | * Standard (required) SS variable for BuildTasks. |
||
36 | * |
||
37 | * @var string |
||
38 | */ |
||
39 | protected $description = 'Runs through all static configuration for review.'; |
||
40 | |||
41 | /** |
||
42 | * Array of definitions - set like this: |
||
43 | * ClassName |
||
44 | * VariableName: Description. |
||
45 | * |
||
46 | * @var array |
||
47 | */ |
||
48 | protected $definitions = array(); |
||
49 | |||
50 | /** |
||
51 | * Array of definitions Header - set like this: |
||
52 | * HEADER TITLE |
||
53 | * ClassName. |
||
54 | * |
||
55 | * @var array |
||
56 | */ |
||
57 | protected $definitionsHeaders = array(); |
||
58 | |||
59 | /** |
||
60 | * Array of defaults - set like this: |
||
61 | * ClassName |
||
62 | * VariableName: Default Variable Value. |
||
63 | * |
||
64 | * @var array |
||
65 | */ |
||
66 | protected $defaults = array(); |
||
67 | |||
68 | /** |
||
69 | * Array of configs - set like this: |
||
70 | * ClassName |
||
71 | * VariableName: VariableValue. |
||
72 | * |
||
73 | * @var array |
||
74 | */ |
||
75 | protected $configs = array(); |
||
76 | |||
77 | /** |
||
78 | * which values are derived from DB |
||
79 | * ClassName |
||
80 | * VariableName: TRUE | FALSE. |
||
81 | * |
||
82 | * @var array |
||
83 | */ |
||
84 | protected $databaseValues = array(); |
||
85 | |||
86 | /** |
||
87 | * set in default yml, but not customised. |
||
88 | * ClassName |
||
89 | * VariableName: TRUE | FALSE. |
||
90 | * |
||
91 | * @var array |
||
92 | */ |
||
93 | protected $customisedValues = array(); |
||
94 | |||
95 | /** |
||
96 | * Other configs |
||
97 | * ClassName |
||
98 | * VariableName: TRUE | FLASE. |
||
99 | * |
||
100 | * @var array |
||
101 | */ |
||
102 | protected $otherConfigs = array(); |
||
103 | |||
104 | /** |
||
105 | * Array of classes (partially) missing in configs. |
||
106 | * VariableName: VariableName. |
||
107 | * |
||
108 | * @var array |
||
109 | */ |
||
110 | protected $missingClasses = array(); |
||
111 | |||
112 | /** |
||
113 | * Standard (required) SS method, runs buildtask. |
||
114 | */ |
||
115 | public function run($request) |
||
116 | { |
||
117 | $definitionsObject = EcommerceConfigDefinitions::create(); |
||
118 | $this->definitions = $definitionsObject->Definitions(); |
||
119 | $this->definitionsHeaders = $definitionsObject->GroupDefinitions(); |
||
120 | $configsObject = EcommerceConfig::create(); |
||
121 | $this->configs = $configsObject->getCompleteDataSet(); |
||
122 | $this->defaults = $this->getDefaultValues(); |
||
123 | if ($this->definitions) { |
||
0 ignored issues
–
show
|
|||
124 | if ($this->configs) { |
||
0 ignored issues
–
show
The expression
$this->configs 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 ![]() |
|||
125 | if ($this->defaults) { |
||
0 ignored issues
–
show
The expression
$this->defaults 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 ![]() |
|||
126 | $this->checkFiles(); |
||
127 | $this->configsNotSet(); |
||
128 | $this->classesThatDoNotExist(); |
||
129 | $this->definitionsNotSet(); |
||
130 | $this->addEcommerceDBConfigToConfigs(); |
||
131 | $this->addOtherValuesToConfigs(); |
||
132 | $this->addPages(); |
||
133 | $this->orderSteps(); |
||
134 | $this->checkoutAndModifierDetails(); |
||
135 | $this->getAjaxDefinitions(); |
||
136 | $this->definedConfigs(); |
||
137 | $this->checkGEOIP(); |
||
138 | } else { |
||
139 | DB::alteration_message('ERROR: could not find any defaults', 'deleted'); |
||
140 | } |
||
141 | } else { |
||
142 | DB::alteration_message('ERROR: could not find any configs', 'deleted'); |
||
143 | } |
||
144 | } else { |
||
145 | DB::alteration_message('ERROR: could not find any definitions', 'deleted'); |
||
146 | } |
||
147 | } |
||
148 | |||
149 | /** |
||
150 | * Check what files is being used. |
||
151 | */ |
||
152 | protected function checkFiles() |
||
153 | { |
||
154 | $configsObject = EcommerceConfig::create(); |
||
155 | DB::alteration_message('<h2>Files Used</h2>'); |
||
156 | $files = implode(', ', $configsObject->fileLocations()); |
||
157 | global $project; |
||
158 | $baseFolder = Director::baseFolder(); |
||
159 | $projectFolder = $project.'/_config'; |
||
160 | $baseAndProjectFolder = $baseFolder.'/'.$projectFolder; |
||
161 | $file = 'ecommerce.yml'; |
||
162 | $projectFolderAndFile = $projectFolder.'/'.$file; |
||
163 | $fullFilePath = $baseFolder.'/'.$projectFolderAndFile; |
||
164 | $defaultFileFullPath = Director::baseFolder().'/'.$this->defaultLocation; |
||
165 | DB::alteration_message( |
||
166 | ' |
||
167 | Current files used: <strong style="color: darkRed">'.$files.'</strong>, |
||
168 | unless stated otherwise, all settings can be edited in these file(s).', |
||
169 | 'created' |
||
170 | ); |
||
171 | if (!file_exists($baseAndProjectFolder)) { |
||
172 | mkdir($baseAndProjectFolder); |
||
173 | } |
||
174 | if (!file_exists($fullFilePath)) { |
||
175 | copy($defaultFileFullPath, $fullFilePath); |
||
176 | DB::alteration_message('We have created a new configuration file for you.', 'created'); |
||
177 | } |
||
178 | if ($files == $this->defaultLocation) { |
||
179 | if (file_exists($fullFilePath)) { |
||
180 | DB::alteration_message("A customisable configuration file exists here: $projectFolderAndFile, you should add the following to your config.yml file: |
||
181 | <pre> |
||
182 | EcommerceConfig: |
||
183 | folder_and_file_locations: |
||
184 | - \"$projectFolderAndFile\" |
||
185 | </pre>", 'created'); |
||
186 | } |
||
187 | } |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * Work out items set in the configuration but not set in the config file. |
||
192 | */ |
||
193 | protected function definitionsNotSet() |
||
194 | { |
||
195 | echo '<h2>Set in configs but not defined</h2>'; |
||
196 | $allOK = true; |
||
197 | foreach ($this->configs as $className => $setting) { |
||
198 | if (!isset($this->definitions[$className])) { |
||
199 | $allOK = false; |
||
200 | $this->missingClasses[$className] = $className; |
||
201 | DB::alteration_message("$className", 'deleted'); |
||
202 | } else { |
||
203 | $classConfigs = $this->configs[$className]; |
||
204 | foreach ($classConfigs as $key => $classConfig) { |
||
205 | if (!isset($this->definitions[$className][$key])) { |
||
206 | $allOK = false; |
||
207 | DB::alteration_message("$className.$key", 'deleted'); |
||
208 | } |
||
209 | } |
||
210 | } |
||
211 | } |
||
212 | if ($allOK) { |
||
213 | DB::alteration_message('Perfect match, nothing to report', 'created'); |
||
214 | } else { |
||
215 | DB::alteration_message('Recommended course of action: remove from your config as these are superfluous!', 'edited'); |
||
216 | } |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * Work out items set in the configuration but not set in the config file. |
||
221 | */ |
||
222 | protected function classesThatDoNotExist() |
||
223 | { |
||
224 | echo '<h2>Classes that do not exist</h2>'; |
||
225 | $allOK = true; |
||
226 | foreach ($this->configs as $className => $setting) { |
||
227 | if (!class_exists($className)) { |
||
228 | $allOK = false; |
||
229 | DB::alteration_message("$className", 'deleted'); |
||
230 | } |
||
231 | } |
||
232 | if ($allOK) { |
||
233 | DB::alteration_message('Perfect match, nothing to report', 'created'); |
||
234 | } else { |
||
235 | DB::alteration_message('Recommended course of action: remove from your config file and review if any other action needs to be taken.', 'edited'); |
||
236 | } |
||
237 | } |
||
238 | |||
239 | /** |
||
240 | * Work out items set in the definitions but not set in the config file. |
||
241 | */ |
||
242 | protected function configsNotSet() |
||
243 | { |
||
244 | echo '<h2>Defined variables not set in configs ...</h2>'; |
||
245 | $allOK = true; |
||
246 | //print_r($this->configs["EcommercePayment"]); |
||
247 | foreach ($this->definitions as $className => $setting) { |
||
248 | if (!isset($this->configs[$className])) { |
||
249 | DB::alteration_message("No settings found for $className in /ecommerce/_config/config.yml", 'deleted'); |
||
250 | } else { |
||
251 | $classConfigs = $this->definitions[$className]; |
||
252 | foreach ($classConfigs as $key => $classConfig) { |
||
253 | if (!isset($this->configs[$className][$key])) { |
||
254 | $this->customisedValues[$className][$key] = false; |
||
255 | //fallback to Configs... |
||
256 | } else { |
||
257 | $this->customisedValues[$className][$key] = false; |
||
258 | } |
||
259 | if (!isset($this->configs[$className][$key])) { |
||
260 | DB::alteration_message(" - $className.$key NOT SET in /ecommerce/_config/config.yml", 'deleted'); |
||
261 | $allOK = false; |
||
262 | } else { |
||
263 | //$this->configs[$className][$key] = EcommerceConfig::get($className, $key); |
||
264 | //if(!$this->configs[$className][$key]) { |
||
265 | //DB::alteration_message(" - $className.$key exists, set to FALSE / [EMPTRY STRING]", "edited"); |
||
266 | //} |
||
267 | } |
||
268 | } |
||
269 | } |
||
270 | } |
||
271 | if ($allOK) { |
||
272 | DB::alteration_message('Perfect match, nothing to report', 'created'); |
||
273 | } else { |
||
274 | DB::alteration_message('Recommended course of action: add the above configs to your mysite/_config/ecommerce.yml file if you required them.', 'edited'); |
||
275 | } |
||
276 | } |
||
277 | |||
278 | /** |
||
279 | * Work out items set in the definitions but not set in the config file. |
||
280 | */ |
||
281 | protected function definedConfigs() |
||
282 | { |
||
283 | $htmlHeader = " |
||
284 | <style> |
||
285 | body {margin-left: 300px!important;} |
||
286 | h2 {padding-top: 2em;margin-bottom: 0; padding-bottom: 0;} |
||
287 | th[scope='col'] {text-align: left; border-bottom: 3px solid #ccdef3;padding-top: 40px;} |
||
288 | td {vertical-align: top; border-left: 1px solid #d7d7d7; border-bottom: 1px solid #d7d7d7; padding: 10px; width: 47%;} |
||
289 | /** headings **/ |
||
290 | td span.spanTitle {color: #002137; font-weight: 900; display: block; padding-left: 10px; padding-bottom: 5px;} |
||
291 | .ecommerceConfigHeadings th, h2 { |
||
292 | font-size: 1.2em; |
||
293 | padding-bottom: 5px; |
||
294 | color: #002137; |
||
295 | } |
||
296 | td span {color: #000; font-size: 0.8em; display: block; padding-left: 10px; } |
||
297 | .sameConfig {color: #000;} |
||
298 | .newConfig pre:first-of-type{color: #000; background-color: yellow;} |
||
299 | .newConfig pre:first-of-type { } |
||
300 | .newConfig pre:nth-of-type(2) { } |
||
301 | #TOC { |
||
302 | position: fixed; |
||
303 | top: -15px; |
||
304 | bottom: -20px; |
||
305 | color: #fff; |
||
306 | background-color: #000; |
||
307 | width: 270px; |
||
308 | left: 0px; |
||
309 | padding-top: 15px; |
||
310 | z-index: 10000; |
||
311 | overflow: auto; |
||
312 | padding-bottom: 20px; |
||
313 | } |
||
314 | #TOC ul { |
||
315 | list-style-type: none; |
||
316 | } |
||
317 | #TOC li { |
||
318 | line-height: 1.3; |
||
319 | font-size: 80%; |
||
320 | font-weight: 900; |
||
321 | height: auto; |
||
322 | list-style-type: none; |
||
323 | } |
||
324 | #TOC a { |
||
325 | color: #fff; |
||
326 | text-decoration: none; |
||
327 | font-size: 85%; |
||
328 | font-weight: 900; |
||
329 | margin-left: -10px; |
||
330 | } |
||
331 | #TOC a:hover { |
||
332 | color: #7da4be; |
||
333 | } |
||
334 | /* not sure why we needed this ... |
||
335 | #TaskHolder, #EcommerceDatabaseAdmin, .info h1, .info h3, .info a:first-of-type { |
||
336 | margin-left: 280px !important; |
||
337 | } |
||
338 | */ |
||
339 | .info h1, .info h3, .info a { |
||
340 | padding-left: 30px; |
||
341 | } |
||
342 | a.backToTop {display: block; font-size: 0.7em; float: right;} |
||
343 | td.newConfig {} |
||
344 | table td pre, table td sub {white-space:pre-wrap; font-size: 1em; font-weight: bold;margin: 3px; padding: 3px;} |
||
345 | table td sub {font-weight: normal; font-size: 77%;} |
||
346 | |||
347 | li pre {width: auto;} |
||
348 | </style> |
||
349 | "; |
||
350 | $htmlTable = ' |
||
351 | <table summary="list of configs"> |
||
352 | '; |
||
353 | $oldClassName = ''; |
||
354 | $htmlTOC = '<div id="TOC"><ul>'; |
||
355 | $count = 0; |
||
356 | $oldHeaderOfGroup = ''; |
||
357 | $newHeader = ''; |
||
358 | $completedListOfClasses = array(); |
||
359 | foreach ($this->definitionsHeaders as $headerOfGroup => $classesArray) { |
||
360 | if ($headerOfGroup == 'OTHER') { |
||
361 | $classesArray = array_keys(array_diff_key($this->configs, $completedListOfClasses)); |
||
362 | } |
||
363 | foreach ($classesArray as $className) { |
||
364 | $completedListOfClasses[$className] = $className; |
||
365 | if (!isset($this->configs[$className])) { |
||
366 | $this->configs[$className] = array(); |
||
367 | } |
||
368 | $settings = $this->configs[$className]; |
||
369 | ++$count; |
||
370 | if (in_array($className, $classesArray)) { |
||
371 | $newHeader = $headerOfGroup; |
||
372 | } |
||
373 | if ($oldHeaderOfGroup != $newHeader) { |
||
374 | $oldHeaderOfGroup = $headerOfGroup; |
||
375 | $htmlTOC .= "</ul><li class=\"header\">$headerOfGroup</li><ul>"; |
||
376 | } |
||
377 | |||
378 | $htmlTOC .= "<li><a href=\"#$className\">$count. $className</a></li>"; |
||
379 | if ($className != $oldClassName) { |
||
380 | $htmlTable .= "<tr class='ecommerceConfigHeadings' id=\"$className\"><th colspan=\"2\" scope=\"col\"> |
||
381 | $count. $className ($newHeader) |
||
382 | <a class=\"backToTop\" href=\"#TaskHolder\">top</a> |
||
383 | </th></tr>"; |
||
384 | $oldClassName = $className; |
||
385 | } |
||
386 | if (is_array($settings)) { |
||
387 | foreach ($settings as $key => $classConfig) { |
||
388 | $configError = ''; |
||
389 | $class = ''; |
||
390 | $hasDefaultvalue = false; |
||
391 | $showActualValue = true; |
||
392 | $isDatabaseValues = isset($this->databaseValues[$className][$key]) ? $this->databaseValues[$className][$key] : false; |
||
393 | $isOtherConfigs = isset($this->otherConfigs[$className][$key]) ? $this->otherConfigs[$className][$key] : false; |
||
394 | $isCustomisedValues = isset($this->customisedValues[$className][$key]) ? $this->customisedValues[$className][$key] : false; |
||
395 | if (!isset($this->defaults[$className][$key])) { |
||
396 | $defaultValueRaw = false; |
||
397 | //DB::alteration_message("Could not retrieve default value for: $className $key", "deleted"); |
||
398 | } else { |
||
399 | $defaultValueRaw = $this->defaults[$className][$key]; |
||
400 | $hasDefaultvalue = true; |
||
401 | } |
||
402 | $defaultValue = print_r($defaultValueRaw, 1); |
||
403 | $manuallyAddedValue = print_r($this->configs[$className][$key], 1); |
||
404 | if ($isDatabaseValues || $isOtherConfigs) { |
||
405 | $actualValueRaw = $this->configs[$className][$key]; |
||
406 | } else { |
||
407 | $actualValueRaw = EcommerceConfig::get($className, $key); |
||
408 | } |
||
409 | //if(!$actualValueRaw && $manuallyAddedValue) { |
||
410 | // $actualValueRaw = $manuallyAddedValue; |
||
411 | //} |
||
412 | |||
413 | $actualValue = print_r($actualValueRaw, 1); |
||
414 | if ($defaultValue === $manuallyAddedValue && $isCustomisedValues) { |
||
415 | $configError .= 'This is a superfluous entry in your custom config as the default value is the same.'; |
||
416 | } |
||
417 | if (($defaultValueRaw == $actualValueRaw) || (! $hasDefaultvalue)) { |
||
418 | $class .= 'sameConfig'; |
||
419 | if ($defaultValueRaw == $actualValueRaw) { |
||
420 | $showActualValue = false; |
||
421 | } |
||
422 | } else { |
||
423 | $class .= ' newConfig'; |
||
424 | } |
||
425 | $actualValue = $this->turnValueIntoHumanReadableValue($actualValue); |
||
426 | if ($hasDefaultvalue) { |
||
427 | $defaultValue = $this->turnValueIntoHumanReadableValue($defaultValue); |
||
428 | } |
||
429 | |||
430 | if (!isset($this->definitions[$className][$key])) { |
||
431 | $description = '<span style="color: red; font-weight: bold">ERROR: no longer required in configs!</span>'; |
||
432 | } else { |
||
433 | $description = $this->definitions[$className][$key]; |
||
434 | $description .= $this->specialCases($className, $key, $actualValue); |
||
435 | } |
||
436 | $defaultValueHTML = ''; |
||
437 | if ($defaultValue && !$isOtherConfigs && $showActualValue) { |
||
438 | $defaultValueHTML = "<sub>default:</sub><pre>$defaultValue</pre>"; |
||
439 | } |
||
440 | if ($configError) { |
||
441 | $configError = "<span style=\"color: red; font-size: 10px;\">$configError</span>"; |
||
442 | } |
||
443 | $sourceNote = ''; |
||
444 | if ($isDatabaseValues) { |
||
445 | $sourceNote = '<span>Values are set in the database using the CMS.</span>'; |
||
446 | } |
||
447 | $htmlTable .= "<tr> |
||
448 | <td> |
||
449 | <span class='spanTitle'>$key</span> |
||
450 | <span>$description</span> |
||
451 | $sourceNote |
||
452 | </td> |
||
453 | <td class=\"$class\"> |
||
454 | <pre>$actualValue</pre> |
||
455 | $defaultValueHTML |
||
456 | $configError |
||
457 | </td> |
||
458 | </tr>"; |
||
459 | } |
||
460 | } |
||
461 | } |
||
462 | } |
||
463 | $htmlEnd = ' |
||
464 | </table> |
||
465 | <h2>--- THE END ---</h2> |
||
466 | '; |
||
467 | $htmlTOC .= '</ul></div>'; |
||
468 | echo $htmlHeader.$htmlTOC.$htmlTable.$htmlEnd; |
||
469 | } |
||
470 | |||
471 | protected function getDefaultValues() |
||
472 | { |
||
473 | require_once Director::baseFolder().'/vendor/mustangostang/spyc/Spyc.php'; |
||
474 | $fixtureFolderAndFile = Director::baseFolder().'/'.$this->defaultLocation; |
||
475 | $parser = new Spyc(); |
||
476 | |||
477 | return $parser->loadFile($fixtureFolderAndFile); |
||
478 | } |
||
479 | |||
480 | /** |
||
481 | * Adding EcommerceDBConfig values. |
||
482 | */ |
||
483 | protected function addEcommerceDBConfigToConfigs() |
||
484 | { |
||
485 | $ecommerceDBConfig = EcommerceDBConfig::current_ecommerce_db_config(); |
||
486 | $fields = $ecommerceDBConfig->fieldLabels(); |
||
487 | if ($fields) { |
||
0 ignored issues
–
show
The expression
$fields 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 ![]() |
|||
488 | foreach ($fields as $field => $description) { |
||
489 | if ($field != 'Title' && $field != 'UseThisOne') { |
||
490 | $defaultsDefaults = $ecommerceDBConfig->stat('defaults'); |
||
491 | $this->definitions['EcommerceDBConfig'][$field] = "$description. <br />see: <a href=\"".$ecommerceDBConfig->CMSEditLink()."\">Ecommerce Configuration</a>"; |
||
492 | $this->configs['EcommerceDBConfig'][$field] = $ecommerceDBConfig->$field; |
||
493 | $this->databaseValues['EcommerceDBConfig'][$field] = true; |
||
494 | $this->defaults['EcommerceDBConfig'][$field] = isset($defaultsDefaults[$field]) ? $defaultsDefaults[$field] : 'no default set'; |
||
495 | $imageField = $field.'ID'; |
||
496 | if (isset($ecommerceDBConfig->$imageField)) { |
||
497 | if ($image = $ecommerceDBConfig->$field()) { |
||
498 | if ($image->exists() && is_a($image, Object::getCustomClass('Image'))) { |
||
499 | $this->configs['EcommerceDBConfig'][$field] = '[Image] --- <img src="'.$image->Link().'" />'; |
||
500 | $this->databaseValues['EcommerceDBConfig'][$field] = true; |
||
501 | } |
||
502 | } |
||
503 | } |
||
504 | } |
||
505 | } |
||
506 | } |
||
507 | } |
||
508 | |||
509 | protected function addOtherValuesToConfigs() |
||
510 | { |
||
511 | $this->definitions['Email']['admin_email_address'] = 'Default administrator email. <br />SET USING Email::$admin_email = "[email protected]" in the _config.php FILES'; |
||
512 | $this->configs['Email']['admin_email_address'] = Config::inst()->get('Email', 'admin_email'); |
||
513 | $this->defaults['Email']['admin_email_address'] = '[no default set]'; |
||
514 | $this->otherConfigs['Email']['admin_email_address'] = true; |
||
515 | |||
516 | $siteConfig = SiteConfig::current_site_config(); |
||
517 | $this->definitions['SiteConfig']['website_title'] = 'The name of the website. <br />see: <a href="/admin/settings/">site configuration</a>.'; |
||
518 | $this->configs['SiteConfig']['website_title'] = $siteConfig->Title; |
||
519 | $this->defaults['SiteConfig']['website_title'] = '[no default set]'; |
||
520 | $this->otherConfigs['SiteConfig']['website_title'] = true; |
||
521 | |||
522 | $this->definitions['SiteConfig']['website_tagline'] = 'The subtitle or tagline of the website. <br />see: <a href="/admin/settings/">site configuration</a>.'; |
||
523 | $this->configs['SiteConfig']['website_tagline'] = $siteConfig->Tagline; |
||
524 | $this->defaults['SiteConfig']['website_tagline'] = '[no default set]'; |
||
525 | $this->otherConfigs['SiteConfig']['website_tagline'] = true; |
||
526 | } |
||
527 | |||
528 | protected function addPages() |
||
529 | { |
||
530 | if ($checkoutPage = DataObject::get_one('CheckoutPage')) { |
||
531 | $this->getPageDefinitions($checkoutPage); |
||
0 ignored issues
–
show
$checkoutPage of type object<DataObject> is not a sub-type of object<SiteTree> . It seems like you assume a child class of the class DataObject to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
532 | $this->definitions['Pages']['CheckoutPage'] = 'Page where customers finalise (checkout) their order. This page is required.<br />'.($checkoutPage ? '<a href="/admin/pages/edit/show/'.$checkoutPage->ID.'/">edit</a>' : 'Create one in the <a href="/admin/pages/add/">CMS</a>'); |
||
533 | $this->configs['Pages']['CheckoutPage'] = $checkoutPage ? 'view: <a href="'.$checkoutPage->Link().'">'.$checkoutPage->Title.'</a><br />'.$checkoutPage->configArray : ' NOT CREATED!'; |
||
534 | $this->defaults['Pages']['CheckoutPage'] = $checkoutPage ? $checkoutPage->defaultsArray : '[add page first to see defaults]'; |
||
0 ignored issues
–
show
The property
defaultsArray does not seem to exist. Did you mean defaults ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
535 | $this->databaseValues['Pages']['CheckoutPage'] = true; |
||
536 | } |
||
537 | |||
538 | if ($orderConfirmationPage = DataObject::get_one('OrderConfirmationPage')) { |
||
539 | $this->getPageDefinitions($orderConfirmationPage); |
||
0 ignored issues
–
show
$orderConfirmationPage of type object<DataObject> is not a sub-type of object<SiteTree> . It seems like you assume a child class of the class DataObject to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
540 | $this->definitions['Pages']['OrderConfirmationPage'] = 'Page where customers review their order after it has been placed. This page is required.<br />'.($orderConfirmationPage ? '<a href="/admin/pages/edit/show/'.$orderConfirmationPage->ID.'/">edit</a>' : 'Create one in the <a href="/admin/pages/add/">CMS</a>'); |
||
541 | $this->configs['Pages']['OrderConfirmationPage'] = $orderConfirmationPage ? 'view: <a href="'.$orderConfirmationPage->Link().'">'.$orderConfirmationPage->Title.'</a><br />'.$orderConfirmationPage->configArray : ' NOT CREATED!'; |
||
542 | $this->defaults['Pages']['OrderConfirmationPage'] = $orderConfirmationPage ? $orderConfirmationPage->defaultsArray : '[add page first to see defaults]'; |
||
0 ignored issues
–
show
The property
defaultsArray does not seem to exist. Did you mean defaults ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
543 | $this->databaseValues['Pages']['OrderConfirmationPage'] = true; |
||
544 | } |
||
545 | |||
546 | if ($accountPage = DataObject::get_one('AccountPage')) { |
||
547 | $this->getPageDefinitions($accountPage); |
||
0 ignored issues
–
show
$accountPage of type object<DataObject> is not a sub-type of object<SiteTree> . It seems like you assume a child class of the class DataObject to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
548 | $this->definitions['Pages']['AccountPage'] = 'Page where customers can review their account. This page is required.<br />'.($accountPage ? '<a href="/admin/pages/edit/show/'.$accountPage->ID.'/">edit</a>' : 'Create one in the <a href="/admin/pages/add/">CMS</a>'); |
||
549 | $this->configs['Pages']['AccountPage'] = $accountPage ? 'view: <a href="'.$accountPage->Link().'">'.$accountPage->Title.'</a><br />'.$accountPage->configArray : ' NOT CREATED!'; |
||
550 | $this->defaults['Pages']['AccountPage'] = $accountPage ? $accountPage->defaultsArray : '[add page first to see defaults]'; |
||
0 ignored issues
–
show
The property
defaultsArray does not seem to exist. Did you mean defaults ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
551 | $this->databaseValues['Pages']['AccountPage'] = true; |
||
552 | } |
||
553 | |||
554 | if ( |
||
555 | $cartPage = DataObject::get_one('CartPage', array('ClassName' => 'CartPage')) |
||
556 | ) { |
||
557 | $this->getPageDefinitions($cartPage); |
||
0 ignored issues
–
show
$cartPage of type object<DataObject> is not a sub-type of object<SiteTree> . It seems like you assume a child class of the class DataObject to be always present.
This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass. Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type. ![]() |
|||
558 | $this->definitions['Pages']['CartPage'] = 'Page where customers review their cart while shopping. This page is optional.<br />'.($cartPage ? '<a href="/admin/pages/edit/show/'.$cartPage->ID.'/">edit</a>' : 'Create one in the <a href="/admin/pages/add/">CMS</a>'); |
||
559 | $this->configs['Pages']['CartPage'] = $cartPage ? 'view: <a href="'.$cartPage->Link().'">'.$cartPage->Title.'</a>, <a href="/admin/pages/edit/show/'.$cartPage->ID.'/">edit</a><br />'.$cartPage->configArray : ' NOT CREATED!'; |
||
560 | $this->defaults['Pages']['CartPage'] = $cartPage ? $cartPage->defaultsArray : '[add page first to see defaults]'; |
||
0 ignored issues
–
show
The property
defaultsArray does not seem to exist. Did you mean defaults ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
561 | $this->defaults['Pages']['CartPage'] = $cartPage ? $cartPage->defaultsArray : '[add page first to see defaults]'; |
||
0 ignored issues
–
show
The property
defaultsArray does not seem to exist. Did you mean defaults ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
562 | $this->databaseValues['Pages']['CartPage'] = true; |
||
563 | } |
||
564 | } |
||
565 | |||
566 | private function getPageDefinitions(SiteTree $page) |
||
567 | { |
||
568 | if ($page) { |
||
569 | $fields = Config::inst()->get($page->ClassName, 'db'); |
||
570 | $defaultsArray = $page->stat('defaults', true); |
||
571 | $configArray = array(); |
||
572 | if ($fields) { |
||
573 | foreach ($fields as $fieldKey => $fieldType) { |
||
0 ignored issues
–
show
The expression
$fields of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
574 | $configArray[$fieldKey] = $page->$fieldKey; |
||
575 | if (!isset($defaultsArray[$fieldKey])) { |
||
576 | $defaultsArray[$fieldKey] = '[default not set]'; |
||
577 | } |
||
578 | } |
||
579 | } |
||
580 | $page->defaultsArray = $defaultsArray; |
||
0 ignored issues
–
show
The property
defaultsArray does not seem to exist. Did you mean defaults ?
An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name. If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading. ![]() |
|||
581 | $page->configArray = print_r($configArray, 1); |
||
582 | } |
||
583 | } |
||
584 | |||
585 | public function orderSteps() |
||
586 | { |
||
587 | $steps = OrderStep::get(); |
||
588 | if ($steps->count()) { |
||
589 | foreach ($steps as $step) { |
||
590 | $fields = Config::inst()->get($step->ClassName, 'db'); |
||
591 | $defaultsArray = $step->stat('defaults', true); |
||
592 | $configArray = array(); |
||
593 | foreach ($fields as $fieldKey => $fieldType) { |
||
0 ignored issues
–
show
The expression
$fields of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
594 | if ($fields) { |
||
595 | $configArray[$fieldKey] = $step->$fieldKey; |
||
596 | if (!isset($defaultsArray[$fieldKey])) { |
||
597 | $defaultsArray[$fieldKey] = '[default not set]'; |
||
598 | } |
||
599 | } |
||
600 | } |
||
601 | $ecommerceDBConfig = EcommerceDBConfig::current_ecommerce_db_config(); |
||
0 ignored issues
–
show
$ecommerceDBConfig 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 ![]() |
|||
602 | $this->definitions['OrderStep'][$step->Code] = $step->Description.'<br />see: <a href="'.$step->CMSEditLink().'">Step Configuration</a>.'; |
||
603 | $this->configs['OrderStep'][$step->Code] = $configArray; |
||
604 | $this->defaults['OrderStep'][$step->Code] = $defaultsArray; |
||
605 | $this->databaseValues['OrderStep'][$step->Code] = true; |
||
606 | } |
||
607 | } |
||
608 | } |
||
609 | |||
610 | public function checkoutAndModifierDetails() |
||
611 | { |
||
612 | $checkoutPage = DataObject::get_one('CheckoutPage'); |
||
613 | if (!$checkoutPage) { |
||
614 | $task = new EcommerceTaskDefaultRecords(); |
||
615 | $task->run(null); |
||
0 ignored issues
–
show
null is of type null , but the function expects a object<SS_HTTPRequest> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
616 | $checkoutPage = DataObject::get_one('CheckoutPage'); |
||
617 | if (!$checkoutPage) { |
||
618 | user_error('There is no checkout page available and it seems impossible to create one.'); |
||
619 | } |
||
620 | } |
||
621 | $steps = CheckoutPage_StepDescription::get(); |
||
622 | if ($steps->count()) { |
||
623 | foreach ($steps as $key => $step) { |
||
624 | $stepNumber = $key + 1; |
||
625 | $fields = Config::inst()->get($step->ClassName, 'db'); |
||
626 | $defaultsArray = $step->stat('defaults', true); |
||
627 | $configArray = array(); |
||
628 | foreach ($fields as $fieldKey => $fieldType) { |
||
0 ignored issues
–
show
The expression
$fields of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
629 | if ($fields) { |
||
630 | $configArray[$fieldKey] = $step->$fieldKey; |
||
631 | if (!isset($defaultsArray[$fieldKey])) { |
||
632 | $defaultsArray[$fieldKey] = '[default not set]'; |
||
633 | } |
||
634 | } |
||
635 | } |
||
636 | $this->definitions['CheckoutPage_Controller']["STEP_$stepNumber".'_'.$step->Code] = $step->Description.'<br />see: <a href="/admin/pages/edit/show/'.$checkoutPage->ID.'/">checkout page</a>.'; |
||
637 | $this->configs['CheckoutPage_Controller']["STEP_$stepNumber".'_'.$step->Code] = $configArray; |
||
638 | $this->defaults['CheckoutPage_Controller']["STEP_$stepNumber".'_'.$step->Code] = $defaultsArray; |
||
639 | $this->databaseValues['CheckoutPage_Controller']["STEP_$stepNumber".'_'.$step->Code] = true; |
||
640 | } |
||
641 | } |
||
642 | $steps = OrderModifier_Descriptor::get(); |
||
643 | if ($steps->count()) { |
||
644 | foreach ($steps as $step) { |
||
645 | $fields = Config::inst()->get($step->ClassName, 'db'); |
||
646 | $defaultsArray = $step->stat('defaults', true); |
||
647 | $configArray = array(); |
||
648 | foreach ($fields as $fieldKey => $fieldType) { |
||
0 ignored issues
–
show
The expression
$fields of type array|integer|double|string|boolean is not guaranteed to be traversable. How about adding an additional type check?
There are different options of fixing this problem.
![]() |
|||
649 | if ($fields) { |
||
650 | $configArray[$fieldKey] = $step->$fieldKey; |
||
651 | if (!isset($defaultsArray[$fieldKey])) { |
||
652 | $defaultsArray[$fieldKey] = '[default not set]'; |
||
653 | } |
||
654 | } |
||
655 | } |
||
656 | $this->definitions['CheckoutPage_Controller']['OrderModifier_Descriptor_'.$step->ModifierClassName] = $step->Description.'<br />see: <a href="/admin/pages/edit/show/'.$checkoutPage->ID.'/">checkout page</a>.'; |
||
657 | $this->configs['CheckoutPage_Controller']['OrderModifier_Descriptor_'.$step->ModifierClassName] = $configArray; |
||
658 | $this->defaults['CheckoutPage_Controller']['OrderModifier_Descriptor_'.$step->ModifierClassName] = $defaultsArray; |
||
659 | $this->databaseValues['CheckoutPage_Controller']['OrderModifier_Descriptor_'.$step->ModifierClassName] = true; |
||
660 | } |
||
661 | } |
||
662 | } |
||
663 | |||
664 | private function getAjaxDefinitions() |
||
665 | { |
||
666 | $definitionsObject = EcommerceConfigDefinitions::create(); |
||
667 | $methodArray = $definitionsObject->getAjaxMethods(); |
||
668 | $requestor = new ArrayData( |
||
669 | array( |
||
670 | 'ID' => '[ID]', |
||
671 | 'ClassName' => '[CLASSNAME]', |
||
672 | ) |
||
673 | ); |
||
674 | $obj = EcommerceConfigAjax::get_one($requestor); |
||
0 ignored issues
–
show
$requestor is of type object<ArrayData> , but the function expects a object<DataObject> .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
|||
675 | foreach ($methodArray as $method => $description) { |
||
676 | if ($method != 'setRequestor') { |
||
677 | if (strpos($method, 'lassName')) { |
||
678 | $selector = 'classname'; |
||
679 | } else { |
||
680 | $selector = 'id'; |
||
681 | } |
||
682 | $note = " |
||
683 | This variable can be used like this: <pre><div $selector=\"\$AJAXDefinitions.".$method.'"></div></pre> |
||
684 | <a href="/shoppingcart/ajaxtest/?ajax=1">AJAX</a> will then use this selector to put the following content: '; |
||
685 | $this->definitions['Templates']["AJAXDefinitions_$method"] = $note.'<br />'.$description; |
||
686 | $this->configs['Templates']["AJAXDefinitions_$method"] = $obj->$method(); |
||
687 | $this->defaults['Templates']["AJAXDefinitions_$method"] = $obj->$method(); |
||
688 | $this->otherConfigs['Templates']["AJAXDefinitions_$method"] = true; |
||
689 | } |
||
690 | } |
||
691 | } |
||
692 | |||
693 | /** |
||
694 | * check for any additional settings. |
||
695 | */ |
||
696 | private function specialCases($className, $key, $actualValue) |
||
0 ignored issues
–
show
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 ![]() |
|||
697 | { |
||
698 | switch ($className.'.'.$key) { |
||
699 | case 'Order_Email.css_file_location': |
||
700 | if (!file_exists(Director::baseFolder()."/$actualValue")) { |
||
701 | return '<span style="color: red">ADDITIONAL CHECK: this file '.Director::baseFolder().'/'.$actualValue.' does not exist! For proper functioning of e-commerce, please make sure to create this file.</span>'; |
||
702 | } else { |
||
703 | return '<span style="color: #7da4be">ADDITIONAL CHECK: file exists.</span>'; |
||
704 | } |
||
705 | break; |
||
0 ignored issues
–
show
break; does not seem to be reachable.
This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed. Unreachable code is most often the result of function fx() {
try {
doSomething();
return true;
}
catch (\Exception $e) {
return false;
}
return false;
}
In the above example, the last ![]() |
|||
706 | case 'Order.modifiers': |
||
707 | $classes = ClassInfo::subclassesFor('OrderModifier'); |
||
708 | unset($classes['OrderModifier']); |
||
709 | $classesAsString = implode(', <br />', $classes); |
||
710 | |||
711 | return "<br /><h4>Available Modifiers</h4>$classesAsString"; |
||
712 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
713 | case 'OrderStatusLog.available_log_classes_array': |
||
714 | $classes = ClassInfo::subclassesFor('OrderStatusLog'); |
||
715 | unset($classes['OrderStatusLog']); |
||
716 | $classesAsString = implode(', <br />', $classes); |
||
717 | |||
718 | return "<br /><h4>Available Modifiers</h4>$classesAsString"; |
||
719 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
720 | case 'OrderStep.order_steps_to_include': |
||
721 | $classes = ClassInfo::subclassesFor('OrderStep'); |
||
722 | unset($classes['OrderStep']); |
||
723 | $classesAsString = implode('<br /> - ', $classes); |
||
724 | |||
725 | return "<br /><h4>Available Order Steps</h4> - $classesAsString"; |
||
726 | break; |
||
0 ignored issues
–
show
break is not strictly necessary here and could be removed.
The break statement is not necessary if it is preceded for example by a return statement: switch ($x) {
case 1:
return 'foo';
break; // This break is not necessary and can be left off.
}
If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive. ![]() |
|||
727 | } |
||
728 | } |
||
729 | |||
730 | private function turnValueIntoHumanReadableValue($actualValue) |
||
0 ignored issues
–
show
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 ![]() |
|||
731 | { |
||
732 | if ($actualValue === '') { |
||
733 | $actualValue = '[FALSE] / [EMPTY STRING] '; |
||
734 | } |
||
735 | if ($actualValue === null) { |
||
736 | $actualValue = '[NULL]'; |
||
737 | } |
||
738 | if ($actualValue === '1' || $actualValue === 1) { |
||
739 | $actualValue = '[TRUE] / 1'; |
||
740 | } |
||
741 | if ($actualValue === '0' || $actualValue === false) { |
||
742 | $actualValue = '[FALSE] / 0'; |
||
743 | } |
||
744 | |||
745 | return $actualValue; |
||
746 | } |
||
747 | |||
748 | protected function checkGEOIP() |
||
749 | { |
||
750 | if (Config::inst()->get('EcommerceCountry', 'visitor_country_provider') == 'EcommerceCountry_VisitorCountryProvider' && !class_exists('Geoip')) { |
||
751 | user_error( |
||
752 | " |
||
753 | You need to install Geoip module that has a method Geoip::visitor_country, returning the country code associated with the user's IP address. |
||
754 | Alternatively you can set the following config EcommerceCountry.visitor_country_provider to something like MyGEOipProvider. |
||
755 | You then create a class MyGEOipProvider with a method getCountry().", |
||
756 | E_USER_NOTICE |
||
757 | ); |
||
758 | } elseif (Director::isLive() && !EcommerceCountry::get_country_from_ip()) { |
||
759 | user_error( |
||
760 | " |
||
761 | Please make sure that '".$this->Config()->get('visitor_country_provider')."' (visitor_country_provider) is working on your server (see the GEOIP module for details).", |
||
762 | E_USER_NOTICE |
||
763 | ); |
||
764 | } |
||
765 | } |
||
766 | } |
||
767 |
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.