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) { |
|
|
|
|
124
|
|
|
if ($this->configs) { |
|
|
|
|
125
|
|
|
if ($this->defaults) { |
|
|
|
|
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) { |
|
|
|
|
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); |
|
|
|
|
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]'; |
|
|
|
|
535
|
|
|
$this->databaseValues['Pages']['CheckoutPage'] = true; |
536
|
|
|
} |
537
|
|
|
|
538
|
|
|
if ($orderConfirmationPage = DataObject::get_one('OrderConfirmationPage')) { |
539
|
|
|
$this->getPageDefinitions($orderConfirmationPage); |
|
|
|
|
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]'; |
|
|
|
|
543
|
|
|
$this->databaseValues['Pages']['OrderConfirmationPage'] = true; |
544
|
|
|
} |
545
|
|
|
|
546
|
|
|
if ($accountPage = DataObject::get_one('AccountPage')) { |
547
|
|
|
$this->getPageDefinitions($accountPage); |
|
|
|
|
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]'; |
|
|
|
|
551
|
|
|
$this->databaseValues['Pages']['AccountPage'] = true; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
if ( |
555
|
|
|
$cartPage = DataObject::get_one('CartPage', array('ClassName' => 'CartPage')) |
556
|
|
|
) { |
557
|
|
|
$this->getPageDefinitions($cartPage); |
|
|
|
|
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]'; |
|
|
|
|
561
|
|
|
$this->defaults['Pages']['CartPage'] = $cartPage ? $cartPage->defaultsArray : '[add page first to see defaults]'; |
|
|
|
|
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) { |
|
|
|
|
574
|
|
|
$configArray[$fieldKey] = $page->$fieldKey; |
575
|
|
|
if (!isset($defaultsArray[$fieldKey])) { |
576
|
|
|
$defaultsArray[$fieldKey] = '[default not set]'; |
577
|
|
|
} |
578
|
|
|
} |
579
|
|
|
} |
580
|
|
|
$page->defaultsArray = $defaultsArray; |
|
|
|
|
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) { |
|
|
|
|
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(); |
|
|
|
|
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); |
|
|
|
|
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) { |
|
|
|
|
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) { |
|
|
|
|
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); |
|
|
|
|
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) |
|
|
|
|
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; |
|
|
|
|
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; |
|
|
|
|
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; |
|
|
|
|
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; |
|
|
|
|
727
|
|
|
} |
728
|
|
|
} |
729
|
|
|
|
730
|
|
|
private function turnValueIntoHumanReadableValue($actualValue) |
|
|
|
|
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.