Completed
Push — copilot/remove-outdated-badges... ( 4a4e1f...d46ff8 )
by
unknown
11:28 queued 11:15
created
thirdparty/rc4crypt.php 2 patches
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -35,7 +35,7 @@  discard block
 block discarded – undo
35 35
 	 * @access public
36 36
 	 * @return string
37 37
 	 */
38
-	static function encrypt ($pwd, $data, $ispwdHex = 0)
38
+	static function encrypt($pwd, $data, $ispwdHex = 0)
39 39
 	{
40 40
 		if ($ispwdHex)
41 41
 			$pwd = @pack('H*', $pwd); // valid input, please!
@@ -80,7 +80,7 @@  discard block
 block discarded – undo
80 80
 	 * @access public
81 81
 	 * @return string
82 82
 	 */
83
-	static function decrypt ($pwd, $data, $ispwdHex = 0)
83
+	static function decrypt($pwd, $data, $ispwdHex = 0)
84 84
 	{
85 85
 		return self::encrypt($pwd, $data, $ispwdHex);
86 86
 	}
Please login to merge, or discard this patch.
Braces   +4 added lines, -2 removed lines patch added patch discarded remove patch
@@ -37,8 +37,10 @@
 block discarded – undo
37 37
 	 */
38 38
 	static function encrypt ($pwd, $data, $ispwdHex = 0)
39 39
 	{
40
-		if ($ispwdHex)
41
-			$pwd = @pack('H*', $pwd); // valid input, please!
40
+		if ($ispwdHex) {
41
+					$pwd = @pack('H*', $pwd);
42
+		}
43
+		// valid input, please!
42 44
  
43 45
 		$key[] = '';
44 46
 		$box[] = '';
Please login to merge, or discard this patch.
src/Controller/OrderHistoryPageController.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -20,7 +20,7 @@
 block discarded – undo
20 20
     {
21 21
         if (Security::getCurrentUser()) {
22 22
             return true;
23
-        } else {
23
+        }else {
24 24
             return Security::permissionFailure($this, _t(
25 25
                 'AccountPage.CANNOTCONFIRMLOGGEDIN',
26 26
                 'Please login to view this page.'
Please login to merge, or discard this patch.
Indentation   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -12,35 +12,35 @@
 block discarded – undo
12 12
  */
13 13
 class OrderHistoryPageController extends \PageController
14 14
 {
15
-    /**
16
-     * @var array
17
-     */
18
-    private static $allowed_actions = array(
19
-        'index',
20
-    );
15
+	/**
16
+	 * @var array
17
+	 */
18
+	private static $allowed_actions = array(
19
+		'index',
20
+	);
21 21
 
22
-    /**
23
-     * @return bool|\SilverStripe\Control\HTTPResponse
24
-     */
25
-    public function checkMember()
26
-    {
27
-        if (Security::getCurrentUser()) {
28
-            return true;
29
-        } else {
30
-            return Security::permissionFailure($this, _t(
31
-                'AccountPage.CANNOTCONFIRMLOGGEDIN',
32
-                'Please login to view this page.'
33
-            ));
34
-        }
35
-    }
22
+	/**
23
+	 * @return bool|\SilverStripe\Control\HTTPResponse
24
+	 */
25
+	public function checkMember()
26
+	{
27
+		if (Security::getCurrentUser()) {
28
+			return true;
29
+		} else {
30
+			return Security::permissionFailure($this, _t(
31
+				'AccountPage.CANNOTCONFIRMLOGGEDIN',
32
+				'Please login to view this page.'
33
+			));
34
+		}
35
+	}
36 36
 
37
-    /**
38
-     * @return array
39
-     */
40
-    public function Index()
41
-    {
42
-        $this->checkMember();
37
+	/**
38
+	 * @return array
39
+	 */
40
+	public function Index()
41
+	{
42
+		$this->checkMember();
43 43
 
44
-        return array();
45
-    }
44
+		return array();
45
+	}
46 46
 }
Please login to merge, or discard this patch.
src/Model/FoxyStripeClient.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -262,7 +262,7 @@
 block discarded – undo
262 262
         if ($client) {
263 263
             if ($category = $this->getCategory($data['code'])) {
264 264
                 $result = $client->patch($category, $data);
265
-            } else {
265
+            }else {
266 266
                 $result = $client->post($this->getItemCategoriesURL(), $data);
267 267
             }
268 268
             $errors = array_merge($errors, $client->getErrors($result));
Please login to merge, or discard this patch.
Indentation   +291 added lines, -291 removed lines patch added patch discarded remove patch
@@ -9,300 +9,300 @@
 block discarded – undo
9 9
 
10 10
 class FoxyStripeClient
11 11
 {
12
-    /**
13
-     * @var string
14
-     */
15
-    private static $table_name = 'FS_FoxyStripeClient';
16
-
17
-    /**
18
-     * @var
19
-     */
20
-    private $client;
21
-
22
-    /**
23
-     * @var
24
-     */
25
-    private $current_store;
26
-
27
-    /**
28
-     * @var
29
-     */
30
-    private $item_categories_url;
31
-
32
-    /**
33
-     * @var
34
-     */
35
-    private $item_categories;
36
-
37
-    /**
38
-     * FoxyStripeClient constructor.
39
-     * @throws \Psr\Container\NotFoundExceptionInterface
40
-     */
41
-    public function __construct()
42
-    {
43
-        $config = array(
44
-            'use_sandbox' => false,
45
-        );
46
-
47
-        if ($setting = FoxyStripeSetting::current_foxystripe_setting()) {
48
-            $config['client_id'] = $setting->client_id;
49
-            $config['client_secret'] = $setting->client_secret;
50
-            $config['refresh_token'] = $setting->refresh_token;
51
-            $config['access_token'] = $setting->access_token;
52
-        }
53
-
54
-        $guzzle_config = array(
55
-            'defaults' => array(
56
-                'debug' => false,
57
-                'exceptions' => false,
58
-            ),
59
-        );
60
-
61
-        /*
12
+	/**
13
+	 * @var string
14
+	 */
15
+	private static $table_name = 'FS_FoxyStripeClient';
16
+
17
+	/**
18
+	 * @var
19
+	 */
20
+	private $client;
21
+
22
+	/**
23
+	 * @var
24
+	 */
25
+	private $current_store;
26
+
27
+	/**
28
+	 * @var
29
+	 */
30
+	private $item_categories_url;
31
+
32
+	/**
33
+	 * @var
34
+	 */
35
+	private $item_categories;
36
+
37
+	/**
38
+	 * FoxyStripeClient constructor.
39
+	 * @throws \Psr\Container\NotFoundExceptionInterface
40
+	 */
41
+	public function __construct()
42
+	{
43
+		$config = array(
44
+			'use_sandbox' => false,
45
+		);
46
+
47
+		if ($setting = FoxyStripeSetting::current_foxystripe_setting()) {
48
+			$config['client_id'] = $setting->client_id;
49
+			$config['client_secret'] = $setting->client_secret;
50
+			$config['refresh_token'] = $setting->refresh_token;
51
+			$config['access_token'] = $setting->access_token;
52
+		}
53
+
54
+		$guzzle_config = array(
55
+			'defaults' => array(
56
+				'debug' => false,
57
+				'exceptions' => false,
58
+			),
59
+		);
60
+
61
+		/*
62 62
          * Set up our Guzzle Client
63 63
          */
64
-        $guzzle = new Client($guzzle_config);
65
-        //CacheSubscriber::attach($guzzle); // todo add caching middleware guzzle-cache-middleware
64
+		$guzzle = new Client($guzzle_config);
65
+		//CacheSubscriber::attach($guzzle); // todo add caching middleware guzzle-cache-middleware
66 66
 
67
-        /*
67
+		/*
68 68
          * Get our FoxyClient
69 69
          */
70
-        $fc = new FoxyClient($guzzle, $config);
71
-
72
-        $this->setClient($fc);
73
-        $this->setCurrentStore();
74
-        $this->setItemCategoriesURL();
75
-        $this->setItemCategories();
76
-    }
77
-
78
-    /**
79
-     * @return mixed
80
-     */
81
-    public function getClient()
82
-    {
83
-        return $this->client;
84
-    }
85
-
86
-    /**
87
-     * @param $client
88
-     *
89
-     * @return $this
90
-     */
91
-    public function setClient($client)
92
-    {
93
-        $this->client = $client;
94
-
95
-        return $this;
96
-    }
97
-
98
-    /**
99
-     * @return bool
100
-     * @throws \SilverStripe\ORM\ValidationException
101
-     */
102
-    public static function is_valid()
103
-    {
104
-        $config = FoxyStripeSetting::current_foxystripe_setting();
105
-        return $config->EnableAPI &&
106
-            $config->client_id &&
107
-            $config->client_secret &&
108
-            $config->refresh_token &&
109
-            $config->access_token;
110
-    }
111
-
112
-    /**
113
-     * @return mixed
114
-     */
115
-    public function getCurrentStore()
116
-    {
117
-        return $this->current_store;
118
-    }
119
-
120
-    /**
121
-     * @throws \SilverStripe\ORM\ValidationException
122
-     */
123
-    public function setCurrentStore()
124
-    {
125
-        $client = $this->getClient();
126
-        $config = FoxyStripeSetting::current_foxystripe_setting();
127
-
128
-        $errors = array();
129
-        $data = array(
130
-            'store_domain' => $config->StoreName,
131
-        );
132
-
133
-        if ($client && $result = $client->get()) {
134
-            $errors = array_merge($errors, $client->getErrors($result));
135
-            if ($reporting_uri = $client->getLink('fx:reporting')) {
136
-                $errors = array_merge($errors, $client->getErrors($reporting_uri));
137
-                if ($result = $client->get($reporting_uri)) {
138
-                    $errors = array_merge($errors, $client->getErrors($result));
139
-                    if ($store_exists_uri = $client->getLink('fx:reporting_store_domain_exists')) {
140
-                        $errors = array_merge($errors, $client->getErrors($store_exists_uri));
141
-                        if ($result = $client->get($store_exists_uri, $data)) {
142
-                            $errors = array_merge($errors, $client->getErrors($result));
143
-                            if ($store = $client->getLink('fx:store')) {
144
-                                $errors = array_merge($errors, $client->getErrors($store));
145
-                                $this->current_store = $store;
146
-                            }
147
-                        }
148
-                    }
149
-                }
150
-            }
151
-            if (count($errors)) {
152
-                Injector::inst()->get(LoggerInterface::class)->error('setCurrentStore errors - '.json_encode($errors));
153
-            }
154
-        }
155
-    }
156
-
157
-    /**
158
-     * @param array $data
159
-     *
160
-     * @throws \Psr\Container\NotFoundExceptionInterface
161
-     */
162
-    public function updateStore($data = [])
163
-    {
164
-        $client = $this->getClient();
165
-        $errors = [];
166
-
167
-        $result = $client->patch($this->getCurrentStore(), $data);
168
-
169
-        $errors = array_merge($errors, $client->getErrors($result));
170
-        if (count($errors)) {
171
-            Injector::inst()->get(LoggerInterface::class)->error('updateStore errors - '.json_encode($errors));
172
-        }
173
-    }
174
-
175
-    /**
176
-     * @return mixed
177
-     */
178
-    public function getItemCategoriesURL()
179
-    {
180
-        return $this->item_categories_url;
181
-    }
182
-
183
-    /**
184
-     * @throws \Psr\Container\NotFoundExceptionInterface
185
-     */
186
-    public function setItemCategoriesURL()
187
-    {
188
-        $client = $this->getClient();
189
-        $errors = [];
190
-
191
-        if ($client) {
192
-            $result = $client->get($this->getCurrentStore());
193
-
194
-            if (isset($result['_links']['fx:item_categories']['href'])) {
195
-                $this->item_categories_url = $result['_links']['fx:item_categories']['href'];
196
-            }
197
-
198
-            $errors = array_merge($errors, $client->getErrors($result));
199
-            if (count($errors)) {
200
-                Injector::inst()
201
-                    ->get(LoggerInterface::class)->error('setItemCategoriesURL errors - '.json_encode($errors));
202
-            }
203
-        }
204
-    }
205
-
206
-    /**
207
-     * @return mixed
208
-     */
209
-    public function getItemCategories()
210
-    {
211
-        return $this->item_categories;
212
-    }
213
-
214
-    /**
215
-     * @throws \Psr\Container\NotFoundExceptionInterface
216
-     */
217
-    public function setItemCategories()
218
-    {
219
-        $client = $this->getClient();
220
-        $errors = [];
221
-
222
-        if ($client) {
223
-            $result = $client->get($this->getItemCategoriesURL());
224
-
225
-            $this->item_categories = $result;
226
-
227
-            $errors = array_merge($errors, $client->getErrors($result));
228
-            if (count($errors)) {
229
-                Injector::inst()
230
-                    ->get(LoggerInterface::class)->error('setItemCategories errors - '.json_encode($errors));
231
-            }
232
-        }
233
-    }
234
-
235
-    /**
236
-     * @param $code
237
-     *
238
-     * @return bool
239
-     *
240
-     * @throws \Psr\Container\NotFoundExceptionInterface
241
-     */
242
-    public function getCategory($code)
243
-    {
244
-        if ($categoriesURL = $this->getItemCategoriesURL()) {
245
-            $client = $this->getClient();
246
-            $errors = [];
247
-            $data = [
248
-                'code' => $code,
249
-            ];
250
-            if ($result = $client->get($categoriesURL, $data)) {
251
-                if (count($result['_embedded']['fx:item_categories']) > 0) {
252
-                    $category = $result['_embedded']['fx:item_categories'][0]['_links']['self']['href'];
253
-
254
-                    return $category;
255
-                }
256
-                $errors = array_merge($errors, $client->getErrors($result));
257
-                if (count($errors)) {
258
-                    Injector::inst()->get(LoggerInterface::class)->error('getCategory errors - '.json_encode($errors));
259
-                }
260
-            }
261
-        }
262
-
263
-        return false;
264
-    }
265
-
266
-    /**
267
-     * @param array $data
268
-     *
269
-     * @throws \Psr\Container\NotFoundExceptionInterface
270
-     */
271
-    public function putCategory($data = [])
272
-    {
273
-        $client = $this->getClient();
274
-        $errors = [];
275
-
276
-        if ($client) {
277
-            if ($category = $this->getCategory($data['code'])) {
278
-                $result = $client->patch($category, $data);
279
-            } else {
280
-                $result = $client->post($this->getItemCategoriesURL(), $data);
281
-            }
282
-            $errors = array_merge($errors, $client->getErrors($result));
283
-            if (count($errors)) {
284
-                Injector::inst()->get(LoggerInterface::class)->error('putCategory errors - '.json_encode($errors));
285
-            }
286
-        }
287
-    }
288
-
289
-    /**
290
-     * @param array $data
291
-     *
292
-     * @throws \Psr\Container\NotFoundExceptionInterface
293
-     */
294
-    public function deleteCategory($data = [])
295
-    {
296
-        $client = $this->getClient();
297
-        $errors = [];
298
-
299
-        if ($category = $this->getCategory($data['code'])) {
300
-            $result = $client->delete($category);
301
-
302
-            $errors = array_merge($errors, $client->getErrors($result));
303
-            if (count($errors)) {
304
-                Injector::inst()->get(LoggerInterface::class)->error('deleteCategory errors - '.json_encode($errors));
305
-            }
306
-        }
307
-    }
70
+		$fc = new FoxyClient($guzzle, $config);
71
+
72
+		$this->setClient($fc);
73
+		$this->setCurrentStore();
74
+		$this->setItemCategoriesURL();
75
+		$this->setItemCategories();
76
+	}
77
+
78
+	/**
79
+	 * @return mixed
80
+	 */
81
+	public function getClient()
82
+	{
83
+		return $this->client;
84
+	}
85
+
86
+	/**
87
+	 * @param $client
88
+	 *
89
+	 * @return $this
90
+	 */
91
+	public function setClient($client)
92
+	{
93
+		$this->client = $client;
94
+
95
+		return $this;
96
+	}
97
+
98
+	/**
99
+	 * @return bool
100
+	 * @throws \SilverStripe\ORM\ValidationException
101
+	 */
102
+	public static function is_valid()
103
+	{
104
+		$config = FoxyStripeSetting::current_foxystripe_setting();
105
+		return $config->EnableAPI &&
106
+			$config->client_id &&
107
+			$config->client_secret &&
108
+			$config->refresh_token &&
109
+			$config->access_token;
110
+	}
111
+
112
+	/**
113
+	 * @return mixed
114
+	 */
115
+	public function getCurrentStore()
116
+	{
117
+		return $this->current_store;
118
+	}
119
+
120
+	/**
121
+	 * @throws \SilverStripe\ORM\ValidationException
122
+	 */
123
+	public function setCurrentStore()
124
+	{
125
+		$client = $this->getClient();
126
+		$config = FoxyStripeSetting::current_foxystripe_setting();
127
+
128
+		$errors = array();
129
+		$data = array(
130
+			'store_domain' => $config->StoreName,
131
+		);
132
+
133
+		if ($client && $result = $client->get()) {
134
+			$errors = array_merge($errors, $client->getErrors($result));
135
+			if ($reporting_uri = $client->getLink('fx:reporting')) {
136
+				$errors = array_merge($errors, $client->getErrors($reporting_uri));
137
+				if ($result = $client->get($reporting_uri)) {
138
+					$errors = array_merge($errors, $client->getErrors($result));
139
+					if ($store_exists_uri = $client->getLink('fx:reporting_store_domain_exists')) {
140
+						$errors = array_merge($errors, $client->getErrors($store_exists_uri));
141
+						if ($result = $client->get($store_exists_uri, $data)) {
142
+							$errors = array_merge($errors, $client->getErrors($result));
143
+							if ($store = $client->getLink('fx:store')) {
144
+								$errors = array_merge($errors, $client->getErrors($store));
145
+								$this->current_store = $store;
146
+							}
147
+						}
148
+					}
149
+				}
150
+			}
151
+			if (count($errors)) {
152
+				Injector::inst()->get(LoggerInterface::class)->error('setCurrentStore errors - '.json_encode($errors));
153
+			}
154
+		}
155
+	}
156
+
157
+	/**
158
+	 * @param array $data
159
+	 *
160
+	 * @throws \Psr\Container\NotFoundExceptionInterface
161
+	 */
162
+	public function updateStore($data = [])
163
+	{
164
+		$client = $this->getClient();
165
+		$errors = [];
166
+
167
+		$result = $client->patch($this->getCurrentStore(), $data);
168
+
169
+		$errors = array_merge($errors, $client->getErrors($result));
170
+		if (count($errors)) {
171
+			Injector::inst()->get(LoggerInterface::class)->error('updateStore errors - '.json_encode($errors));
172
+		}
173
+	}
174
+
175
+	/**
176
+	 * @return mixed
177
+	 */
178
+	public function getItemCategoriesURL()
179
+	{
180
+		return $this->item_categories_url;
181
+	}
182
+
183
+	/**
184
+	 * @throws \Psr\Container\NotFoundExceptionInterface
185
+	 */
186
+	public function setItemCategoriesURL()
187
+	{
188
+		$client = $this->getClient();
189
+		$errors = [];
190
+
191
+		if ($client) {
192
+			$result = $client->get($this->getCurrentStore());
193
+
194
+			if (isset($result['_links']['fx:item_categories']['href'])) {
195
+				$this->item_categories_url = $result['_links']['fx:item_categories']['href'];
196
+			}
197
+
198
+			$errors = array_merge($errors, $client->getErrors($result));
199
+			if (count($errors)) {
200
+				Injector::inst()
201
+					->get(LoggerInterface::class)->error('setItemCategoriesURL errors - '.json_encode($errors));
202
+			}
203
+		}
204
+	}
205
+
206
+	/**
207
+	 * @return mixed
208
+	 */
209
+	public function getItemCategories()
210
+	{
211
+		return $this->item_categories;
212
+	}
213
+
214
+	/**
215
+	 * @throws \Psr\Container\NotFoundExceptionInterface
216
+	 */
217
+	public function setItemCategories()
218
+	{
219
+		$client = $this->getClient();
220
+		$errors = [];
221
+
222
+		if ($client) {
223
+			$result = $client->get($this->getItemCategoriesURL());
224
+
225
+			$this->item_categories = $result;
226
+
227
+			$errors = array_merge($errors, $client->getErrors($result));
228
+			if (count($errors)) {
229
+				Injector::inst()
230
+					->get(LoggerInterface::class)->error('setItemCategories errors - '.json_encode($errors));
231
+			}
232
+		}
233
+	}
234
+
235
+	/**
236
+	 * @param $code
237
+	 *
238
+	 * @return bool
239
+	 *
240
+	 * @throws \Psr\Container\NotFoundExceptionInterface
241
+	 */
242
+	public function getCategory($code)
243
+	{
244
+		if ($categoriesURL = $this->getItemCategoriesURL()) {
245
+			$client = $this->getClient();
246
+			$errors = [];
247
+			$data = [
248
+				'code' => $code,
249
+			];
250
+			if ($result = $client->get($categoriesURL, $data)) {
251
+				if (count($result['_embedded']['fx:item_categories']) > 0) {
252
+					$category = $result['_embedded']['fx:item_categories'][0]['_links']['self']['href'];
253
+
254
+					return $category;
255
+				}
256
+				$errors = array_merge($errors, $client->getErrors($result));
257
+				if (count($errors)) {
258
+					Injector::inst()->get(LoggerInterface::class)->error('getCategory errors - '.json_encode($errors));
259
+				}
260
+			}
261
+		}
262
+
263
+		return false;
264
+	}
265
+
266
+	/**
267
+	 * @param array $data
268
+	 *
269
+	 * @throws \Psr\Container\NotFoundExceptionInterface
270
+	 */
271
+	public function putCategory($data = [])
272
+	{
273
+		$client = $this->getClient();
274
+		$errors = [];
275
+
276
+		if ($client) {
277
+			if ($category = $this->getCategory($data['code'])) {
278
+				$result = $client->patch($category, $data);
279
+			} else {
280
+				$result = $client->post($this->getItemCategoriesURL(), $data);
281
+			}
282
+			$errors = array_merge($errors, $client->getErrors($result));
283
+			if (count($errors)) {
284
+				Injector::inst()->get(LoggerInterface::class)->error('putCategory errors - '.json_encode($errors));
285
+			}
286
+		}
287
+	}
288
+
289
+	/**
290
+	 * @param array $data
291
+	 *
292
+	 * @throws \Psr\Container\NotFoundExceptionInterface
293
+	 */
294
+	public function deleteCategory($data = [])
295
+	{
296
+		$client = $this->getClient();
297
+		$errors = [];
298
+
299
+		if ($category = $this->getCategory($data['code'])) {
300
+			$result = $client->delete($category);
301
+
302
+			$errors = array_merge($errors, $client->getErrors($result));
303
+			if (count($errors)) {
304
+				Injector::inst()->get(LoggerInterface::class)->error('deleteCategory errors - '.json_encode($errors));
305
+			}
306
+		}
307
+	}
308 308
 }
Please login to merge, or discard this patch.
src/Model/foxycart.cart_validation.php 2 patches
Spacing   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
 
160 160
         if ($output) {
161 161
             echo self::$cart_url.'?'.$qs;
162
-        } else {
162
+        }else {
163 163
             return self::$cart_url.'?'.$qs;
164 164
         }
165 165
     }
@@ -183,18 +183,18 @@  discard block
 block discarded – undo
183 183
         if ($option_value == '--OPEN--') {
184 184
             $hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
185 185
             $value = ($urlencode) ? urlencode($option_name).'||'.$hash.'||open' : $option_name.'||'.$hash.'||open';
186
-        } else {
186
+        }else {
187 187
             $hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
188 188
             if ($method == 'name') {
189 189
                 $value = ($urlencode) ? urlencode($option_name).'||'.$hash : $option_name.'||'.$hash;
190
-            } else {
190
+            }else {
191 191
                 $value = ($urlencode) ? urlencode($option_value).'||'.$hash : $option_value.'||'.$hash;
192 192
             }
193 193
         }
194 194
 
195 195
         if ($output) {
196 196
             echo $value;
197
-        } else {
197
+        }else {
198 198
             return $value;
199 199
         }
200 200
     }
@@ -322,7 +322,7 @@  discard block
 block discarded – undo
322 322
                                 .preg_quote($value[2]).'\1%', '${1}'
323 323
                                 .self::fc_hash_value($code, $name[2], $value[2], 'value', false)
324 324
                                 .'$1', $input);
325
-                        } else {
325
+                        }else {
326 326
                             $input_signed = preg_replace('%([\'"])'.$prefix.preg_quote($name[2])
327 327
                                 .'\1%', '${1}'.$prefix
328 328
                                 .self::fc_hash_value($code, $name[2], $value[2], 'name', false)
Please login to merge, or discard this patch.
Indentation   +417 added lines, -417 removed lines patch added patch discarded remove patch
@@ -21,12 +21,12 @@  discard block
 block discarded – undo
21 21
  */
22 22
 class FoxyCart_Helper
23 23
 {
24
-    /**
25
-     * API Key (Secret).
26
-     *
27
-     * @var string
28
-     **/
29
-    private static $secret;
24
+	/**
25
+	 * API Key (Secret).
26
+	 *
27
+	 * @var string
28
+	 **/
29
+	private static $secret;
30 30
 
31 31
 /**
32 32
  * Cart URL.
@@ -34,416 +34,416 @@  discard block
 block discarded – undo
34 34
  * @var string
35 35
  *             Notes: Could be 'https://yourdomain.foxycart.com/cart' or 'https://secure.yourdomain.com/cart'
36 36
  **/
37
-    // protected static $cart_url = 'https://yourdomain.foxycart.com/cart';
38
-    protected static $cart_url;
39
-
40
-    public static function setCartURL($storeName = null)
41
-    {
42
-        self::$cart_url = 'https://'.$storeName.'.faxycart.com/cart';
43
-    }
44
-
45
-    public static function setSecret($secret = null)
46
-    {
47
-        self::$secret = $secret;
48
-    }
49
-
50
-    public function __construct()
51
-    {
52
-        self::setCartURL(FoxyCart::getFoxyCartStoreName());
53
-        self::setSecret(FoxyCart::getStoreKey());
54
-    }
55
-
56
-    public static function getSecret()
57
-    {
58
-        return FoxyCart::getStoreKey();
59
-    }
60
-
61
-    /**
62
-     * Cart Excludes.
63
-     *
64
-     * Arrays of values and prefixes that should be ignored when signing links and forms.
65
-     *
66
-     * @var array
67
-     */
68
-    protected static $cart_excludes = array(
69
-        // Cart values
70
-        'cart', 'fcsid', 'empty', 'coupon', 'output', 'sub_token', 'redirect', 'callback', '_',
71
-        // Checkout pre-population values
72
-        'customer_email', 'customer_first_name', 'customer_last_name', 'customer_address1', 'customer_address2',
73
-        'customer_city', 'customer_state', 'customer_postal_code', 'customer_country', 'customer_phone',
74
-        'customer_company', 'shipping_first_name', 'shipping_last_name', 'shipping_address1', 'shipping_address2',
75
-        'shipping_city', 'shipping_state', 'shipping_postal_code', 'shipping_country', 'shipping_phone',
76
-        'shipping_company',
77
-    );
78
-    protected static $cart_excludes_prefixes = array(
79
-        'h:', 'x:', '__',
80
-    );
81
-
82
-    /**
83
-     * Debugging.
84
-     *
85
-     * Set to $debug to TRUE to enable debug logging.
86
-     */
87
-    protected static $debug = false;
88
-    protected static $log = array();
89
-
90
-    /**
91
-     * "Link Method": Generate HMAC SHA256 for GET Query Strings.
92
-     *
93
-     * Notes: Can't parse_str because PHP doesn't support non-alphanumeric characters as array keys.
94
-     *
95
-     * @return string
96
-     **/
97
-    public static function fc_hash_querystring($qs, $output = true)
98
-    {
99
-        self::$log[] = '<strong>Signing link</strong> with data: '
100
-            .htmlspecialchars(substr($qs, 0, 150)).'...';
101
-        $fail = self::$cart_url.'?'.$qs;
102
-
103
-        // If the link appears to be hashed already, don't bother
104
-        if (strpos($qs, '||')) {
105
-            self::$log[] = '<strong>Link appears to be signed already</strong>: '.htmlspecialchars($code[0]);
106
-
107
-            return $fail;
108
-        }
109
-
110
-        // Stick an ampersand on the beginning of the querystring to make matching the first element a little easier
111
-        $qs = '&'.urldecode($qs);
112
-
113
-        // Get all the prefixes, codes, and name=value pairs
114
-        preg_match_all(
115
-            '%(?P<amp>&(?:amp;)?)(?P<prefix>[a-z0-9]{1,3}:)?(?P<name>[^=]+)=(?P<value>[^&]+)%',
116
-            $qs,
117
-            $pairs,
118
-            PREG_SET_ORDER
119
-        );
120
-        self::$log[] = 'Found the following pairs to sign:<pre>'.htmlspecialchars(print_r($pairs, true)).'</pre>';
121
-
122
-        // Get all the "code" values, set the matches in $codes
123
-        $codes = array();
124
-        foreach ($pairs as $pair) {
125
-            if ($pair['name'] == 'code') {
126
-                $codes[$pair['prefix']] = $pair['value'];
127
-            }
128
-        }
129
-        if (!count($codes)) {
130
-            self::$log[] = '<strong style="color:#600;">No code found</strong> for the above link.';
131
-
132
-            return $fail;
133
-        }
134
-        self::$log[] = '<strong style="color:orange;">CODES found:</strong> '
135
-            .htmlspecialchars(print_r($codes, true));
136
-
137
-        // Sign the name/value pairs
138
-        foreach ($pairs as $pair) {
139
-            // Skip the cart excludes
140
-            if (in_array($pair['name'], self::$cart_excludes)
141
-                || in_array($pair['prefix'], self::$cart_excludes_prefixes)) {
142
-                self::$log[] = '<strong style="color:purple;">Skipping</strong> the reserved parameter or prefix "'
143
-                    .$pair['prefix'].$pair['name'].'" = '.$pair['value'];
144
-                continue;
145
-            }
146
-
147
-            // Continue to sign the value and replace the name=value in the querystring with name=value||hash
148
-            $value = self::fc_hash_value(
149
-                $codes[$pair['prefix']],
150
-                $pair['name'],
151
-                $pair['value'],
152
-                'value',
153
-                false,
154
-                'urlencode'
155
-            );
156
-            $replacement = $pair['amp'].$pair['prefix'].urlencode($pair['name']).'='.$value;
157
-            $qs = str_replace($pair[0], $replacement, $qs);
158
-            self::$log[] = 'Signed <strong>'.$pair['name'].'</strong> = <strong>'.$pair['value'].'</strong> with '
159
-                .$replacement.'.<br />Replacing: '.$pair[0].'<br />With... '.$replacement;
160
-        }
161
-        $qs = ltrim($qs, '&'); // Get rid of that leading ampersand we added earlier
162
-
163
-        if ($output) {
164
-            echo self::$cart_url.'?'.$qs;
165
-        } else {
166
-            return self::$cart_url.'?'.$qs;
167
-        }
168
-    }
169
-
170
-    /**
171
-     * "Form Method": Generate HMAC SHA256 for form elements or individual <input />s.
172
-     *
173
-     * @return string
174
-     **/
175
-    public static function fc_hash_value(
176
-        $product_code,
177
-        $option_name,
178
-        $option_value = '',
179
-        $method = 'name',
180
-        $output = true,
181
-        $urlencode = false
182
-    ) {
183
-        if (!$product_code || !$option_name) {
184
-            return false;
185
-        }
186
-        if ($option_value == '--OPEN--') {
187
-            $hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
188
-            $value = ($urlencode) ? urlencode($option_name).'||'.$hash.'||open' : $option_name.'||'.$hash.'||open';
189
-        } else {
190
-            $hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
191
-            if ($method == 'name') {
192
-                $value = ($urlencode) ? urlencode($option_name).'||'.$hash : $option_name.'||'.$hash;
193
-            } else {
194
-                $value = ($urlencode) ? urlencode($option_value).'||'.$hash : $option_value.'||'.$hash;
195
-            }
196
-        }
197
-
198
-        if ($output) {
199
-            echo $value;
200
-        } else {
201
-            return $value;
202
-        }
203
-    }
204
-
205
-    /**
206
-     * Raw HTML Signing: Sign all links and form elements in a block of HTML.
207
-     *
208
-     * Accepts a string of HTML and signs all links and forms.
209
-     * Requires link 'href' and form 'action' attributes to use 'https' and not 'http'.
210
-     * Requires a 'code' to be set in every form.
211
-     *
212
-     * @return string
213
-     **/
214
-    public static function fc_hash_html($html)
215
-    {
216
-        // Initialize some counting
217
-        $count['temp'] = 0; // temp counter
218
-        $count['links'] = 0;
219
-        $count['forms'] = 0;
220
-        $count['inputs'] = 0;
221
-        $count['lists'] = 0;
222
-        $count['textareas'] = 0;
223
-
224
-        // Find and sign all the links
225
-        preg_match_all(
226
-            '%<a .*?href=[\'"]'.preg_quote(self::$cart_url).'(?:\.php)?\?(.+?)[\'"].*?>%i',
227
-            $html,
228
-            $querystrings
229
-        );
230
-        // print_r($querystrings);
231
-        foreach ($querystrings[1] as $querystring) {
232
-            // If it's already signed, skip it.
233
-            if (preg_match('%&(?:amp;)?hash=%i', $querystring)) {
234
-                continue;
235
-            }
236
-            $pattern = '%(href=[\'"])'.preg_quote(self::$cart_url, '%').'(?:\.php)?\?'
237
-                .preg_quote($querystring, '%').'([\'"])%i';
238
-            $signed = self::fc_hash_querystring($querystring, false);
239
-            $html = preg_replace($pattern, '$1'.$signed.'$2', $html, -1, $count['temp']);
240
-            $count['links'] += $count['temp'];
241
-        }
242
-        unset($querystrings);
243
-
244
-        // Find and sign all form values
245
-        preg_match_all(
246
-            '%<form [^>]*?action=[\'"]'.preg_quote(self::$cart_url).'?[\'"].*?>(.+?)</form>%is',
247
-            $html,
248
-            $forms
249
-        );
250
-        foreach ($forms[1] as $form) {
251
-            ++$count['forms'];
252
-            self::$log[] = '<strong>Signing form</strong> with data: '.htmlspecialchars(substr(
253
-                $form,
254
-                0,
255
-                150
256
-            )).'...';
257
-
258
-            // Store the original form so we can replace it when we're done
259
-            $form_original = $form;
260
-
261
-            // Check for the "code" input, set the matches in $codes
262
-            if (!preg_match_all(
263
-                '%<[^>]*?name=([\'"])([0-9]{1,3}:)?code\1[^>]*?>%i',
264
-                $form,
265
-                $codes,
266
-                PREG_SET_ORDER
267
-            )) {
268
-                self::$log[] = '<strong style="color:#600;">No code found</strong> for the above form.';
269
-                continue;
270
-            }
271
-            // For each code found, sign the appropriate inputs
272
-            foreach ($codes as $code) {
273
-                // If the form appears to be hashed already, don't bother
274
-                if (strpos($code[0], '||')) {
275
-                    self::$log[] = '<strong>Form appears to be signed already</strong>: '.htmlspecialchars($code[0]);
276
-                    continue;
277
-                }
278
-                // Get the code and the prefix
279
-                $prefix = (isset($code[2])) ? $code[2] : '';
280
-                preg_match('%<[^>]*?value=([\'"])(.+?)\1[^>]*?>%i', $code[0], $code);
281
-                $code = trim($code[2]);
282
-                self::$log[] = '<strong>Prefix for '.htmlspecialchars($code).'</strong>: '.htmlspecialchars($prefix);
283
-                if (!$code) { // If the code is empty, skip this form or specific prefixed elements
284
-                    continue;
285
-                }
286
-
287
-                // Sign all <input /> elements with matching prefix
288
-                preg_match_all(
289
-                    '%<input [^>]*?name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(?:.+?)\1[^>]*>%i',
290
-                    $form,
291
-                    $inputs
292
-                );
293
-                foreach ($inputs[0] as $input) {
294
-                    ++$count['inputs'];
295
-                    // Test to make sure both name and value attributes are found
296
-                    if (preg_match(
297
-                        '%name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1%i',
298
-                        $input,
299
-                        $name
300
-                    ) > 0) {
301
-                        preg_match('%value=([\'"])(.*?)\1%i', $input, $value);
302
-                        $value = (count($value) > 0) ? $value : array('', '', '');
303
-                        preg_match('%type=([\'"])(.*?)\1%i', $input, $type);
304
-                        $type = (count($type) > 0) ? $type : array('', '', '');
305
-                        // Skip the cart excludes
306
-                        if (in_array(
307
-                            $prefix.$name[2],
308
-                            self::$cart_excludes
309
-                        ) || in_array(substr(
310
-                            $prefix.$name[2],
311
-                            0,
312
-                            2
313
-                        ), self::$cart_excludes_prefixes)) {
314
-                            self::$log[] = '<strong style="color:purple;">Skipping</strong> 
37
+	// protected static $cart_url = 'https://yourdomain.foxycart.com/cart';
38
+	protected static $cart_url;
39
+
40
+	public static function setCartURL($storeName = null)
41
+	{
42
+		self::$cart_url = 'https://'.$storeName.'.faxycart.com/cart';
43
+	}
44
+
45
+	public static function setSecret($secret = null)
46
+	{
47
+		self::$secret = $secret;
48
+	}
49
+
50
+	public function __construct()
51
+	{
52
+		self::setCartURL(FoxyCart::getFoxyCartStoreName());
53
+		self::setSecret(FoxyCart::getStoreKey());
54
+	}
55
+
56
+	public static function getSecret()
57
+	{
58
+		return FoxyCart::getStoreKey();
59
+	}
60
+
61
+	/**
62
+	 * Cart Excludes.
63
+	 *
64
+	 * Arrays of values and prefixes that should be ignored when signing links and forms.
65
+	 *
66
+	 * @var array
67
+	 */
68
+	protected static $cart_excludes = array(
69
+		// Cart values
70
+		'cart', 'fcsid', 'empty', 'coupon', 'output', 'sub_token', 'redirect', 'callback', '_',
71
+		// Checkout pre-population values
72
+		'customer_email', 'customer_first_name', 'customer_last_name', 'customer_address1', 'customer_address2',
73
+		'customer_city', 'customer_state', 'customer_postal_code', 'customer_country', 'customer_phone',
74
+		'customer_company', 'shipping_first_name', 'shipping_last_name', 'shipping_address1', 'shipping_address2',
75
+		'shipping_city', 'shipping_state', 'shipping_postal_code', 'shipping_country', 'shipping_phone',
76
+		'shipping_company',
77
+	);
78
+	protected static $cart_excludes_prefixes = array(
79
+		'h:', 'x:', '__',
80
+	);
81
+
82
+	/**
83
+	 * Debugging.
84
+	 *
85
+	 * Set to $debug to TRUE to enable debug logging.
86
+	 */
87
+	protected static $debug = false;
88
+	protected static $log = array();
89
+
90
+	/**
91
+	 * "Link Method": Generate HMAC SHA256 for GET Query Strings.
92
+	 *
93
+	 * Notes: Can't parse_str because PHP doesn't support non-alphanumeric characters as array keys.
94
+	 *
95
+	 * @return string
96
+	 **/
97
+	public static function fc_hash_querystring($qs, $output = true)
98
+	{
99
+		self::$log[] = '<strong>Signing link</strong> with data: '
100
+			.htmlspecialchars(substr($qs, 0, 150)).'...';
101
+		$fail = self::$cart_url.'?'.$qs;
102
+
103
+		// If the link appears to be hashed already, don't bother
104
+		if (strpos($qs, '||')) {
105
+			self::$log[] = '<strong>Link appears to be signed already</strong>: '.htmlspecialchars($code[0]);
106
+
107
+			return $fail;
108
+		}
109
+
110
+		// Stick an ampersand on the beginning of the querystring to make matching the first element a little easier
111
+		$qs = '&'.urldecode($qs);
112
+
113
+		// Get all the prefixes, codes, and name=value pairs
114
+		preg_match_all(
115
+			'%(?P<amp>&(?:amp;)?)(?P<prefix>[a-z0-9]{1,3}:)?(?P<name>[^=]+)=(?P<value>[^&]+)%',
116
+			$qs,
117
+			$pairs,
118
+			PREG_SET_ORDER
119
+		);
120
+		self::$log[] = 'Found the following pairs to sign:<pre>'.htmlspecialchars(print_r($pairs, true)).'</pre>';
121
+
122
+		// Get all the "code" values, set the matches in $codes
123
+		$codes = array();
124
+		foreach ($pairs as $pair) {
125
+			if ($pair['name'] == 'code') {
126
+				$codes[$pair['prefix']] = $pair['value'];
127
+			}
128
+		}
129
+		if (!count($codes)) {
130
+			self::$log[] = '<strong style="color:#600;">No code found</strong> for the above link.';
131
+
132
+			return $fail;
133
+		}
134
+		self::$log[] = '<strong style="color:orange;">CODES found:</strong> '
135
+			.htmlspecialchars(print_r($codes, true));
136
+
137
+		// Sign the name/value pairs
138
+		foreach ($pairs as $pair) {
139
+			// Skip the cart excludes
140
+			if (in_array($pair['name'], self::$cart_excludes)
141
+				|| in_array($pair['prefix'], self::$cart_excludes_prefixes)) {
142
+				self::$log[] = '<strong style="color:purple;">Skipping</strong> the reserved parameter or prefix "'
143
+					.$pair['prefix'].$pair['name'].'" = '.$pair['value'];
144
+				continue;
145
+			}
146
+
147
+			// Continue to sign the value and replace the name=value in the querystring with name=value||hash
148
+			$value = self::fc_hash_value(
149
+				$codes[$pair['prefix']],
150
+				$pair['name'],
151
+				$pair['value'],
152
+				'value',
153
+				false,
154
+				'urlencode'
155
+			);
156
+			$replacement = $pair['amp'].$pair['prefix'].urlencode($pair['name']).'='.$value;
157
+			$qs = str_replace($pair[0], $replacement, $qs);
158
+			self::$log[] = 'Signed <strong>'.$pair['name'].'</strong> = <strong>'.$pair['value'].'</strong> with '
159
+				.$replacement.'.<br />Replacing: '.$pair[0].'<br />With... '.$replacement;
160
+		}
161
+		$qs = ltrim($qs, '&'); // Get rid of that leading ampersand we added earlier
162
+
163
+		if ($output) {
164
+			echo self::$cart_url.'?'.$qs;
165
+		} else {
166
+			return self::$cart_url.'?'.$qs;
167
+		}
168
+	}
169
+
170
+	/**
171
+	 * "Form Method": Generate HMAC SHA256 for form elements or individual <input />s.
172
+	 *
173
+	 * @return string
174
+	 **/
175
+	public static function fc_hash_value(
176
+		$product_code,
177
+		$option_name,
178
+		$option_value = '',
179
+		$method = 'name',
180
+		$output = true,
181
+		$urlencode = false
182
+	) {
183
+		if (!$product_code || !$option_name) {
184
+			return false;
185
+		}
186
+		if ($option_value == '--OPEN--') {
187
+			$hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
188
+			$value = ($urlencode) ? urlencode($option_name).'||'.$hash.'||open' : $option_name.'||'.$hash.'||open';
189
+		} else {
190
+			$hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
191
+			if ($method == 'name') {
192
+				$value = ($urlencode) ? urlencode($option_name).'||'.$hash : $option_name.'||'.$hash;
193
+			} else {
194
+				$value = ($urlencode) ? urlencode($option_value).'||'.$hash : $option_value.'||'.$hash;
195
+			}
196
+		}
197
+
198
+		if ($output) {
199
+			echo $value;
200
+		} else {
201
+			return $value;
202
+		}
203
+	}
204
+
205
+	/**
206
+	 * Raw HTML Signing: Sign all links and form elements in a block of HTML.
207
+	 *
208
+	 * Accepts a string of HTML and signs all links and forms.
209
+	 * Requires link 'href' and form 'action' attributes to use 'https' and not 'http'.
210
+	 * Requires a 'code' to be set in every form.
211
+	 *
212
+	 * @return string
213
+	 **/
214
+	public static function fc_hash_html($html)
215
+	{
216
+		// Initialize some counting
217
+		$count['temp'] = 0; // temp counter
218
+		$count['links'] = 0;
219
+		$count['forms'] = 0;
220
+		$count['inputs'] = 0;
221
+		$count['lists'] = 0;
222
+		$count['textareas'] = 0;
223
+
224
+		// Find and sign all the links
225
+		preg_match_all(
226
+			'%<a .*?href=[\'"]'.preg_quote(self::$cart_url).'(?:\.php)?\?(.+?)[\'"].*?>%i',
227
+			$html,
228
+			$querystrings
229
+		);
230
+		// print_r($querystrings);
231
+		foreach ($querystrings[1] as $querystring) {
232
+			// If it's already signed, skip it.
233
+			if (preg_match('%&(?:amp;)?hash=%i', $querystring)) {
234
+				continue;
235
+			}
236
+			$pattern = '%(href=[\'"])'.preg_quote(self::$cart_url, '%').'(?:\.php)?\?'
237
+				.preg_quote($querystring, '%').'([\'"])%i';
238
+			$signed = self::fc_hash_querystring($querystring, false);
239
+			$html = preg_replace($pattern, '$1'.$signed.'$2', $html, -1, $count['temp']);
240
+			$count['links'] += $count['temp'];
241
+		}
242
+		unset($querystrings);
243
+
244
+		// Find and sign all form values
245
+		preg_match_all(
246
+			'%<form [^>]*?action=[\'"]'.preg_quote(self::$cart_url).'?[\'"].*?>(.+?)</form>%is',
247
+			$html,
248
+			$forms
249
+		);
250
+		foreach ($forms[1] as $form) {
251
+			++$count['forms'];
252
+			self::$log[] = '<strong>Signing form</strong> with data: '.htmlspecialchars(substr(
253
+				$form,
254
+				0,
255
+				150
256
+			)).'...';
257
+
258
+			// Store the original form so we can replace it when we're done
259
+			$form_original = $form;
260
+
261
+			// Check for the "code" input, set the matches in $codes
262
+			if (!preg_match_all(
263
+				'%<[^>]*?name=([\'"])([0-9]{1,3}:)?code\1[^>]*?>%i',
264
+				$form,
265
+				$codes,
266
+				PREG_SET_ORDER
267
+			)) {
268
+				self::$log[] = '<strong style="color:#600;">No code found</strong> for the above form.';
269
+				continue;
270
+			}
271
+			// For each code found, sign the appropriate inputs
272
+			foreach ($codes as $code) {
273
+				// If the form appears to be hashed already, don't bother
274
+				if (strpos($code[0], '||')) {
275
+					self::$log[] = '<strong>Form appears to be signed already</strong>: '.htmlspecialchars($code[0]);
276
+					continue;
277
+				}
278
+				// Get the code and the prefix
279
+				$prefix = (isset($code[2])) ? $code[2] : '';
280
+				preg_match('%<[^>]*?value=([\'"])(.+?)\1[^>]*?>%i', $code[0], $code);
281
+				$code = trim($code[2]);
282
+				self::$log[] = '<strong>Prefix for '.htmlspecialchars($code).'</strong>: '.htmlspecialchars($prefix);
283
+				if (!$code) { // If the code is empty, skip this form or specific prefixed elements
284
+					continue;
285
+				}
286
+
287
+				// Sign all <input /> elements with matching prefix
288
+				preg_match_all(
289
+					'%<input [^>]*?name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(?:.+?)\1[^>]*>%i',
290
+					$form,
291
+					$inputs
292
+				);
293
+				foreach ($inputs[0] as $input) {
294
+					++$count['inputs'];
295
+					// Test to make sure both name and value attributes are found
296
+					if (preg_match(
297
+						'%name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1%i',
298
+						$input,
299
+						$name
300
+					) > 0) {
301
+						preg_match('%value=([\'"])(.*?)\1%i', $input, $value);
302
+						$value = (count($value) > 0) ? $value : array('', '', '');
303
+						preg_match('%type=([\'"])(.*?)\1%i', $input, $type);
304
+						$type = (count($type) > 0) ? $type : array('', '', '');
305
+						// Skip the cart excludes
306
+						if (in_array(
307
+							$prefix.$name[2],
308
+							self::$cart_excludes
309
+						) || in_array(substr(
310
+							$prefix.$name[2],
311
+							0,
312
+							2
313
+						), self::$cart_excludes_prefixes)) {
314
+							self::$log[] = '<strong style="color:purple;">Skipping</strong> 
315 315
                                 the reserved parameter or prefix "'.$prefix.$name[2].'" = '.$value[2];
316
-                            continue;
317
-                        }
318
-                        self::$log[] = '<strong>INPUT['.$type[2].']:</strong> Name: <strong>'
319
-                            .$prefix.htmlspecialchars(preg_quote($name[2])).'</strong>';
320
-                        self::$log[] = '<strong>Replacement Pattern:</strong> ([\'"])'
321
-                            .$prefix.preg_quote($name[2]).'\1';
322
-                        $value[2] = ($value[2] == '') ? '--OPEN--' : $value[2];
323
-                        if ($type[2] == 'radio') {
324
-                            $input_signed = preg_replace('%([\'"])'
325
-                                .preg_quote($value[2]).'\1%', '${1}'
326
-                                .self::fc_hash_value($code, $name[2], $value[2], 'value', false)
327
-                                .'$1', $input);
328
-                        } else {
329
-                            $input_signed = preg_replace('%([\'"])'.$prefix.preg_quote($name[2])
330
-                                .'\1%', '${1}'.$prefix
331
-                                .self::fc_hash_value($code, $name[2], $value[2], 'name', false)
332
-                                .'$1', $input);
333
-                        }
334
-                        self::$log[] = '<strong>INPUT:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
335
-                           '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$name[2]).
336
-                           '</strong> :: Value: <strong>'.htmlspecialchars($value[2]).
337
-                           '</strong><br />Initial input: '.htmlspecialchars($input).
338
-                           '<br />Signed: <span style="color:#060;">'.htmlspecialchars($input_signed).'</span>';
339
-                        $form = str_replace($input, $input_signed, $form);
340
-                    }
341
-                }
342
-                self::$log[] = '<strong>FORM after INPUTS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
343
-
344
-                // Sign all <option /> elements
345
-                preg_match_all(
346
-                    '%<select [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.+?)</select>%is',
347
-                    $form,
348
-                    $lists,
349
-                    PREG_SET_ORDER
350
-                );
351
-                foreach ($lists as $list) {
352
-                    ++$count['lists'];
353
-                    preg_match_all(
354
-                        '%<option [^>]*value=([\'"])(.+?)\1[^>]*>(?:.*?)</option>%i',
355
-                        $list[0],
356
-                        $options,
357
-                        PREG_SET_ORDER
358
-                    );
359
-                    self::$log[] = '<strong>Options:</strong> <pre>'.htmlspecialchars(print_r($options, true))
360
-                        .'</pre>';
361
-                    unset($form_part_signed);
362
-                    foreach ($options as $option) {
363
-                        if (!isset($form_part_signed)) {
364
-                            $form_part_signed = $list[0];
365
-                        }
366
-                        $option_signed = preg_replace(
367
-                            '%'.preg_quote($option[1]).preg_quote($option[2]).preg_quote($option[1]).'%',
368
-                            $option[1].self::fc_hash_value(
369
-                                $code,
370
-                                $list[2],
371
-                                $option[2],
372
-                                'value',
373
-                                false
374
-                            ).$option[1],
375
-                            $option[0]
376
-                        );
377
-                        $form_part_signed = str_replace($option[0], $option_signed, $form_part_signed);
378
-                        self::$log[] = '<strong>OPTION:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
379
-                           '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$list[2]).
380
-                           '</strong> :: Value: <strong>'.htmlspecialchars($option[2]).
381
-                           '</strong><br />Initial option: '.htmlspecialchars($option[0]).
382
-                           '<br />Signed: <span style="color:#060;">'.htmlspecialchars($option_signed).'</span>';
383
-                    }
384
-                    $form = str_replace($list[0], $form_part_signed, $form);
385
-                }
386
-                self::$log[] = '<strong>FORM after OPTIONS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
387
-
388
-                // Sign all <textarea /> elements
389
-                preg_match_all(
390
-                    '%<textarea [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.*?)</textarea>%is',
391
-                    $form,
392
-                    $textareas,
393
-                    PREG_SET_ORDER
394
-                );
395
-                // echo "\n\nTextareas: ".print_r($textareas, true);
396
-                foreach ($textareas as $textarea) {
397
-                    ++$count['textareas'];
398
-                    // Tackle implied "--OPEN--" first, if textarea is empty
399
-                    $textarea[3] = ($textarea[3] == '') ? '--OPEN--' : $textarea[3];
400
-                    $textarea_signed = preg_replace(
401
-                        '%([\'"])'.preg_quote($prefix.$textarea[2]).'\1%',
402
-                        '$1'.self::fc_hash_value(
403
-                            $code,
404
-                            $textarea[2],
405
-                            $textarea[3],
406
-                            'name',
407
-                            false
408
-                        ).'$1',
409
-                        $textarea[0]
410
-                    );
411
-                    $form = str_replace($textarea[0], $textarea_signed, $form);
412
-                    self::$log[] = '<strong>TEXTAREA:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
413
-                       '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$textarea[2]).
414
-                       '</strong> :: Value: <strong>'.htmlspecialchars($textarea[3]).
415
-                       '</strong><br />Initial textarea: '.htmlspecialchars($textarea[0]).
416
-                       '<br />Signed: <span style="color:#060;">'.htmlspecialchars($textarea_signed).'</span>';
417
-                }
418
-                self::$log[] = '<strong>FORM after TEXTAREAS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
419
-
420
-                // Exclude all <button> elements
421
-                $form = preg_replace(
422
-                    '%<button ([^>]*)name=([\'"])(.*?)\1([^>]*>.*?</button>)%i',
423
-                    '<button $1name=$2x:$3$4',
424
-                    $form
425
-                );
426
-            }
427
-            // Replace the entire form
428
-            self::$log[] = '<strong>FORM after ALL:</strong> <pre>'.htmlspecialchars($form).'</pre>'
429
-                .'replacing <pre>'.htmlspecialchars($form_original).'</pre>';
430
-            $html = str_replace($form_original, $form, $html);
431
-            self::$log[] = '<strong>FORM end</strong><hr />';
432
-        }
433
-
434
-        // Return the signed output
435
-        $output = '';
436
-        if (self::$debug) {
437
-            self::$log['Summary'] = $count['links'].' links signed. '.$count['forms'].' forms signed. '
438
-                .$count['inputs'].' inputs signed. '.$count['lists'].' lists signed. '.$count['textareas']
439
-                .' textareas signed.';
440
-            $output .= '<h3>FoxyCart HMAC Debugging:</h3><ul>';
441
-            foreach (self::$log as $name => $value) {
442
-                $output .= '<li><strong>'.$name.':</strong> '.$value.'</li>';
443
-            }
444
-            $output .= '</ul><hr />';
445
-        }
446
-
447
-        return $output.$html;
448
-    }
316
+							continue;
317
+						}
318
+						self::$log[] = '<strong>INPUT['.$type[2].']:</strong> Name: <strong>'
319
+							.$prefix.htmlspecialchars(preg_quote($name[2])).'</strong>';
320
+						self::$log[] = '<strong>Replacement Pattern:</strong> ([\'"])'
321
+							.$prefix.preg_quote($name[2]).'\1';
322
+						$value[2] = ($value[2] == '') ? '--OPEN--' : $value[2];
323
+						if ($type[2] == 'radio') {
324
+							$input_signed = preg_replace('%([\'"])'
325
+								.preg_quote($value[2]).'\1%', '${1}'
326
+								.self::fc_hash_value($code, $name[2], $value[2], 'value', false)
327
+								.'$1', $input);
328
+						} else {
329
+							$input_signed = preg_replace('%([\'"])'.$prefix.preg_quote($name[2])
330
+								.'\1%', '${1}'.$prefix
331
+								.self::fc_hash_value($code, $name[2], $value[2], 'name', false)
332
+								.'$1', $input);
333
+						}
334
+						self::$log[] = '<strong>INPUT:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
335
+						   '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$name[2]).
336
+						   '</strong> :: Value: <strong>'.htmlspecialchars($value[2]).
337
+						   '</strong><br />Initial input: '.htmlspecialchars($input).
338
+						   '<br />Signed: <span style="color:#060;">'.htmlspecialchars($input_signed).'</span>';
339
+						$form = str_replace($input, $input_signed, $form);
340
+					}
341
+				}
342
+				self::$log[] = '<strong>FORM after INPUTS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
343
+
344
+				// Sign all <option /> elements
345
+				preg_match_all(
346
+					'%<select [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.+?)</select>%is',
347
+					$form,
348
+					$lists,
349
+					PREG_SET_ORDER
350
+				);
351
+				foreach ($lists as $list) {
352
+					++$count['lists'];
353
+					preg_match_all(
354
+						'%<option [^>]*value=([\'"])(.+?)\1[^>]*>(?:.*?)</option>%i',
355
+						$list[0],
356
+						$options,
357
+						PREG_SET_ORDER
358
+					);
359
+					self::$log[] = '<strong>Options:</strong> <pre>'.htmlspecialchars(print_r($options, true))
360
+						.'</pre>';
361
+					unset($form_part_signed);
362
+					foreach ($options as $option) {
363
+						if (!isset($form_part_signed)) {
364
+							$form_part_signed = $list[0];
365
+						}
366
+						$option_signed = preg_replace(
367
+							'%'.preg_quote($option[1]).preg_quote($option[2]).preg_quote($option[1]).'%',
368
+							$option[1].self::fc_hash_value(
369
+								$code,
370
+								$list[2],
371
+								$option[2],
372
+								'value',
373
+								false
374
+							).$option[1],
375
+							$option[0]
376
+						);
377
+						$form_part_signed = str_replace($option[0], $option_signed, $form_part_signed);
378
+						self::$log[] = '<strong>OPTION:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
379
+						   '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$list[2]).
380
+						   '</strong> :: Value: <strong>'.htmlspecialchars($option[2]).
381
+						   '</strong><br />Initial option: '.htmlspecialchars($option[0]).
382
+						   '<br />Signed: <span style="color:#060;">'.htmlspecialchars($option_signed).'</span>';
383
+					}
384
+					$form = str_replace($list[0], $form_part_signed, $form);
385
+				}
386
+				self::$log[] = '<strong>FORM after OPTIONS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
387
+
388
+				// Sign all <textarea /> elements
389
+				preg_match_all(
390
+					'%<textarea [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.*?)</textarea>%is',
391
+					$form,
392
+					$textareas,
393
+					PREG_SET_ORDER
394
+				);
395
+				// echo "\n\nTextareas: ".print_r($textareas, true);
396
+				foreach ($textareas as $textarea) {
397
+					++$count['textareas'];
398
+					// Tackle implied "--OPEN--" first, if textarea is empty
399
+					$textarea[3] = ($textarea[3] == '') ? '--OPEN--' : $textarea[3];
400
+					$textarea_signed = preg_replace(
401
+						'%([\'"])'.preg_quote($prefix.$textarea[2]).'\1%',
402
+						'$1'.self::fc_hash_value(
403
+							$code,
404
+							$textarea[2],
405
+							$textarea[3],
406
+							'name',
407
+							false
408
+						).'$1',
409
+						$textarea[0]
410
+					);
411
+					$form = str_replace($textarea[0], $textarea_signed, $form);
412
+					self::$log[] = '<strong>TEXTAREA:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
413
+					   '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$textarea[2]).
414
+					   '</strong> :: Value: <strong>'.htmlspecialchars($textarea[3]).
415
+					   '</strong><br />Initial textarea: '.htmlspecialchars($textarea[0]).
416
+					   '<br />Signed: <span style="color:#060;">'.htmlspecialchars($textarea_signed).'</span>';
417
+				}
418
+				self::$log[] = '<strong>FORM after TEXTAREAS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
419
+
420
+				// Exclude all <button> elements
421
+				$form = preg_replace(
422
+					'%<button ([^>]*)name=([\'"])(.*?)\1([^>]*>.*?</button>)%i',
423
+					'<button $1name=$2x:$3$4',
424
+					$form
425
+				);
426
+			}
427
+			// Replace the entire form
428
+			self::$log[] = '<strong>FORM after ALL:</strong> <pre>'.htmlspecialchars($form).'</pre>'
429
+				.'replacing <pre>'.htmlspecialchars($form_original).'</pre>';
430
+			$html = str_replace($form_original, $form, $html);
431
+			self::$log[] = '<strong>FORM end</strong><hr />';
432
+		}
433
+
434
+		// Return the signed output
435
+		$output = '';
436
+		if (self::$debug) {
437
+			self::$log['Summary'] = $count['links'].' links signed. '.$count['forms'].' forms signed. '
438
+				.$count['inputs'].' inputs signed. '.$count['lists'].' lists signed. '.$count['textareas']
439
+				.' textareas signed.';
440
+			$output .= '<h3>FoxyCart HMAC Debugging:</h3><ul>';
441
+			foreach (self::$log as $name => $value) {
442
+				$output .= '<li><strong>'.$name.':</strong> '.$value.'</li>';
443
+			}
444
+			$output .= '</ul><hr />';
445
+		}
446
+
447
+		return $output.$html;
448
+	}
449 449
 }
Please login to merge, or discard this patch.
src/Admin/FoxyStripeAdmin.php 2 patches
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -88,7 +88,7 @@  discard block
 block discarded – undo
88 88
         // Retrieve validator, if one has been setup (e.g. via data extensions).
89 89
         if ($config->hasMethod('getCMSValidator')) {
90 90
             $validator = $config->getCMSValidator();
91
-        } else {
91
+        }else {
92 92
             $validator = null;
93 93
         }
94 94
 
@@ -101,13 +101,13 @@  discard block
 block discarded – undo
101 101
             $actions,
102 102
             $validator
103 103
         )->setHTMLID('Form_EditForm');
104
-        $form->setValidationResponseCallback(function (ValidationResult $errors) use ($negotiator, $form) {
104
+        $form->setValidationResponseCallback(function(ValidationResult $errors) use ($negotiator, $form) {
105 105
             $request = $this->getRequest();
106 106
             if ($request->isAjax() && $negotiator) {
107 107
                 $result = $form->forTemplate();
108 108
 
109 109
                 return $negotiator->respond($request, array(
110
-                    'CurrentForm' => function () use ($result) {
110
+                    'CurrentForm' => function() use ($result) {
111 111
                         return $result;
112 112
                     },
113 113
                 ));
Please login to merge, or discard this patch.
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -18,163 +18,163 @@
 block discarded – undo
18 18
 
19 19
 class FoxyStripeAdmin extends LeftAndMain
20 20
 {
21
-    /**
22
-     * @var string
23
-     */
24
-    private static $url_segment = 'foxystripe';
25
-
26
-    /**
27
-     * @var string
28
-     */
29
-    private static $url_rule = '/$Action/$ID/$OtherID';
30
-
31
-    /**
32
-     * @var int
33
-     */
34
-    private static $menu_priority = 4;
35
-
36
-    /**
37
-     * @var string
38
-     */
39
-    private static $menu_title = 'FoxyStripe';
40
-
41
-    /**
42
-     * @var string
43
-     */
44
-    private static $menu_icon_class = 'font-icon-cog';
45
-
46
-    /**
47
-     * @var string
48
-     */
49
-    private static $tree_class = FoxyStripeSetting::class;
50
-
51
-    /**
52
-     * @var array
53
-     */
54
-    private static $required_permission_codes = ['EDIT_GLOBAL_PERMISSION'];
55
-
56
-    /**
57
-     * Initialises the {@link FoxyStripeSetting} controller.
58
-     */
59
-    public function init()
60
-    {
61
-        parent::init();
62
-
63
-        Requirements::javascript('silverstripe/cms: client/dist/js/bundle.js');
64
-    }
65
-
66
-    /**
67
-     * @param null $id
68
-     * @param null $fields
69
-     *
70
-     * @return $this|Form
71
-     */
72
-    public function getEditForm($id = null, $fields = null)
73
-    {
74
-        $config = FoxyStripeSetting::current_foxystripe_setting();
75
-        $fields = $config->getCMSFields();
76
-
77
-        // Tell the CMS what URL the preview should show
78
-        $home = Director::absoluteBaseURL();
79
-        $fields->push(new HiddenField('PreviewURL', 'Preview URL', $home));
80
-
81
-        // Added in-line to the form, but plucked into different view by LeftAndMain.Preview.js upon load
82
-        $fields->push($navField = new LiteralField(
83
-            'SilverStripeNavigator',
84
-            $this->getSilverStripeNavigator()
85
-        ));
86
-        $navField->setAllowHTML(true);
87
-
88
-        // Retrieve validator, if one has been setup (e.g. via data extensions).
89
-        if ($config->hasMethod('getCMSValidator')) {
90
-            $validator = $config->getCMSValidator();
91
-        } else {
92
-            $validator = null;
93
-        }
94
-
95
-        $actions = $config->getCMSActions();
96
-        $negotiator = $this->getResponseNegotiator();
97
-        $form = Form::create(
98
-            $this,
99
-            'EditForm',
100
-            $fields,
101
-            $actions,
102
-            $validator
103
-        )->setHTMLID('Form_EditForm');
104
-        $form->setValidationResponseCallback(function (ValidationResult $errors) use ($negotiator, $form) {
105
-            $request = $this->getRequest();
106
-            if ($request->isAjax() && $negotiator) {
107
-                $result = $form->forTemplate();
108
-
109
-                return $negotiator->respond($request, array(
110
-                    'CurrentForm' => function () use ($result) {
111
-                        return $result;
112
-                    },
113
-                ));
114
-            }
115
-            return null;
116
-        });
117
-        $form->addExtraClass('flexbox-area-grow fill-height cms-content cms-edit-form');
118
-        $form->setAttribute('data-pjax-fragment', 'CurrentForm');
119
-
120
-        if ($form->Fields()->hasTabSet()) {
121
-            $form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet');
122
-        }
123
-        $form->setHTMLID('Form_EditForm');
124
-        $form->loadDataFrom($config);
125
-        $form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
126
-
127
-        // Use <button> to allow full jQuery UI styling
128
-        $actions = $actions->dataFields();
129
-        if ($actions) {
130
-            /** @var FormAction $action */
131
-            foreach ($actions as $action) {
132
-                $action->setUseButtonTag(true);
133
-            }
134
-        }
135
-
136
-        $this->extend('updateEditForm', $form);
137
-
138
-        return $form;
139
-    }
140
-
141
-    /**
142
-     * Save the current sites {@link FoxyStripeSetting} into the database.
143
-     *
144
-     * @param $data
145
-     * @param $form
146
-     *
147
-     * @return \SilverStripe\Control\HTTPResponse
148
-     * @throws \SilverStripe\Control\HTTPResponse_Exception
149
-     */
150
-    public function save_foxystripe_setting($data, $form)
151
-    {
152
-        $config = FoxyStripeSetting::current_foxystripe_setting();
153
-        $form->saveInto($config);
154
-        try {
155
-            $config->write();
156
-        } catch (ValidationException $ex) {
157
-            $form->sessionMessage($ex->getResult()->message(), 'bad');
158
-
159
-            return $this->getResponseNegotiator()->respond($this->request);
160
-        }
161
-        $this->response->addHeader('X-Status', rawurlencode(_t('SilverStripe\\Admin\\LeftAndMain.SAVEDUP', 'Saved.')));
162
-
163
-        return $form->forTemplate();
164
-    }
165
-
166
-    /**
167
-     * @param bool $unlinked
168
-     *
169
-     * @return ArrayList
170
-     */
171
-    public function Breadcrumbs($unlinked = false)
172
-    {
173
-        return new ArrayList(array(
174
-            new ArrayData(array(
175
-                'Title' => static::menu_title(),
176
-                'Link' => $this->Link(),
177
-            )),
178
-        ));
179
-    }
21
+	/**
22
+	 * @var string
23
+	 */
24
+	private static $url_segment = 'foxystripe';
25
+
26
+	/**
27
+	 * @var string
28
+	 */
29
+	private static $url_rule = '/$Action/$ID/$OtherID';
30
+
31
+	/**
32
+	 * @var int
33
+	 */
34
+	private static $menu_priority = 4;
35
+
36
+	/**
37
+	 * @var string
38
+	 */
39
+	private static $menu_title = 'FoxyStripe';
40
+
41
+	/**
42
+	 * @var string
43
+	 */
44
+	private static $menu_icon_class = 'font-icon-cog';
45
+
46
+	/**
47
+	 * @var string
48
+	 */
49
+	private static $tree_class = FoxyStripeSetting::class;
50
+
51
+	/**
52
+	 * @var array
53
+	 */
54
+	private static $required_permission_codes = ['EDIT_GLOBAL_PERMISSION'];
55
+
56
+	/**
57
+	 * Initialises the {@link FoxyStripeSetting} controller.
58
+	 */
59
+	public function init()
60
+	{
61
+		parent::init();
62
+
63
+		Requirements::javascript('silverstripe/cms: client/dist/js/bundle.js');
64
+	}
65
+
66
+	/**
67
+	 * @param null $id
68
+	 * @param null $fields
69
+	 *
70
+	 * @return $this|Form
71
+	 */
72
+	public function getEditForm($id = null, $fields = null)
73
+	{
74
+		$config = FoxyStripeSetting::current_foxystripe_setting();
75
+		$fields = $config->getCMSFields();
76
+
77
+		// Tell the CMS what URL the preview should show
78
+		$home = Director::absoluteBaseURL();
79
+		$fields->push(new HiddenField('PreviewURL', 'Preview URL', $home));
80
+
81
+		// Added in-line to the form, but plucked into different view by LeftAndMain.Preview.js upon load
82
+		$fields->push($navField = new LiteralField(
83
+			'SilverStripeNavigator',
84
+			$this->getSilverStripeNavigator()
85
+		));
86
+		$navField->setAllowHTML(true);
87
+
88
+		// Retrieve validator, if one has been setup (e.g. via data extensions).
89
+		if ($config->hasMethod('getCMSValidator')) {
90
+			$validator = $config->getCMSValidator();
91
+		} else {
92
+			$validator = null;
93
+		}
94
+
95
+		$actions = $config->getCMSActions();
96
+		$negotiator = $this->getResponseNegotiator();
97
+		$form = Form::create(
98
+			$this,
99
+			'EditForm',
100
+			$fields,
101
+			$actions,
102
+			$validator
103
+		)->setHTMLID('Form_EditForm');
104
+		$form->setValidationResponseCallback(function (ValidationResult $errors) use ($negotiator, $form) {
105
+			$request = $this->getRequest();
106
+			if ($request->isAjax() && $negotiator) {
107
+				$result = $form->forTemplate();
108
+
109
+				return $negotiator->respond($request, array(
110
+					'CurrentForm' => function () use ($result) {
111
+						return $result;
112
+					},
113
+				));
114
+			}
115
+			return null;
116
+		});
117
+		$form->addExtraClass('flexbox-area-grow fill-height cms-content cms-edit-form');
118
+		$form->setAttribute('data-pjax-fragment', 'CurrentForm');
119
+
120
+		if ($form->Fields()->hasTabSet()) {
121
+			$form->Fields()->findOrMakeTab('Root')->setTemplate('SilverStripe\\Forms\\CMSTabSet');
122
+		}
123
+		$form->setHTMLID('Form_EditForm');
124
+		$form->loadDataFrom($config);
125
+		$form->setTemplate($this->getTemplatesWithSuffix('_EditForm'));
126
+
127
+		// Use <button> to allow full jQuery UI styling
128
+		$actions = $actions->dataFields();
129
+		if ($actions) {
130
+			/** @var FormAction $action */
131
+			foreach ($actions as $action) {
132
+				$action->setUseButtonTag(true);
133
+			}
134
+		}
135
+
136
+		$this->extend('updateEditForm', $form);
137
+
138
+		return $form;
139
+	}
140
+
141
+	/**
142
+	 * Save the current sites {@link FoxyStripeSetting} into the database.
143
+	 *
144
+	 * @param $data
145
+	 * @param $form
146
+	 *
147
+	 * @return \SilverStripe\Control\HTTPResponse
148
+	 * @throws \SilverStripe\Control\HTTPResponse_Exception
149
+	 */
150
+	public function save_foxystripe_setting($data, $form)
151
+	{
152
+		$config = FoxyStripeSetting::current_foxystripe_setting();
153
+		$form->saveInto($config);
154
+		try {
155
+			$config->write();
156
+		} catch (ValidationException $ex) {
157
+			$form->sessionMessage($ex->getResult()->message(), 'bad');
158
+
159
+			return $this->getResponseNegotiator()->respond($this->request);
160
+		}
161
+		$this->response->addHeader('X-Status', rawurlencode(_t('SilverStripe\\Admin\\LeftAndMain.SAVEDUP', 'Saved.')));
162
+
163
+		return $form->forTemplate();
164
+	}
165
+
166
+	/**
167
+	 * @param bool $unlinked
168
+	 *
169
+	 * @return ArrayList
170
+	 */
171
+	public function Breadcrumbs($unlinked = false)
172
+	{
173
+		return new ArrayList(array(
174
+			new ArrayData(array(
175
+				'Title' => static::menu_title(),
176
+				'Link' => $this->Link(),
177
+			)),
178
+		));
179
+	}
180 180
 }
Please login to merge, or discard this patch.
src/Model/Order.php 2 patches
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -211,7 +211,7 @@  discard block
 block discarded – undo
211 211
             $this->parseOrderDetails($response);
212 212
 
213 213
             return true;
214
-        } else {
214
+        }else {
215 215
             return false;
216 216
         }
217 217
     }
@@ -223,14 +223,14 @@  discard block
 block discarded – undo
223 223
     {
224 224
         foreach ($response->transactions->transaction as $transaction) {
225 225
             // Record transaction data from FoxyCart Datafeed:
226
-            $this->Store_ID = (int) $transaction->store_id;
227
-            $this->TransactionDate = (string) $transaction->transaction_date;
228
-            $this->ProductTotal = (float) $transaction->product_total;
229
-            $this->TaxTotal = (float) $transaction->tax_total;
230
-            $this->ShippingTotal = (float) $transaction->shipping_total;
231
-            $this->OrderTotal = (float) $transaction->order_total;
232
-            $this->ReceiptURL = (string) $transaction->receipt_url;
233
-            $this->OrderStatus = (string) $transaction->status;
226
+            $this->Store_ID = (int)$transaction->store_id;
227
+            $this->TransactionDate = (string)$transaction->transaction_date;
228
+            $this->ProductTotal = (float)$transaction->product_total;
229
+            $this->TaxTotal = (float)$transaction->tax_total;
230
+            $this->ShippingTotal = (float)$transaction->shipping_total;
231
+            $this->OrderTotal = (float)$transaction->order_total;
232
+            $this->ReceiptURL = (string)$transaction->receipt_url;
233
+            $this->OrderStatus = (string)$transaction->status;
234 234
 
235 235
             $this->extend('handleOrderInfo', $order, $response);
236 236
         }
@@ -249,18 +249,18 @@  discard block
 block discarded – undo
249 249
                 if (Member::get()->filter('Email', $transaction->customer_email)->First()) {
250 250
                     $customer = Member::get()->filter('Email', $transaction->customer_email)->First();
251 251
                     // if new customer, create account with data from FoxyCart
252
-                } else {
252
+                }else {
253 253
                     // set PasswordEncryption to 'none' so imported, encrypted password is not encrypted again
254 254
                     Config::modify()->set(Security::class, 'password_encryption_algorithm', 'none');
255 255
 
256 256
                     // create new Member, set password info from FoxyCart
257 257
                     $customer = Member::create();
258
-                    $customer->Customer_ID = (int) $transaction->customer_id;
259
-                    $customer->FirstName = (string) $transaction->customer_first_name;
260
-                    $customer->Surname = (string) $transaction->customer_last_name;
261
-                    $customer->Email = (string) $transaction->customer_email;
262
-                    $customer->Password = (string) $transaction->customer_password;
263
-                    $customer->Salt = (string) $transaction->customer_password_salt;
258
+                    $customer->Customer_ID = (int)$transaction->customer_id;
259
+                    $customer->FirstName = (string)$transaction->customer_first_name;
260
+                    $customer->Surname = (string)$transaction->customer_last_name;
261
+                    $customer->Email = (string)$transaction->customer_email;
262
+                    $customer->Password = (string)$transaction->customer_password;
263
+                    $customer->Salt = (string)$transaction->customer_password_salt;
264 264
                     $customer->PasswordEncryption = 'none';
265 265
 
266 266
                     // record member record
@@ -297,11 +297,11 @@  discard block
 block discarded – undo
297 297
             foreach ($transaction->transaction_details->transaction_detail as $detail) {
298 298
                 $OrderDetail = OrderDetail::create();
299 299
 
300
-                $OrderDetail->Quantity = (int) $detail->product_quantity;
301
-                $OrderDetail->ProductName = (string) $detail->product_name;
302
-                $OrderDetail->ProductCode = (string) $detail->product_code;
303
-                $OrderDetail->ProductImage = (string) $detail->image;
304
-                $OrderDetail->ProductCategory = (string) $detail->category_code;
300
+                $OrderDetail->Quantity = (int)$detail->product_quantity;
301
+                $OrderDetail->ProductName = (string)$detail->product_name;
302
+                $OrderDetail->ProductCode = (string)$detail->product_code;
303
+                $OrderDetail->ProductImage = (string)$detail->image;
304
+                $OrderDetail->ProductCategory = (string)$detail->category_code;
305 305
                 $priceModifier = 0;
306 306
 
307 307
                 // parse OrderOptions
@@ -309,14 +309,14 @@  discard block
 block discarded – undo
309 309
                     // Find product via product_id custom variable
310 310
                     if ($option->product_option_name == 'product_id') {
311 311
                         // if product is found, set relation to OrderDetail
312
-                        $OrderProduct = ProductPage::get()->byID((int) $option->product_option_value);
312
+                        $OrderProduct = ProductPage::get()->byID((int)$option->product_option_value);
313 313
                         if ($OrderProduct) {
314 314
                             $OrderDetail->ProductID = $OrderProduct->ID;
315 315
                         }
316
-                    } else {
316
+                    }else {
317 317
                         $OrderOption = OrderOption::create();
318
-                        $OrderOption->Name = (string) $option->product_option_name;
319
-                        $OrderOption->Value = (string) $option->product_option_value;
318
+                        $OrderOption->Name = (string)$option->product_option_name;
319
+                        $OrderOption->Value = (string)$option->product_option_value;
320 320
                         $OrderOption->write();
321 321
                         $OrderDetail->OrderOptions()->add($OrderOption);
322 322
 
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
                     }
325 325
                 }
326 326
 
327
-                $OrderDetail->Price = (float) $detail->product_price + (float) $priceModifier;
327
+                $OrderDetail->Price = (float)$detail->product_price + (float)$priceModifier;
328 328
 
329 329
                 // extend OrderDetail parsing, allowing for recording custom fields from FoxyCart
330 330
                 $this->extend('handleOrderItem', $order, $response, $OrderDetail);
Please login to merge, or discard this patch.
Indentation   +357 added lines, -357 removed lines patch added patch discarded remove patch
@@ -33,361 +33,361 @@
 block discarded – undo
33 33
  */
34 34
 class Order extends DataObject implements PermissionProvider
35 35
 {
36
-    /**
37
-     * @var array
38
-     */
39
-    private static $db = array(
40
-        'Order_ID' => 'Int',
41
-        'TransactionDate' => 'DBDatetime',
42
-        'ProductTotal' => 'Currency',
43
-        'TaxTotal' => 'Currency',
44
-        'ShippingTotal' => 'Currency',
45
-        'OrderTotal' => 'Currency',
46
-        'ReceiptURL' => 'Varchar(255)',
47
-        'OrderStatus' => 'Varchar(255)',
48
-        'Response' => 'Text',
49
-    );
50
-
51
-    /**
52
-     * @var array
53
-     */
54
-    private static $has_one = array(
55
-        'Member' => Member::class,
56
-    );
57
-
58
-    /**
59
-     * @var array
60
-     */
61
-    private static $has_many = array(
62
-        'Details' => OrderDetail::class,
63
-    );
64
-
65
-    /**
66
-     * @var string
67
-     */
68
-    private static $singular_name = 'Order';
69
-
70
-    /**
71
-     * @var string
72
-     */
73
-    private static $plural_name = 'Orders';
74
-
75
-    /**
76
-     * @var string
77
-     */
78
-    private static $description = 'Orders from FoxyCart Datafeed';
79
-
80
-    /**
81
-     * @var string
82
-     */
83
-    private static $default_sort = 'TransactionDate DESC, ID DESC';
84
-
85
-    /**
86
-     * @var array
87
-     */
88
-    private static $summary_fields = array(
89
-        'Order_ID',
90
-        'TransactionDate.Nice',
91
-        'Member.Name',
92
-        'ProductTotal.Nice',
93
-        'ShippingTotal.Nice',
94
-        'TaxTotal.Nice',
95
-        'OrderTotal.Nice',
96
-        'ReceiptLink',
97
-    );
98
-
99
-    /**
100
-     * @var array
101
-     */
102
-    private static $searchable_fields = array(
103
-        'Order_ID',
104
-        'TransactionDate' => array(
105
-            'field' => DateField::class,
106
-            'filter' => 'PartialMatchFilter',
107
-        ),
108
-        'Member.ID',
109
-        'OrderTotal',
110
-        'Details.ProductID',
111
-    );
112
-
113
-    /**
114
-     * @var array
115
-     */
116
-    private static $casting = array(
117
-        'ReceiptLink' => 'HTMLVarchar',
118
-    );
119
-
120
-    /**
121
-     * @var array
122
-     */
123
-    private static $indexes = array(
124
-        'Order_ID' => true, // make unique
125
-    );
126
-
127
-    /**
128
-     * @var string
129
-     */
130
-    private static $table_name = 'Order';
131
-
132
-    /**
133
-     * @param bool $includerelations
134
-     *
135
-     * @return array|string
136
-     */
137
-    public function fieldLabels($includerelations = true)
138
-    {
139
-        $labels = parent::fieldLabels();
140
-
141
-        $labels['Order_ID'] = _t('Order.Order_ID', 'Order ID#');
142
-        $labels['TransactionDate'] = _t('Order.TransactionDate', 'Date');
143
-        $labels['TransactionDate.NiceUS'] = _t('Order.TransactionDate', 'Date');
144
-        $labels['Member.Name'] = _t('Order.MemberName', 'Customer');
145
-        $labels['Member.ID'] = _t('Order.MemberName', 'Customer');
146
-        $labels['ProductTotal.Nice'] = _t('Order.ProductTotal', 'Sub Total');
147
-        $labels['TaxTotal.Nice'] = _t('Order.TaxTotal', 'Tax');
148
-        $labels['ShippingTotal.Nice'] = _t('Order.ShippingTotal', 'Shipping');
149
-        $labels['OrderTotal'] = _t('Order.OrderTotal', 'Total');
150
-        $labels['OrderTotal.Nice'] = _t('Order.OrderTotal', 'Total');
151
-        $labels['ReceiptLink'] = _t('Order.ReceiptLink', 'Invoice');
152
-        $labels['Details.ProductID'] = _t('Order.Details.ProductID', 'Product');
153
-
154
-        return $labels;
155
-    }
156
-
157
-    /**
158
-     * @return mixed
159
-     */
160
-    public function ReceiptLink()
161
-    {
162
-        return $this->getReceiptLink();
163
-    }
164
-
165
-    /**
166
-     * @return mixed
167
-     */
168
-    public function getReceiptLink()
169
-    {
170
-        $obj = DBHTMLVarchar::create();
171
-        $obj->setValue(
172
-            '<a href="'.$this->ReceiptURL.'" target="_blank" class="cms-panel-link action external-link">view</a>'
173
-        );
174
-
175
-        return $obj;
176
-    }
177
-
178
-    /**
179
-     * @return bool|string
180
-     */
181
-    public function getDecryptedResponse()
182
-    {
183
-        $decrypted = urldecode($this->Response);
184
-        if (FoxyCart::getStoreKey()) {
185
-            return \rc4crypt::decrypt(FoxyCart::getStoreKey(), $decrypted);
186
-        }
187
-        return false;
188
-    }
189
-
190
-    /**
191
-     * @throws \SilverStripe\ORM\ValidationException
192
-     */
193
-    public function onBeforeWrite()
194
-    {
195
-        $this->parseOrder();
196
-        parent::onBeforeWrite();
197
-    }
198
-
199
-    /**
200
-     * @return bool
201
-     *
202
-     * @throws \SilverStripe\ORM\ValidationException
203
-     */
204
-    public function parseOrder()
205
-    {
206
-        if ($this->getDecryptedResponse()) {
207
-            $response = new \SimpleXMLElement($this->getDecryptedResponse());
208
-
209
-            $this->parseOrderInfo($response);
210
-            $this->parseOrderCustomer($response);
211
-            $this->parseOrderDetails($response);
212
-
213
-            return true;
214
-        } else {
215
-            return false;
216
-        }
217
-    }
218
-
219
-    /**
220
-     * @param $response
221
-     */
222
-    public function parseOrderInfo($response)
223
-    {
224
-        foreach ($response->transactions->transaction as $transaction) {
225
-            // Record transaction data from FoxyCart Datafeed:
226
-            $this->Store_ID = (int) $transaction->store_id;
227
-            $this->TransactionDate = (string) $transaction->transaction_date;
228
-            $this->ProductTotal = (float) $transaction->product_total;
229
-            $this->TaxTotal = (float) $transaction->tax_total;
230
-            $this->ShippingTotal = (float) $transaction->shipping_total;
231
-            $this->OrderTotal = (float) $transaction->order_total;
232
-            $this->ReceiptURL = (string) $transaction->receipt_url;
233
-            $this->OrderStatus = (string) $transaction->status;
234
-
235
-            $this->extend('handleOrderInfo', $order, $response);
236
-        }
237
-    }
238
-
239
-    /**
240
-     * @param $response
241
-     * @throws \SilverStripe\ORM\ValidationException
242
-     */
243
-    public function parseOrderCustomer($response)
244
-    {
245
-        foreach ($response->transactions->transaction as $transaction) {
246
-            // if not a guest transaction in FoxyCart
247
-            if (isset($transaction->customer_email) && $transaction->is_anonymous == 0) {
248
-                // if Customer is existing member, associate with current order
249
-                if (Member::get()->filter('Email', $transaction->customer_email)->First()) {
250
-                    $customer = Member::get()->filter('Email', $transaction->customer_email)->First();
251
-                    // if new customer, create account with data from FoxyCart
252
-                } else {
253
-                    // set PasswordEncryption to 'none' so imported, encrypted password is not encrypted again
254
-                    Config::modify()->set(Security::class, 'password_encryption_algorithm', 'none');
255
-
256
-                    // create new Member, set password info from FoxyCart
257
-                    $customer = Member::create();
258
-                    $customer->Customer_ID = (int) $transaction->customer_id;
259
-                    $customer->FirstName = (string) $transaction->customer_first_name;
260
-                    $customer->Surname = (string) $transaction->customer_last_name;
261
-                    $customer->Email = (string) $transaction->customer_email;
262
-                    $customer->Password = (string) $transaction->customer_password;
263
-                    $customer->Salt = (string) $transaction->customer_password_salt;
264
-                    $customer->PasswordEncryption = 'none';
265
-
266
-                    // record member record
267
-                    $customer->write();
268
-                }
269
-
270
-                // set Order MemberID
271
-                $this->MemberID = $customer->ID;
272
-
273
-                $this->extend('handleOrderCustomer', $order, $response, $customer);
274
-            }
275
-        }
276
-    }
277
-
278
-    /**
279
-     * @param $response
280
-     *
281
-     * @throws \SilverStripe\ORM\ValidationException
282
-     */
283
-    public function parseOrderDetails($response)
284
-    {
285
-
286
-        // remove previous OrderDetails and OrderOptions so we don't end up with duplicates
287
-        foreach ($this->Details() as $detail) {
288
-            /** @var OrderOption $orderOption */
289
-            foreach ($detail->OrderOptions() as $orderOption) {
290
-                $orderOption->delete();
291
-            }
292
-            $detail->delete();
293
-        }
294
-
295
-        foreach ($response->transactions->transaction as $transaction) {
296
-            // Associate ProductPages, Options, Quantity with Order
297
-            foreach ($transaction->transaction_details->transaction_detail as $detail) {
298
-                $OrderDetail = OrderDetail::create();
299
-
300
-                $OrderDetail->Quantity = (int) $detail->product_quantity;
301
-                $OrderDetail->ProductName = (string) $detail->product_name;
302
-                $OrderDetail->ProductCode = (string) $detail->product_code;
303
-                $OrderDetail->ProductImage = (string) $detail->image;
304
-                $OrderDetail->ProductCategory = (string) $detail->category_code;
305
-                $priceModifier = 0;
306
-
307
-                // parse OrderOptions
308
-                foreach ($detail->transaction_detail_options->transaction_detail_option as $option) {
309
-                    // Find product via product_id custom variable
310
-                    if ($option->product_option_name == 'product_id') {
311
-                        // if product is found, set relation to OrderDetail
312
-                        $OrderProduct = ProductPage::get()->byID((int) $option->product_option_value);
313
-                        if ($OrderProduct) {
314
-                            $OrderDetail->ProductID = $OrderProduct->ID;
315
-                        }
316
-                    } else {
317
-                        $OrderOption = OrderOption::create();
318
-                        $OrderOption->Name = (string) $option->product_option_name;
319
-                        $OrderOption->Value = (string) $option->product_option_value;
320
-                        $OrderOption->write();
321
-                        $OrderDetail->OrderOptions()->add($OrderOption);
322
-
323
-                        $priceModifier += $option->price_mod;
324
-                    }
325
-                }
326
-
327
-                $OrderDetail->Price = (float) $detail->product_price + (float) $priceModifier;
328
-
329
-                // extend OrderDetail parsing, allowing for recording custom fields from FoxyCart
330
-                $this->extend('handleOrderItem', $order, $response, $OrderDetail);
331
-
332
-                // write
333
-                $OrderDetail->write();
334
-
335
-                // associate with this order
336
-                $this->Details()->add($OrderDetail);
337
-            }
338
-        }
339
-    }
340
-
341
-    /**
342
-     * @param bool $member
343
-     *
344
-     * @return bool|int
345
-     */
346
-    public function canView($member = null)
347
-    {
348
-        return Permission::check('Product_ORDERS', 'any', $member);
349
-    }
350
-
351
-    /**
352
-     * @param null $member
353
-     *
354
-     * @return bool
355
-     */
356
-    public function canEdit($member = null)
357
-    {
358
-        return false;
359
-        //return Permission::check('Product_ORDERS', 'any', $member);
360
-    }
361
-
362
-    /**
363
-     * @param null $member
364
-     *
365
-     * @return bool
366
-     */
367
-    public function canDelete($member = null)
368
-    {
369
-        return false;
370
-        //return Permission::check('Product_ORDERS', 'any', $member);
371
-    }
372
-
373
-    /**
374
-     * @param null  $member
375
-     * @param array $context
376
-     *
377
-     * @return bool
378
-     */
379
-    public function canCreate($member = null, $context = [])
380
-    {
381
-        return false;
382
-    }
383
-
384
-    /**
385
-     * @return array
386
-     */
387
-    public function providePermissions()
388
-    {
389
-        return array(
390
-            'Product_ORDERS' => 'Allow user to manage Orders and related objects',
391
-        );
392
-    }
36
+	/**
37
+	 * @var array
38
+	 */
39
+	private static $db = array(
40
+		'Order_ID' => 'Int',
41
+		'TransactionDate' => 'DBDatetime',
42
+		'ProductTotal' => 'Currency',
43
+		'TaxTotal' => 'Currency',
44
+		'ShippingTotal' => 'Currency',
45
+		'OrderTotal' => 'Currency',
46
+		'ReceiptURL' => 'Varchar(255)',
47
+		'OrderStatus' => 'Varchar(255)',
48
+		'Response' => 'Text',
49
+	);
50
+
51
+	/**
52
+	 * @var array
53
+	 */
54
+	private static $has_one = array(
55
+		'Member' => Member::class,
56
+	);
57
+
58
+	/**
59
+	 * @var array
60
+	 */
61
+	private static $has_many = array(
62
+		'Details' => OrderDetail::class,
63
+	);
64
+
65
+	/**
66
+	 * @var string
67
+	 */
68
+	private static $singular_name = 'Order';
69
+
70
+	/**
71
+	 * @var string
72
+	 */
73
+	private static $plural_name = 'Orders';
74
+
75
+	/**
76
+	 * @var string
77
+	 */
78
+	private static $description = 'Orders from FoxyCart Datafeed';
79
+
80
+	/**
81
+	 * @var string
82
+	 */
83
+	private static $default_sort = 'TransactionDate DESC, ID DESC';
84
+
85
+	/**
86
+	 * @var array
87
+	 */
88
+	private static $summary_fields = array(
89
+		'Order_ID',
90
+		'TransactionDate.Nice',
91
+		'Member.Name',
92
+		'ProductTotal.Nice',
93
+		'ShippingTotal.Nice',
94
+		'TaxTotal.Nice',
95
+		'OrderTotal.Nice',
96
+		'ReceiptLink',
97
+	);
98
+
99
+	/**
100
+	 * @var array
101
+	 */
102
+	private static $searchable_fields = array(
103
+		'Order_ID',
104
+		'TransactionDate' => array(
105
+			'field' => DateField::class,
106
+			'filter' => 'PartialMatchFilter',
107
+		),
108
+		'Member.ID',
109
+		'OrderTotal',
110
+		'Details.ProductID',
111
+	);
112
+
113
+	/**
114
+	 * @var array
115
+	 */
116
+	private static $casting = array(
117
+		'ReceiptLink' => 'HTMLVarchar',
118
+	);
119
+
120
+	/**
121
+	 * @var array
122
+	 */
123
+	private static $indexes = array(
124
+		'Order_ID' => true, // make unique
125
+	);
126
+
127
+	/**
128
+	 * @var string
129
+	 */
130
+	private static $table_name = 'Order';
131
+
132
+	/**
133
+	 * @param bool $includerelations
134
+	 *
135
+	 * @return array|string
136
+	 */
137
+	public function fieldLabels($includerelations = true)
138
+	{
139
+		$labels = parent::fieldLabels();
140
+
141
+		$labels['Order_ID'] = _t('Order.Order_ID', 'Order ID#');
142
+		$labels['TransactionDate'] = _t('Order.TransactionDate', 'Date');
143
+		$labels['TransactionDate.NiceUS'] = _t('Order.TransactionDate', 'Date');
144
+		$labels['Member.Name'] = _t('Order.MemberName', 'Customer');
145
+		$labels['Member.ID'] = _t('Order.MemberName', 'Customer');
146
+		$labels['ProductTotal.Nice'] = _t('Order.ProductTotal', 'Sub Total');
147
+		$labels['TaxTotal.Nice'] = _t('Order.TaxTotal', 'Tax');
148
+		$labels['ShippingTotal.Nice'] = _t('Order.ShippingTotal', 'Shipping');
149
+		$labels['OrderTotal'] = _t('Order.OrderTotal', 'Total');
150
+		$labels['OrderTotal.Nice'] = _t('Order.OrderTotal', 'Total');
151
+		$labels['ReceiptLink'] = _t('Order.ReceiptLink', 'Invoice');
152
+		$labels['Details.ProductID'] = _t('Order.Details.ProductID', 'Product');
153
+
154
+		return $labels;
155
+	}
156
+
157
+	/**
158
+	 * @return mixed
159
+	 */
160
+	public function ReceiptLink()
161
+	{
162
+		return $this->getReceiptLink();
163
+	}
164
+
165
+	/**
166
+	 * @return mixed
167
+	 */
168
+	public function getReceiptLink()
169
+	{
170
+		$obj = DBHTMLVarchar::create();
171
+		$obj->setValue(
172
+			'<a href="'.$this->ReceiptURL.'" target="_blank" class="cms-panel-link action external-link">view</a>'
173
+		);
174
+
175
+		return $obj;
176
+	}
177
+
178
+	/**
179
+	 * @return bool|string
180
+	 */
181
+	public function getDecryptedResponse()
182
+	{
183
+		$decrypted = urldecode($this->Response);
184
+		if (FoxyCart::getStoreKey()) {
185
+			return \rc4crypt::decrypt(FoxyCart::getStoreKey(), $decrypted);
186
+		}
187
+		return false;
188
+	}
189
+
190
+	/**
191
+	 * @throws \SilverStripe\ORM\ValidationException
192
+	 */
193
+	public function onBeforeWrite()
194
+	{
195
+		$this->parseOrder();
196
+		parent::onBeforeWrite();
197
+	}
198
+
199
+	/**
200
+	 * @return bool
201
+	 *
202
+	 * @throws \SilverStripe\ORM\ValidationException
203
+	 */
204
+	public function parseOrder()
205
+	{
206
+		if ($this->getDecryptedResponse()) {
207
+			$response = new \SimpleXMLElement($this->getDecryptedResponse());
208
+
209
+			$this->parseOrderInfo($response);
210
+			$this->parseOrderCustomer($response);
211
+			$this->parseOrderDetails($response);
212
+
213
+			return true;
214
+		} else {
215
+			return false;
216
+		}
217
+	}
218
+
219
+	/**
220
+	 * @param $response
221
+	 */
222
+	public function parseOrderInfo($response)
223
+	{
224
+		foreach ($response->transactions->transaction as $transaction) {
225
+			// Record transaction data from FoxyCart Datafeed:
226
+			$this->Store_ID = (int) $transaction->store_id;
227
+			$this->TransactionDate = (string) $transaction->transaction_date;
228
+			$this->ProductTotal = (float) $transaction->product_total;
229
+			$this->TaxTotal = (float) $transaction->tax_total;
230
+			$this->ShippingTotal = (float) $transaction->shipping_total;
231
+			$this->OrderTotal = (float) $transaction->order_total;
232
+			$this->ReceiptURL = (string) $transaction->receipt_url;
233
+			$this->OrderStatus = (string) $transaction->status;
234
+
235
+			$this->extend('handleOrderInfo', $order, $response);
236
+		}
237
+	}
238
+
239
+	/**
240
+	 * @param $response
241
+	 * @throws \SilverStripe\ORM\ValidationException
242
+	 */
243
+	public function parseOrderCustomer($response)
244
+	{
245
+		foreach ($response->transactions->transaction as $transaction) {
246
+			// if not a guest transaction in FoxyCart
247
+			if (isset($transaction->customer_email) && $transaction->is_anonymous == 0) {
248
+				// if Customer is existing member, associate with current order
249
+				if (Member::get()->filter('Email', $transaction->customer_email)->First()) {
250
+					$customer = Member::get()->filter('Email', $transaction->customer_email)->First();
251
+					// if new customer, create account with data from FoxyCart
252
+				} else {
253
+					// set PasswordEncryption to 'none' so imported, encrypted password is not encrypted again
254
+					Config::modify()->set(Security::class, 'password_encryption_algorithm', 'none');
255
+
256
+					// create new Member, set password info from FoxyCart
257
+					$customer = Member::create();
258
+					$customer->Customer_ID = (int) $transaction->customer_id;
259
+					$customer->FirstName = (string) $transaction->customer_first_name;
260
+					$customer->Surname = (string) $transaction->customer_last_name;
261
+					$customer->Email = (string) $transaction->customer_email;
262
+					$customer->Password = (string) $transaction->customer_password;
263
+					$customer->Salt = (string) $transaction->customer_password_salt;
264
+					$customer->PasswordEncryption = 'none';
265
+
266
+					// record member record
267
+					$customer->write();
268
+				}
269
+
270
+				// set Order MemberID
271
+				$this->MemberID = $customer->ID;
272
+
273
+				$this->extend('handleOrderCustomer', $order, $response, $customer);
274
+			}
275
+		}
276
+	}
277
+
278
+	/**
279
+	 * @param $response
280
+	 *
281
+	 * @throws \SilverStripe\ORM\ValidationException
282
+	 */
283
+	public function parseOrderDetails($response)
284
+	{
285
+
286
+		// remove previous OrderDetails and OrderOptions so we don't end up with duplicates
287
+		foreach ($this->Details() as $detail) {
288
+			/** @var OrderOption $orderOption */
289
+			foreach ($detail->OrderOptions() as $orderOption) {
290
+				$orderOption->delete();
291
+			}
292
+			$detail->delete();
293
+		}
294
+
295
+		foreach ($response->transactions->transaction as $transaction) {
296
+			// Associate ProductPages, Options, Quantity with Order
297
+			foreach ($transaction->transaction_details->transaction_detail as $detail) {
298
+				$OrderDetail = OrderDetail::create();
299
+
300
+				$OrderDetail->Quantity = (int) $detail->product_quantity;
301
+				$OrderDetail->ProductName = (string) $detail->product_name;
302
+				$OrderDetail->ProductCode = (string) $detail->product_code;
303
+				$OrderDetail->ProductImage = (string) $detail->image;
304
+				$OrderDetail->ProductCategory = (string) $detail->category_code;
305
+				$priceModifier = 0;
306
+
307
+				// parse OrderOptions
308
+				foreach ($detail->transaction_detail_options->transaction_detail_option as $option) {
309
+					// Find product via product_id custom variable
310
+					if ($option->product_option_name == 'product_id') {
311
+						// if product is found, set relation to OrderDetail
312
+						$OrderProduct = ProductPage::get()->byID((int) $option->product_option_value);
313
+						if ($OrderProduct) {
314
+							$OrderDetail->ProductID = $OrderProduct->ID;
315
+						}
316
+					} else {
317
+						$OrderOption = OrderOption::create();
318
+						$OrderOption->Name = (string) $option->product_option_name;
319
+						$OrderOption->Value = (string) $option->product_option_value;
320
+						$OrderOption->write();
321
+						$OrderDetail->OrderOptions()->add($OrderOption);
322
+
323
+						$priceModifier += $option->price_mod;
324
+					}
325
+				}
326
+
327
+				$OrderDetail->Price = (float) $detail->product_price + (float) $priceModifier;
328
+
329
+				// extend OrderDetail parsing, allowing for recording custom fields from FoxyCart
330
+				$this->extend('handleOrderItem', $order, $response, $OrderDetail);
331
+
332
+				// write
333
+				$OrderDetail->write();
334
+
335
+				// associate with this order
336
+				$this->Details()->add($OrderDetail);
337
+			}
338
+		}
339
+	}
340
+
341
+	/**
342
+	 * @param bool $member
343
+	 *
344
+	 * @return bool|int
345
+	 */
346
+	public function canView($member = null)
347
+	{
348
+		return Permission::check('Product_ORDERS', 'any', $member);
349
+	}
350
+
351
+	/**
352
+	 * @param null $member
353
+	 *
354
+	 * @return bool
355
+	 */
356
+	public function canEdit($member = null)
357
+	{
358
+		return false;
359
+		//return Permission::check('Product_ORDERS', 'any', $member);
360
+	}
361
+
362
+	/**
363
+	 * @param null $member
364
+	 *
365
+	 * @return bool
366
+	 */
367
+	public function canDelete($member = null)
368
+	{
369
+		return false;
370
+		//return Permission::check('Product_ORDERS', 'any', $member);
371
+	}
372
+
373
+	/**
374
+	 * @param null  $member
375
+	 * @param array $context
376
+	 *
377
+	 * @return bool
378
+	 */
379
+	public function canCreate($member = null, $context = [])
380
+	{
381
+		return false;
382
+	}
383
+
384
+	/**
385
+	 * @return array
386
+	 */
387
+	public function providePermissions()
388
+	{
389
+		return array(
390
+			'Product_ORDERS' => 'Allow user to manage Orders and related objects',
391
+		);
392
+	}
393 393
 }
Please login to merge, or discard this patch.
src/Model/FoxyStripeSetting.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -332,7 +332,7 @@  discard block
 block discarded – undo
332 332
                 FormAction::create('save_foxystripe_setting', _t('FoxyStripeSetting.SAVE', 'Save'))
333 333
                     ->addExtraClass('btn-primary font-icon-save')
334 334
             );
335
-        } else {
335
+        }else {
336 336
             $actions = FieldList::create();
337 337
         }
338 338
         $this->extend('updateCMSActions', $actions);
@@ -360,7 +360,7 @@  discard block
 block discarded – undo
360 360
             }
361 361
             $config->StoreKey = $key;
362 362
             $config->write();
363
-            DB::alteration_message('Created FoxyCart Store Key ' . $key, 'created');
363
+            DB::alteration_message('Created FoxyCart Store Key '.$key, 'created');
364 364
         }
365 365
     }
366 366
 
@@ -462,7 +462,7 @@  discard block
 block discarded – undo
462 462
      */
463 463
     private static function getSSOLink()
464 464
     {
465
-        return Director::absoluteBaseURL() . 'foxystripe/sso/';
465
+        return Director::absoluteBaseURL().'foxystripe/sso/';
466 466
     }
467 467
 
468 468
     /**
@@ -470,7 +470,7 @@  discard block
 block discarded – undo
470 470
      */
471 471
     private static function getDataFeedLink()
472 472
     {
473
-        return Director::absoluteBaseURL() . 'foxystripe/';
473
+        return Director::absoluteBaseURL().'foxystripe/';
474 474
     }
475 475
 
476 476
     /**
Please login to merge, or discard this patch.
Indentation   +493 added lines, -493 removed lines patch added patch discarded remove patch
@@ -62,236 +62,236 @@  discard block
 block discarded – undo
62 62
  */
63 63
 class FoxyStripeSetting extends DataObject implements PermissionProvider, TemplateGlobalProvider
64 64
 {
65
-    /**
66
-     * @var string
67
-     */
68
-    private static $singular_name = 'FoxyStripe Setting';
69
-    /**
70
-     * @var string
71
-     */
72
-    private static $plural_name = 'FoxyStripe Settings';
73
-    /**
74
-     * @var string
75
-     */
76
-    private static $description = 'Update the settings for your store';
77
-
78
-    /**
79
-     * @var array
80
-     */
81
-    private static $db = [
82
-        'StoreTitle' => 'Varchar(255)',
83
-        'StoreName' => 'Varchar(255)',
84
-        'CustomSSL' => 'Boolean',
85
-        'RemoteDomain' => 'Varchar(255)',
86
-        'StoreURL' => 'Varchar(255)',
87
-        'ReceiptURL' => 'Varchar(255)',
88
-        'StoreEmail' => 'Varchar(255)',
89
-        'FromEmail' => 'Varchar(255)',
90
-        'StorePostalCode' => 'Varchar(10)',
91
-        'StoreCountry' => 'Varchar(100)',
92
-        'StoreRegion' => 'Varchar(100)',
93
-        'StoreLocaleCode' => 'Varchar(10)',
94
-        'StoreLogoURL' => 'Varchar(255)',
95
-        'CheckoutType' => 'Varchar(50)',
96
-        'BccEmail' => 'Boolean',
97
-        'UseWebhook' => 'Boolean',
98
-        'StoreKey' => 'Varchar(60)',
99
-        'CartValidation' => 'Boolean',
100
-        'UseSingleSignOn' => 'Boolean',
101
-        'AllowMultiship' => 'Boolean',
102
-        'StoreTimezone' => 'Varchar(100)',
103
-        'MultiGroup' => 'Boolean',
104
-        'ProductLimit' => 'Int',
105
-        'MaxQuantity' => 'Int',
106
-        'EnableAPI' => 'Boolean',
107
-        'client_id' => 'Varchar(255)',
108
-        'client_secret' => 'Varchar(255)',
109
-        'access_token' => 'Varchar(255)',
110
-        'refresh_token' => 'Varchar(255)',
111
-        'EnableSidecart' => 'Boolean',
112
-    ];
113
-
114
-    // Set Default values
115
-    private static $defaults = [
116
-        'ProductLimit' => 10,
117
-        'EnableSidecart' => 1,
118
-    ];
119
-
120
-    /**
121
-     * @var string
122
-     */
123
-    private static $table_name = 'FoxyStripeSetting';
124
-
125
-    /**
126
-     * Default permission to check for 'LoggedInUsers' to create or edit pages.
127
-     *
128
-     * @var array
129
-     * @config
130
-     */
131
-    private static $required_permission = ['CMS_ACCESS_CMSMain', 'CMS_ACCESS_LeftAndMain'];
132
-
133
-    /**
134
-     * @return FieldList
135
-     */
136
-    public function getCMSFields()
137
-    {
138
-        $fields = FieldList::create(
139
-            TabSet::create(
140
-                'Root',
141
-                $tabMain = Tab::create(
142
-                    'Main'
143
-                )
144
-            ),
145
-            HiddenField::create('ID')
146
-        );
147
-        $tabMain->setTitle('Settings');
148
-
149
-        // settings tab
150
-        $fields->addFieldsToTab('Root.Main', [
151
-            // Store Details
152
-            HeaderField::create('StoreDetails', _t('FoxyStripeSiteConfig.StoreDetails', 'Store Settings'), 3),
153
-            LiteralField::create('DetailsIntro', _t(
154
-                'FoxyStripeSiteConfig.DetailsIntro',
155
-                '<p>Maps to data in your 
65
+	/**
66
+	 * @var string
67
+	 */
68
+	private static $singular_name = 'FoxyStripe Setting';
69
+	/**
70
+	 * @var string
71
+	 */
72
+	private static $plural_name = 'FoxyStripe Settings';
73
+	/**
74
+	 * @var string
75
+	 */
76
+	private static $description = 'Update the settings for your store';
77
+
78
+	/**
79
+	 * @var array
80
+	 */
81
+	private static $db = [
82
+		'StoreTitle' => 'Varchar(255)',
83
+		'StoreName' => 'Varchar(255)',
84
+		'CustomSSL' => 'Boolean',
85
+		'RemoteDomain' => 'Varchar(255)',
86
+		'StoreURL' => 'Varchar(255)',
87
+		'ReceiptURL' => 'Varchar(255)',
88
+		'StoreEmail' => 'Varchar(255)',
89
+		'FromEmail' => 'Varchar(255)',
90
+		'StorePostalCode' => 'Varchar(10)',
91
+		'StoreCountry' => 'Varchar(100)',
92
+		'StoreRegion' => 'Varchar(100)',
93
+		'StoreLocaleCode' => 'Varchar(10)',
94
+		'StoreLogoURL' => 'Varchar(255)',
95
+		'CheckoutType' => 'Varchar(50)',
96
+		'BccEmail' => 'Boolean',
97
+		'UseWebhook' => 'Boolean',
98
+		'StoreKey' => 'Varchar(60)',
99
+		'CartValidation' => 'Boolean',
100
+		'UseSingleSignOn' => 'Boolean',
101
+		'AllowMultiship' => 'Boolean',
102
+		'StoreTimezone' => 'Varchar(100)',
103
+		'MultiGroup' => 'Boolean',
104
+		'ProductLimit' => 'Int',
105
+		'MaxQuantity' => 'Int',
106
+		'EnableAPI' => 'Boolean',
107
+		'client_id' => 'Varchar(255)',
108
+		'client_secret' => 'Varchar(255)',
109
+		'access_token' => 'Varchar(255)',
110
+		'refresh_token' => 'Varchar(255)',
111
+		'EnableSidecart' => 'Boolean',
112
+	];
113
+
114
+	// Set Default values
115
+	private static $defaults = [
116
+		'ProductLimit' => 10,
117
+		'EnableSidecart' => 1,
118
+	];
119
+
120
+	/**
121
+	 * @var string
122
+	 */
123
+	private static $table_name = 'FoxyStripeSetting';
124
+
125
+	/**
126
+	 * Default permission to check for 'LoggedInUsers' to create or edit pages.
127
+	 *
128
+	 * @var array
129
+	 * @config
130
+	 */
131
+	private static $required_permission = ['CMS_ACCESS_CMSMain', 'CMS_ACCESS_LeftAndMain'];
132
+
133
+	/**
134
+	 * @return FieldList
135
+	 */
136
+	public function getCMSFields()
137
+	{
138
+		$fields = FieldList::create(
139
+			TabSet::create(
140
+				'Root',
141
+				$tabMain = Tab::create(
142
+					'Main'
143
+				)
144
+			),
145
+			HiddenField::create('ID')
146
+		);
147
+		$tabMain->setTitle('Settings');
148
+
149
+		// settings tab
150
+		$fields->addFieldsToTab('Root.Main', [
151
+			// Store Details
152
+			HeaderField::create('StoreDetails', _t('FoxyStripeSiteConfig.StoreDetails', 'Store Settings'), 3),
153
+			LiteralField::create('DetailsIntro', _t(
154
+				'FoxyStripeSiteConfig.DetailsIntro',
155
+				'<p>Maps to data in your 
156 156
                         <a href="https://admin.foxycart.com/admin.php?ThisAction=EditStore" target="_blank">
157 157
                             FoxyCart store settings
158 158
                         </a>.'
159
-            )),
160
-            TextField::create('StoreTitle')
161
-                ->setTitle(_t('FoxyStripeSiteConfig.StoreTitle', 'Store Name'))
162
-                ->setDescription(_t(
163
-                    'FoxyStripeSiteConfig.StoreTitleDescription',
164
-                    'The name of your store as you\'d like it displayed to your customers'
165
-                )),
166
-            CheckboxField::create('CustomSSL', 'Use custom SSL'),
167
-            TextField::create('RemoteDomain')
168
-                ->setTitle(_t('FoxyStripeSiteConfig.RemoteDomain', 'Store Remote Domain'))
169
-                ->setDescription(_t(
170
-                    'FoxyStripeSiteConfig.RemoteDomainDescription',
171
-                    'custom subdomain for FoxyCart'
172
-                ))
173
-                ->displayIf('CustomSSL')->isChecked()->end(),
174
-            TextField::create('StoreName')
175
-                ->setTitle(_t('FoxyStripeSiteConfig.StoreName', 'Store Domain'))
176
-                ->setDescription(_t(
177
-                    'FoxyStripeSiteConfig.StoreNameDescription',
178
-                    'This is a unique FoxyCart subdomain for your cart, checkout, and receipt'
179
-                ))
180
-                ->hideIf('CustomSSL')->isChecked()->end(),
181
-            TextField::create('StoreURL')
182
-                ->setTitle(_t('FoxyStripeSiteConfig.StoreURL', 'Store URL'))
183
-                ->setDescription(_t(
184
-                    'FoxyStripeSiteConfig.StoreURLDescription',
185
-                    'The URL of your online store'
186
-                )),
187
-            TextField::create('ReceiptURL')
188
-                ->setTitle(_t('FoxyStripeSiteConfig.ReceiptURL', 'Receipt URL'))
189
-                ->setDescription(_t(
190
-                    'FoxyStripeSiteConfig.ReceiptURLDescription',
191
-                    'By default, FoxyCart sends customers back to the page referrer after completing a purchase. 
159
+			)),
160
+			TextField::create('StoreTitle')
161
+				->setTitle(_t('FoxyStripeSiteConfig.StoreTitle', 'Store Name'))
162
+				->setDescription(_t(
163
+					'FoxyStripeSiteConfig.StoreTitleDescription',
164
+					'The name of your store as you\'d like it displayed to your customers'
165
+				)),
166
+			CheckboxField::create('CustomSSL', 'Use custom SSL'),
167
+			TextField::create('RemoteDomain')
168
+				->setTitle(_t('FoxyStripeSiteConfig.RemoteDomain', 'Store Remote Domain'))
169
+				->setDescription(_t(
170
+					'FoxyStripeSiteConfig.RemoteDomainDescription',
171
+					'custom subdomain for FoxyCart'
172
+				))
173
+				->displayIf('CustomSSL')->isChecked()->end(),
174
+			TextField::create('StoreName')
175
+				->setTitle(_t('FoxyStripeSiteConfig.StoreName', 'Store Domain'))
176
+				->setDescription(_t(
177
+					'FoxyStripeSiteConfig.StoreNameDescription',
178
+					'This is a unique FoxyCart subdomain for your cart, checkout, and receipt'
179
+				))
180
+				->hideIf('CustomSSL')->isChecked()->end(),
181
+			TextField::create('StoreURL')
182
+				->setTitle(_t('FoxyStripeSiteConfig.StoreURL', 'Store URL'))
183
+				->setDescription(_t(
184
+					'FoxyStripeSiteConfig.StoreURLDescription',
185
+					'The URL of your online store'
186
+				)),
187
+			TextField::create('ReceiptURL')
188
+				->setTitle(_t('FoxyStripeSiteConfig.ReceiptURL', 'Receipt URL'))
189
+				->setDescription(_t(
190
+					'FoxyStripeSiteConfig.ReceiptURLDescription',
191
+					'By default, FoxyCart sends customers back to the page referrer after completing a purchase. 
192 192
                             Instead, you can set a specific URL here.'
193
-                )),
194
-            TextField::create('StoreEmail')
195
-                ->setTitle(_t('FoxyStripeSiteConfig.StoreEmail', 'Store Email'))
196
-                ->setDescription(_t(
197
-                    'FoxyStripeSiteConfig.StoreEmailDescription',
198
-                    'This is the email address of your store. By default, this will be the from address for your 
193
+				)),
194
+			TextField::create('StoreEmail')
195
+				->setTitle(_t('FoxyStripeSiteConfig.StoreEmail', 'Store Email'))
196
+				->setDescription(_t(
197
+					'FoxyStripeSiteConfig.StoreEmailDescription',
198
+					'This is the email address of your store. By default, this will be the from address for your 
199 199
                             store receipts. '
200
-                )),
201
-            TextField::create('FromEmail')
202
-                ->setTitle(_t('FoxyStripeSiteConfig.FromEmail', 'From Email'))
203
-                ->setDescription(_t(
204
-                    'FoxyStripeSiteConfig.FromEmailDescription',
205
-                    'Used for when you want to specify a different from email than your store\'s email address'
206
-                )),
207
-            TextField::create('StorePostalCode', 'Postal Code'),
208
-            CountryDropdownField::create('StoreCountry', 'Country'),
209
-            TextField::create('StoreRegion', 'State/Region'),
210
-            TextField::create('StoreLocaleCode', 'Locale Code')
211
-                ->setDescription('example: en_US'),
212
-            TextField::create('StoreTimezone', 'Store timezone'),
213
-            TextField::create('StoreLogoURL', 'Logo URL')
214
-                ->setAttribute('placeholder', 'http://'),
215
-        ]);
216
-
217
-        $fields->addFieldsToTab('Root.Advanced', [
218
-            HeaderField::create('AdvanceHeader', _t(
219
-                'FoxyStripeSiteConfig.AdvancedHeader',
220
-                'Advanced Settings'
221
-            ), 3),
222
-            LiteralField::create('AdvancedIntro', _t(
223
-                'FoxyStripeSiteConfig.AdvancedIntro',
224
-                '<p>Maps to data in your 
200
+				)),
201
+			TextField::create('FromEmail')
202
+				->setTitle(_t('FoxyStripeSiteConfig.FromEmail', 'From Email'))
203
+				->setDescription(_t(
204
+					'FoxyStripeSiteConfig.FromEmailDescription',
205
+					'Used for when you want to specify a different from email than your store\'s email address'
206
+				)),
207
+			TextField::create('StorePostalCode', 'Postal Code'),
208
+			CountryDropdownField::create('StoreCountry', 'Country'),
209
+			TextField::create('StoreRegion', 'State/Region'),
210
+			TextField::create('StoreLocaleCode', 'Locale Code')
211
+				->setDescription('example: en_US'),
212
+			TextField::create('StoreTimezone', 'Store timezone'),
213
+			TextField::create('StoreLogoURL', 'Logo URL')
214
+				->setAttribute('placeholder', 'http://'),
215
+		]);
216
+
217
+		$fields->addFieldsToTab('Root.Advanced', [
218
+			HeaderField::create('AdvanceHeader', _t(
219
+				'FoxyStripeSiteConfig.AdvancedHeader',
220
+				'Advanced Settings'
221
+			), 3),
222
+			LiteralField::create('AdvancedIntro', _t(
223
+				'FoxyStripeSiteConfig.AdvancedIntro',
224
+				'<p>Maps to data in your 
225 225
                     <a href="https://admin.foxycart.com/admin.php?ThisAction=EditAdvancedFeatures" target="_blank">
226 226
                         FoxyCart advanced store settings
227 227
                     </a>.</p>'
228
-            )),
229
-            DropdownField::create('CheckoutType', 'Checkout Type', $this->getCheckoutTypes()),
230
-            CheckboxField::create('BccEmail', 'BCC Admin Email')
231
-                ->setDescription('bcc all receipts to store\'s email address'),
232
-            CheckboxField::create('UseWebhook', 'Use Webhook')
233
-                ->setDescription('record order history in CMS, allows customers to view their order history'),
234
-            ReadonlyField::create('WebhookURL', 'Webhook URL', self::getDataFeedLink()),
235
-            ReadonlyField::create('StoreKey', 'Webhook Key', self::getDataFeedLink()),
236
-            CheckboxField::create('CartValidation', 'Use cart validation'),
237
-            CheckboxField::create('UseSingleSignOn', 'Use single sign on')
238
-                ->setDescription('Sync user accounts between FoxyCart and your website'),
239
-            ReadonlyField::create('SingleSignOnURL', 'Single sign on URL', self::getSSOLink()),
240
-            CheckboxField::create('AllowMultiship', 'Allow multiple shipments per order'),
241
-        ]);
242
-
243
-        // configuration warning
244
-        if (FoxyCart::store_name_warning() !== null) {
245
-            $fields->insertBefore(LiteralField::create(
246
-                'StoreSubDomainHeaderWarning',
247
-                _t(
248
-                    'FoxyStripeSiteConfig.StoreSubDomainHeadingWarning',
249
-                    '<p class="message error">Store Domain must be entered below
228
+			)),
229
+			DropdownField::create('CheckoutType', 'Checkout Type', $this->getCheckoutTypes()),
230
+			CheckboxField::create('BccEmail', 'BCC Admin Email')
231
+				->setDescription('bcc all receipts to store\'s email address'),
232
+			CheckboxField::create('UseWebhook', 'Use Webhook')
233
+				->setDescription('record order history in CMS, allows customers to view their order history'),
234
+			ReadonlyField::create('WebhookURL', 'Webhook URL', self::getDataFeedLink()),
235
+			ReadonlyField::create('StoreKey', 'Webhook Key', self::getDataFeedLink()),
236
+			CheckboxField::create('CartValidation', 'Use cart validation'),
237
+			CheckboxField::create('UseSingleSignOn', 'Use single sign on')
238
+				->setDescription('Sync user accounts between FoxyCart and your website'),
239
+			ReadonlyField::create('SingleSignOnURL', 'Single sign on URL', self::getSSOLink()),
240
+			CheckboxField::create('AllowMultiship', 'Allow multiple shipments per order'),
241
+		]);
242
+
243
+		// configuration warning
244
+		if (FoxyCart::store_name_warning() !== null) {
245
+			$fields->insertBefore(LiteralField::create(
246
+				'StoreSubDomainHeaderWarning',
247
+				_t(
248
+					'FoxyStripeSiteConfig.StoreSubDomainHeadingWarning',
249
+					'<p class="message error">Store Domain must be entered below
250 250
                         </a></p>'
251
-                )
252
-            ), 'StoreDetails');
253
-        }
254
-
255
-        // products tab
256
-        $fields->addFieldsToTab('Root.Products', [
257
-            HeaderField::create('ProductHeader', _t(
258
-                'FoxyStripeSiteConfig.ProductHeader',
259
-                'Products'
260
-            ), 3),
261
-            CheckboxField::create('MultiGroup')
262
-                ->setTitle(_t('FoxyStripeSiteConfig.MultiGroup', 'Multiple Groups'))
263
-                ->setDescription(_t(
264
-                    'FoxyStripeSiteConfig.MultiGroupDescription',
265
-                    'Allows products to be shown in multiple Product Groups'
266
-                )),
267
-            HeaderField::create('ProductGroupHD', _t(
268
-                'FoxyStripeSiteConfig.ProductGroupHD',
269
-                'Product Groups'
270
-            ), 3),
271
-            NumericField::create('ProductLimit')
272
-                ->setTitle(_t('FoxyStripeSiteConfig.ProductLimit', 'Products per Page'))
273
-                ->setDescription(_t(
274
-                    'FoxyStripeSiteConfig.ProductLimitDescription',
275
-                    'Number of Products to show per page on a Product Group'
276
-                )),
277
-            HeaderField::create('ProductQuantityHD', _t(
278
-                'FoxyStripeSiteConfig.ProductQuantityHD',
279
-                'Product Form Max Quantity'
280
-            ), 3),
281
-            NumericField::create('MaxQuantity')
282
-                ->setTitle(_t('FoxyStripeSiteConfig.MaxQuantity', 'Max Quantity'))
283
-                ->setDescription(_t(
284
-                    'FoxyStripeSiteConfig.MaxQuantityDescription',
285
-                    'Sets max quantity for product form dropdown (add to cart form - default 10)'
286
-                )),
287
-        ]);
288
-
289
-        // categories tab
290
-        $fields->addFieldsToTab('Root.Categories', [
291
-            HeaderField::create('CategoryHD', _t('FoxyStripeSiteConfig.CategoryHD', 'FoxyStripe Categories'), 3),
292
-            LiteralField::create('CategoryDescrip', _t(
293
-                'FoxyStripeSiteConfig.CategoryDescrip',
294
-                '<p>FoxyCart Categories offer a way to give products additional behaviors that cannot be 
251
+				)
252
+			), 'StoreDetails');
253
+		}
254
+
255
+		// products tab
256
+		$fields->addFieldsToTab('Root.Products', [
257
+			HeaderField::create('ProductHeader', _t(
258
+				'FoxyStripeSiteConfig.ProductHeader',
259
+				'Products'
260
+			), 3),
261
+			CheckboxField::create('MultiGroup')
262
+				->setTitle(_t('FoxyStripeSiteConfig.MultiGroup', 'Multiple Groups'))
263
+				->setDescription(_t(
264
+					'FoxyStripeSiteConfig.MultiGroupDescription',
265
+					'Allows products to be shown in multiple Product Groups'
266
+				)),
267
+			HeaderField::create('ProductGroupHD', _t(
268
+				'FoxyStripeSiteConfig.ProductGroupHD',
269
+				'Product Groups'
270
+			), 3),
271
+			NumericField::create('ProductLimit')
272
+				->setTitle(_t('FoxyStripeSiteConfig.ProductLimit', 'Products per Page'))
273
+				->setDescription(_t(
274
+					'FoxyStripeSiteConfig.ProductLimitDescription',
275
+					'Number of Products to show per page on a Product Group'
276
+				)),
277
+			HeaderField::create('ProductQuantityHD', _t(
278
+				'FoxyStripeSiteConfig.ProductQuantityHD',
279
+				'Product Form Max Quantity'
280
+			), 3),
281
+			NumericField::create('MaxQuantity')
282
+				->setTitle(_t('FoxyStripeSiteConfig.MaxQuantity', 'Max Quantity'))
283
+				->setDescription(_t(
284
+					'FoxyStripeSiteConfig.MaxQuantityDescription',
285
+					'Sets max quantity for product form dropdown (add to cart form - default 10)'
286
+				)),
287
+		]);
288
+
289
+		// categories tab
290
+		$fields->addFieldsToTab('Root.Categories', [
291
+			HeaderField::create('CategoryHD', _t('FoxyStripeSiteConfig.CategoryHD', 'FoxyStripe Categories'), 3),
292
+			LiteralField::create('CategoryDescrip', _t(
293
+				'FoxyStripeSiteConfig.CategoryDescrip',
294
+				'<p>FoxyCart Categories offer a way to give products additional behaviors that cannot be 
295 295
                         accomplished by product options alone, including category specific coupon codes, 
296 296
                         shipping and handling fees, and email receipts. 
297 297
                         <a href="https://wiki.foxycart.com/v/2.0/categories" target="_blank">
@@ -300,262 +300,262 @@  discard block
 block discarded – undo
300 300
                         <p>Categories you\'ve created in FoxyStripe must also be created in your 
301 301
                             <a href="https://admin.foxycart.com/admin.php?ThisAction=ManageProductCategories" 
302 302
                                 target="_blank">FoxyCart Categories</a> admin panel.</p>'
303
-            )),
304
-            GridField::create(
305
-                'ProductCategory',
306
-                _t('FoxyStripeSiteConfig.ProductCategory', 'FoxyCart Categories'),
307
-                ProductCategory::get(),
308
-                GridFieldConfig_RecordEditor::create()
309
-            ),
310
-        ]);
311
-
312
-        // option groups tab
313
-        $fields->addFieldsToTab('Root.Groups', [
314
-            HeaderField::create('OptionGroupsHead', _t('FoxyStripeSiteConfig', 'Product Option Groups'), 3),
315
-            LiteralField::create('OptionGroupsDescrip', _t(
316
-                'FoxyStripeSiteConfig.OptionGroupsDescrip',
317
-                '<p>Product Option Groups allow you to name a set of product options.</p>'
318
-            )),
319
-            GridField::create(
320
-                'OptionGroup',
321
-                _t('FoxyStripeSiteConfig.OptionGroup', 'Product Option Groups'),
322
-                OptionGroup::get(),
323
-                GridFieldConfig_RecordEditor::create()
324
-            ),
325
-        ]);
326
-
327
-        // api tab
328
-        if (Permission::check('ADMIN')) {
329
-            $fields->addFieldsToTab('Root.API', [
330
-                HeaderField::create('APIHD', 'FoxyCart API Settings', 3),
331
-                CheckboxField::create('EnableAPI', 'Enable FoxyCart API'),
332
-                TextField::create('client_id', 'FoxyCart Client ID'),
333
-                TextField::create('client_secret', 'FoxyCart Client Secret'),
334
-                TextField::create('access_token', 'FoxyCart Access Token'),
335
-                TextField::create('refresh_token', 'FoxyCart Refresh Token'),
336
-            ]);
337
-        }
338
-
339
-        $fields->addFieldsToTab('Root.Template', [
340
-            HeaderField::create('TemplateHD', _t('FoxyStripeSiteConfig.TemplateHD', 'Template Options'), 3),
341
-            CheckboxField::create('EnableSidecart')
342
-                ->setDescription('Turns on the Sidebar cart. Uncheck to use the full page cart.'),
343
-        ]);
344
-
345
-        $this->extend('updateCMSFields', $fields);
346
-
347
-        return $fields;
348
-    }
349
-
350
-    /**
351
-     * @return FieldList
352
-     */
353
-    public function getCMSActions()
354
-    {
355
-        if (Permission::check('ADMIN') || Permission::check('EDIT_FOXYSTRIPE_SETTING')) {
356
-            $actions = new FieldList(
357
-                FormAction::create('save_foxystripe_setting', _t('FoxyStripeSetting.SAVE', 'Save'))
358
-                    ->addExtraClass('btn-primary font-icon-save')
359
-            );
360
-        } else {
361
-            $actions = FieldList::create();
362
-        }
363
-        $this->extend('updateCMSActions', $actions);
364
-
365
-        return $actions;
366
-    }
367
-
368
-    /**
369
-     * @throws \SilverStripe\ORM\ValidationException
370
-     */
371
-    public function requireDefaultRecords()
372
-    {
373
-        parent::requireDefaultRecords();
374
-        $config = self::current_foxystripe_setting();
375
-
376
-        if (!$config) {
377
-            self::make_foxystripe_setting();
378
-            DB::alteration_message('Added default FoxyStripe Setting', 'created');
379
-        }
380
-
381
-        if (!$config->StoreKey) {
382
-            $key = FoxyCart::setStoreKey();
383
-            while (!ctype_alnum($key)) {
384
-                $key = FoxyCart::setStoreKey();
385
-            }
386
-            $config->StoreKey = $key;
387
-            $config->write();
388
-            DB::alteration_message('Created FoxyCart Store Key ' . $key, 'created');
389
-        }
390
-    }
391
-
392
-    /**
393
-     * @return string
394
-     */
395
-    public function CMSEditLink()
396
-    {
397
-        return FoxyStripeAdmin::singleton()->Link();
398
-    }
399
-
400
-    /**
401
-     * @param null $member
402
-     *
403
-     * @return bool|int|null
404
-     */
405
-    public function canEdit($member = null)
406
-    {
407
-        if (!$member) {
408
-            $member = Security::getCurrentUser();
409
-        }
410
-
411
-        $extended = $this->extendedCan('canEdit', $member);
412
-        if ($extended !== null) {
413
-            return $extended;
414
-        }
415
-
416
-        return Permission::checkMember($member, 'EDIT_FOXYSTRIPE_SETTING');
417
-    }
418
-
419
-    /**
420
-     * @return array
421
-     */
422
-    public function providePermissions()
423
-    {
424
-        return [
425
-            'EDIT_FOXYSTRIPE_SETTING' => [
426
-                'name' => _t(
427
-                    'FoxyStripeSetting.EDIT_FOXYSTRIPE_SETTING',
428
-                    'Manage FoxyStripe settings'
429
-                ),
430
-                'category' => _t(
431
-                    'Permissions.PERMISSIONS_FOXYSTRIPE_SETTING',
432
-                    'FoxyStripe'
433
-                ),
434
-                'help' => _t(
435
-                    'FoxyStripeSetting.EDIT_PERMISSION_FOXYSTRIPE_SETTING',
436
-                    'Ability to edit the settings of a FoxyStripe Store.'
437
-                ),
438
-                'sort' => 400,
439
-            ],
440
-        ];
441
-    }
442
-
443
-    /**
444
-     * Get the current sites {@link GlobalSiteSetting}, and creates a new one
445
-     * through {@link make_global_config()} if none is found.
446
-     *
447
-     * @return FoxyStripeSetting|DataObject
448
-     * @throws \SilverStripe\ORM\ValidationException
449
-     */
450
-    public static function current_foxystripe_setting()
451
-    {
452
-        if ($config = self::get()->first()) {
453
-            return $config;
454
-        }
455
-
456
-        return self::make_foxystripe_setting();
457
-    }
458
-
459
-    /**
460
-     * Create {@link GlobalSiteSetting} with defaults from language file.
461
-     *
462
-     * @return static
463
-     */
464
-    public static function make_foxystripe_setting()
465
-    {
466
-        $config = self::create();
467
-        try {
468
-            $config->write();
469
-        } catch (ValidationException $e) {
470
-        }
471
-
472
-        return $config;
473
-    }
474
-
475
-    /**
476
-     * Add $GlobalConfig to all SSViewers.
477
-     */
478
-    public static function get_template_global_variables()
479
-    {
480
-        return [
481
-            'FoxyStripe' => 'current_foxystripe_setting',
482
-        ];
483
-    }
484
-
485
-    /**
486
-     * @return string
487
-     */
488
-    private static function getSSOLink()
489
-    {
490
-        return Director::absoluteBaseURL() . 'foxystripe/sso/';
491
-    }
492
-
493
-    /**
494
-     * @return string
495
-     */
496
-    private static function getDataFeedLink()
497
-    {
498
-        return Director::absoluteBaseURL() . 'foxystripe/';
499
-    }
500
-
501
-    /**
502
-     * @return array
503
-     */
504
-    public function getCheckoutTypes()
505
-    {
506
-        return [
507
-            'default_account' => 'Allow guest and customer accounts, default to account',
508
-            'default_guest' => 'Allow guest and customer accounts, default to guest',
509
-            'account_only' => 'Allow customer accounts only',
510
-            'guest_only' => 'Allow guests only',
511
-        ];
512
-    }
513
-
514
-    /**
515
-     * @return array
516
-     */
517
-    public function getDataMap()
518
-    {
519
-        return [
520
-            'store_name' => $this->StoreTitle,
521
-            'store_domain' => $this->StoreName,
522
-            'store_url' => $this->StoreURL,
523
-            'receipt_continue_url' => $this->ReceiptURL,
524
-            'store_email' => $this->StoreEmail,
525
-            'from_email' => $this->FromEmail,
526
-            'postal_code' => $this->StorePostalCode,
527
-            'country' => $this->StoreCountry,
528
-            'region' => $this->StoreRegion,
529
-            'locale_code' => $this->StoreLocaleCode,
530
-            'logo_url' => $this->StoreLogoURL,
531
-            'checkout_type' => $this->CheckoutType,
532
-            'bcc_on_receipt_email' => $this->BccEmail,
533
-            'use_webhook' => $this->UseWebhook,
534
-            'webhook_url' => $this->getDataFeedLink(),
535
-            'webhook_key' => $this->StoreKey,
536
-            'use_cart_validation' => $this->CartValidation,
537
-            'use_single_sign_on' => $this->UseSingleSignOn,
538
-            'single_sign_on_url' => $this->getSSOLink(),
539
-            'customer_password_hash_type' => 'sha1_salted_suffix',
540
-            'customer_password_hash_config' => 40,
541
-            'features_multiship' => $this->AllowMultiship,
542
-            //'timezone' => $this->StoreTimezone,
543
-        ];
544
-    }
545
-
546
-    /**
547
-     * if StoreTitle is empty, grab values from FoxyCart.
548
-     *
549
-     * example of 2 way sync for future reference
550
-     *
551
-     * @throws \Psr\Container\NotFoundExceptionInterface
552
-     */
553
-    public function onBeforeWrite()
554
-    {
555
-        parent::onBeforeWrite();
556
-
557
-        if ($this->ID && !$this->StoreTitle && $this->access_token) {
558
-            /*
303
+			)),
304
+			GridField::create(
305
+				'ProductCategory',
306
+				_t('FoxyStripeSiteConfig.ProductCategory', 'FoxyCart Categories'),
307
+				ProductCategory::get(),
308
+				GridFieldConfig_RecordEditor::create()
309
+			),
310
+		]);
311
+
312
+		// option groups tab
313
+		$fields->addFieldsToTab('Root.Groups', [
314
+			HeaderField::create('OptionGroupsHead', _t('FoxyStripeSiteConfig', 'Product Option Groups'), 3),
315
+			LiteralField::create('OptionGroupsDescrip', _t(
316
+				'FoxyStripeSiteConfig.OptionGroupsDescrip',
317
+				'<p>Product Option Groups allow you to name a set of product options.</p>'
318
+			)),
319
+			GridField::create(
320
+				'OptionGroup',
321
+				_t('FoxyStripeSiteConfig.OptionGroup', 'Product Option Groups'),
322
+				OptionGroup::get(),
323
+				GridFieldConfig_RecordEditor::create()
324
+			),
325
+		]);
326
+
327
+		// api tab
328
+		if (Permission::check('ADMIN')) {
329
+			$fields->addFieldsToTab('Root.API', [
330
+				HeaderField::create('APIHD', 'FoxyCart API Settings', 3),
331
+				CheckboxField::create('EnableAPI', 'Enable FoxyCart API'),
332
+				TextField::create('client_id', 'FoxyCart Client ID'),
333
+				TextField::create('client_secret', 'FoxyCart Client Secret'),
334
+				TextField::create('access_token', 'FoxyCart Access Token'),
335
+				TextField::create('refresh_token', 'FoxyCart Refresh Token'),
336
+			]);
337
+		}
338
+
339
+		$fields->addFieldsToTab('Root.Template', [
340
+			HeaderField::create('TemplateHD', _t('FoxyStripeSiteConfig.TemplateHD', 'Template Options'), 3),
341
+			CheckboxField::create('EnableSidecart')
342
+				->setDescription('Turns on the Sidebar cart. Uncheck to use the full page cart.'),
343
+		]);
344
+
345
+		$this->extend('updateCMSFields', $fields);
346
+
347
+		return $fields;
348
+	}
349
+
350
+	/**
351
+	 * @return FieldList
352
+	 */
353
+	public function getCMSActions()
354
+	{
355
+		if (Permission::check('ADMIN') || Permission::check('EDIT_FOXYSTRIPE_SETTING')) {
356
+			$actions = new FieldList(
357
+				FormAction::create('save_foxystripe_setting', _t('FoxyStripeSetting.SAVE', 'Save'))
358
+					->addExtraClass('btn-primary font-icon-save')
359
+			);
360
+		} else {
361
+			$actions = FieldList::create();
362
+		}
363
+		$this->extend('updateCMSActions', $actions);
364
+
365
+		return $actions;
366
+	}
367
+
368
+	/**
369
+	 * @throws \SilverStripe\ORM\ValidationException
370
+	 */
371
+	public function requireDefaultRecords()
372
+	{
373
+		parent::requireDefaultRecords();
374
+		$config = self::current_foxystripe_setting();
375
+
376
+		if (!$config) {
377
+			self::make_foxystripe_setting();
378
+			DB::alteration_message('Added default FoxyStripe Setting', 'created');
379
+		}
380
+
381
+		if (!$config->StoreKey) {
382
+			$key = FoxyCart::setStoreKey();
383
+			while (!ctype_alnum($key)) {
384
+				$key = FoxyCart::setStoreKey();
385
+			}
386
+			$config->StoreKey = $key;
387
+			$config->write();
388
+			DB::alteration_message('Created FoxyCart Store Key ' . $key, 'created');
389
+		}
390
+	}
391
+
392
+	/**
393
+	 * @return string
394
+	 */
395
+	public function CMSEditLink()
396
+	{
397
+		return FoxyStripeAdmin::singleton()->Link();
398
+	}
399
+
400
+	/**
401
+	 * @param null $member
402
+	 *
403
+	 * @return bool|int|null
404
+	 */
405
+	public function canEdit($member = null)
406
+	{
407
+		if (!$member) {
408
+			$member = Security::getCurrentUser();
409
+		}
410
+
411
+		$extended = $this->extendedCan('canEdit', $member);
412
+		if ($extended !== null) {
413
+			return $extended;
414
+		}
415
+
416
+		return Permission::checkMember($member, 'EDIT_FOXYSTRIPE_SETTING');
417
+	}
418
+
419
+	/**
420
+	 * @return array
421
+	 */
422
+	public function providePermissions()
423
+	{
424
+		return [
425
+			'EDIT_FOXYSTRIPE_SETTING' => [
426
+				'name' => _t(
427
+					'FoxyStripeSetting.EDIT_FOXYSTRIPE_SETTING',
428
+					'Manage FoxyStripe settings'
429
+				),
430
+				'category' => _t(
431
+					'Permissions.PERMISSIONS_FOXYSTRIPE_SETTING',
432
+					'FoxyStripe'
433
+				),
434
+				'help' => _t(
435
+					'FoxyStripeSetting.EDIT_PERMISSION_FOXYSTRIPE_SETTING',
436
+					'Ability to edit the settings of a FoxyStripe Store.'
437
+				),
438
+				'sort' => 400,
439
+			],
440
+		];
441
+	}
442
+
443
+	/**
444
+	 * Get the current sites {@link GlobalSiteSetting}, and creates a new one
445
+	 * through {@link make_global_config()} if none is found.
446
+	 *
447
+	 * @return FoxyStripeSetting|DataObject
448
+	 * @throws \SilverStripe\ORM\ValidationException
449
+	 */
450
+	public static function current_foxystripe_setting()
451
+	{
452
+		if ($config = self::get()->first()) {
453
+			return $config;
454
+		}
455
+
456
+		return self::make_foxystripe_setting();
457
+	}
458
+
459
+	/**
460
+	 * Create {@link GlobalSiteSetting} with defaults from language file.
461
+	 *
462
+	 * @return static
463
+	 */
464
+	public static function make_foxystripe_setting()
465
+	{
466
+		$config = self::create();
467
+		try {
468
+			$config->write();
469
+		} catch (ValidationException $e) {
470
+		}
471
+
472
+		return $config;
473
+	}
474
+
475
+	/**
476
+	 * Add $GlobalConfig to all SSViewers.
477
+	 */
478
+	public static function get_template_global_variables()
479
+	{
480
+		return [
481
+			'FoxyStripe' => 'current_foxystripe_setting',
482
+		];
483
+	}
484
+
485
+	/**
486
+	 * @return string
487
+	 */
488
+	private static function getSSOLink()
489
+	{
490
+		return Director::absoluteBaseURL() . 'foxystripe/sso/';
491
+	}
492
+
493
+	/**
494
+	 * @return string
495
+	 */
496
+	private static function getDataFeedLink()
497
+	{
498
+		return Director::absoluteBaseURL() . 'foxystripe/';
499
+	}
500
+
501
+	/**
502
+	 * @return array
503
+	 */
504
+	public function getCheckoutTypes()
505
+	{
506
+		return [
507
+			'default_account' => 'Allow guest and customer accounts, default to account',
508
+			'default_guest' => 'Allow guest and customer accounts, default to guest',
509
+			'account_only' => 'Allow customer accounts only',
510
+			'guest_only' => 'Allow guests only',
511
+		];
512
+	}
513
+
514
+	/**
515
+	 * @return array
516
+	 */
517
+	public function getDataMap()
518
+	{
519
+		return [
520
+			'store_name' => $this->StoreTitle,
521
+			'store_domain' => $this->StoreName,
522
+			'store_url' => $this->StoreURL,
523
+			'receipt_continue_url' => $this->ReceiptURL,
524
+			'store_email' => $this->StoreEmail,
525
+			'from_email' => $this->FromEmail,
526
+			'postal_code' => $this->StorePostalCode,
527
+			'country' => $this->StoreCountry,
528
+			'region' => $this->StoreRegion,
529
+			'locale_code' => $this->StoreLocaleCode,
530
+			'logo_url' => $this->StoreLogoURL,
531
+			'checkout_type' => $this->CheckoutType,
532
+			'bcc_on_receipt_email' => $this->BccEmail,
533
+			'use_webhook' => $this->UseWebhook,
534
+			'webhook_url' => $this->getDataFeedLink(),
535
+			'webhook_key' => $this->StoreKey,
536
+			'use_cart_validation' => $this->CartValidation,
537
+			'use_single_sign_on' => $this->UseSingleSignOn,
538
+			'single_sign_on_url' => $this->getSSOLink(),
539
+			'customer_password_hash_type' => 'sha1_salted_suffix',
540
+			'customer_password_hash_config' => 40,
541
+			'features_multiship' => $this->AllowMultiship,
542
+			//'timezone' => $this->StoreTimezone,
543
+		];
544
+	}
545
+
546
+	/**
547
+	 * if StoreTitle is empty, grab values from FoxyCart.
548
+	 *
549
+	 * example of 2 way sync for future reference
550
+	 *
551
+	 * @throws \Psr\Container\NotFoundExceptionInterface
552
+	 */
553
+	public function onBeforeWrite()
554
+	{
555
+		parent::onBeforeWrite();
556
+
557
+		if ($this->ID && !$this->StoreTitle && $this->access_token) {
558
+			/*
559 559
             if ($fc = new FoxyStripeClient()) {
560 560
                 $client = $fc->getClient();
561 561
                 $errors = [];
@@ -570,20 +570,20 @@  discard block
 block discarded – undo
570 570
                 }
571 571
             }
572 572
             */
573
-        }
574
-    }
575
-
576
-    /**
577
-     * @throws \SilverStripe\ORM\ValidationException
578
-     */
579
-    public function onAfterWrite()
580
-    {
581
-        parent::onAfterWrite();
582
-
583
-        if (FoxyStripeClient::is_valid() && $this->isChanged()) {
584
-            if ($fc = new FoxyStripeClient()) {
585
-                $fc->updateStore($this->getDataMap());
586
-            }
587
-        }
588
-    }
573
+		}
574
+	}
575
+
576
+	/**
577
+	 * @throws \SilverStripe\ORM\ValidationException
578
+	 */
579
+	public function onAfterWrite()
580
+	{
581
+		parent::onAfterWrite();
582
+
583
+		if (FoxyStripeClient::is_valid() && $this->isChanged()) {
584
+			if ($fc = new FoxyStripeClient()) {
585
+				$fc->updateStore($this->getDataMap());
586
+			}
587
+		}
588
+	}
589 589
 }
Please login to merge, or discard this patch.
src/ORM/FoxyStripePageExtension.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -18,7 +18,7 @@
 block discarded – undo
18 18
 
19 19
         if ($config->EnableSidecart) {
20 20
             Requirements::javascript(
21
-                "https://cdn.foxycart.com/" . FoxyCart::getFoxyCartStoreName() . "/loader.js",
21
+                "https://cdn.foxycart.com/".FoxyCart::getFoxyCartStoreName()."/loader.js",
22 22
                 [
23 23
                     "async" => true,
24 24
                     "defer" => true,
Please login to merge, or discard this patch.
Indentation   +16 added lines, -16 removed lines patch added patch discarded remove patch
@@ -9,21 +9,21 @@
 block discarded – undo
9 9
 
10 10
 class FoxyStripePageExtension extends Extension
11 11
 {
12
-    /**
13
-     * @throws \SilverStripe\ORM\ValidationException
14
-     */
15
-    public function onAfterInit()
16
-    {
17
-        $config = FoxyStripeSetting::current_foxystripe_setting();
12
+	/**
13
+	 * @throws \SilverStripe\ORM\ValidationException
14
+	 */
15
+	public function onAfterInit()
16
+	{
17
+		$config = FoxyStripeSetting::current_foxystripe_setting();
18 18
 
19
-        if ($config->EnableSidecart) {
20
-            Requirements::javascript(
21
-                "https://cdn.foxycart.com/" . FoxyCart::getFoxyCartStoreName() . "/loader.js",
22
-                [
23
-                    "async" => true,
24
-                    "defer" => true,
25
-                ]
26
-            );
27
-        }
28
-    }
19
+		if ($config->EnableSidecart) {
20
+			Requirements::javascript(
21
+				"https://cdn.foxycart.com/" . FoxyCart::getFoxyCartStoreName() . "/loader.js",
22
+				[
23
+					"async" => true,
24
+					"defer" => true,
25
+				]
26
+			);
27
+		}
28
+	}
29 29
 }
Please login to merge, or discard this patch.
src/Page/ProductPage.php 2 patches
Spacing   +4 added lines, -5 removed lines patch added patch discarded remove patch
@@ -226,9 +226,9 @@  discard block
 block discarded – undo
226 226
      */
227 227
     public function getCMSFields()
228 228
     {
229
-        $this->beforeUpdateCMSFields(function (FieldList $fields) {
229
+        $this->beforeUpdateCMSFields(function(FieldList $fields) {
230 230
             // Cateogry Dropdown field w/ add new
231
-            $source = function () {
231
+            $source = function() {
232 232
                 return ProductCategory::get()->map()->toArray();
233 233
             };
234 234
             $catField = DropdownField::create('CategoryID', _t('ProductPage.Category', 'FoxyCart Category'), $source())
@@ -368,7 +368,7 @@  discard block
 block discarded – undo
368 368
             $product = self::get()->byID($this->ID);
369 369
             if (isset($product->ParentID)) {
370 370
                 $origParent = $product->ParentID;
371
-            } else {
371
+            }else {
372 372
                 $origParent = null;
373 373
             }
374 374
             $currentParent = $this->ParentID;
@@ -448,8 +448,7 @@  discard block
 block discarded – undo
448 448
         $optionName = ($optionName !== null) ? preg_replace('/\s/', '_', $optionName) : $optionName;
449 449
 
450 450
         return (FoxyStripeSetting::current_foxystripe_setting()->CartValidation)
451
-            ? \FoxyCart_Helper::fc_hash_value($productCode, $optionName, $optionValue, $method, $output, $urlEncode) :
452
-            $optionValue;
451
+            ? \FoxyCart_Helper::fc_hash_value($productCode, $optionName, $optionValue, $method, $output, $urlEncode) : $optionValue;
453 452
     }
454 453
 
455 454
     /**
Please login to merge, or discard this patch.
Indentation   +463 added lines, -463 removed lines patch added patch discarded remove patch
@@ -56,189 +56,189 @@  discard block
 block discarded – undo
56 56
  */
57 57
 class ProductPage extends \Page implements PermissionProvider
58 58
 {
59
-    /**
60
-     * @var string
61
-     */
62
-    private static $default_parent = ProductHolder::class;
63
-
64
-    /**
65
-     * @var bool
66
-     */
67
-    private static $can_be_root = false;
68
-
69
-    /**
70
-     * @var array
71
-     */
72
-    private static $db = [
73
-        'Price' => 'Currency',
74
-        'Weight' => 'Decimal',
75
-        'Code' => 'Varchar(100)',
76
-        'ReceiptTitle' => 'HTMLVarchar(255)',
77
-        'Available' => 'Boolean',
78
-    ];
79
-
80
-    /**
81
-     * @var array
82
-     */
83
-    private static $has_one = [
84
-        'Category' => ProductCategory::class,
85
-    ];
86
-
87
-    /**
88
-     * @var array
89
-     */
90
-    private static $has_many = [
91
-        'ProductOptions' => OptionItem::class,
92
-        'OrderDetails' => OrderDetail::class,
93
-    ];
94
-
95
-    /**
96
-     * @var array
97
-     */
98
-    private static $many_many = [
99
-        'Images' => Image::class,
100
-    ];
101
-
102
-    /**
103
-     * @var array
104
-     */
105
-    private static $many_many_extraFields = [
106
-        'Images' => [
107
-            'SortOrder' => 'Int',
108
-        ],
109
-    ];
110
-
111
-    /**
112
-     * @var array
113
-     */
114
-    private static $owns = [
115
-        'Images',
116
-    ];
117
-
118
-    /**
119
-     * @var array
120
-     */
121
-    private static $belongs_many_many = [
122
-        'ProductHolders' => ProductHolder::class,
123
-    ];
124
-
125
-    /**
126
-     * @var string
127
-     */
128
-    private static $singular_name = 'Product';
129
-
130
-    /**
131
-     * @var string
132
-     */
133
-    private static $plural_name = 'Products';
134
-
135
-    /**
136
-     * @var string
137
-     */
138
-    private static $description = 'A product that can be added to the shopping cart';
139
-
140
-    /**
141
-     * @var array
142
-     */
143
-    private static $indexes = [
144
-        'Code' => [
145
-            'type' => 'unique',
146
-            'columns' => ['Code'],
147
-        ],
148
-    ];
149
-
150
-    /**
151
-     * @var array
152
-     */
153
-    private static $defaults = [
154
-        'ShowInMenus' => false,
155
-        'Available' => true,
156
-        'Weight' => '0.0',
157
-    ];
158
-
159
-    /**
160
-     * @var array
161
-     */
162
-    private static $summary_fields = [
163
-        'Image.CMSThumbnail',
164
-        'Title',
165
-        'Code',
166
-        'Price.Nice',
167
-        'Category.Title',
168
-    ];
169
-
170
-    /**
171
-     * @var array
172
-     */
173
-    private static $searchable_fields = [
174
-        'Title',
175
-        'Code',
176
-        'Available',
177
-        'Category.ID',
178
-    ];
179
-
180
-    /**
181
-     * @var string
182
-     */
183
-    private static $table_name = 'ProductPage';
184
-
185
-    /**
186
-     * Construct a new ProductPage.
187
-     *
188
-     * @param array|null $record Used internally for rehydrating an object from database content.
189
-     *                           Bypasses setters on this class, and hence should not be used
190
-     *                           for populating data on new records.
191
-     * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods.
192
-     *                             Singletons don't have their defaults set.
193
-     * @param array $queryParams List of DataQuery params necessary to lazy load, or load related objects.
194
-     */
195
-    public function __construct($record = null, $isSingleton = false, $queryParams = [])
196
-    {
197
-        parent::__construct($record, $isSingleton, $queryParams);
198
-
199
-        if (Controller::has_curr()) {
200
-            if (Controller::curr() instanceof ContentController) {
201
-                Requirements::javascript('dynamic/foxystripe: javascript/quantity.js');
202
-                Requirements::css('dynamic/foxystripe: client/dist/css/quantityfield.css');
203
-            }
204
-        }
205
-    }
206
-
207
-    /**
208
-     * @param bool $includerelations
209
-     *
210
-     * @return array
211
-     */
212
-    public function fieldLabels($includerelations = true)
213
-    {
214
-        $labels = parent::fieldLabels();
215
-
216
-        $labels['Title'] = _t('ProductPage.TitleLabel', 'Name');
217
-        $labels['Code'] = _t('ProductPage.CodeLabel', 'Code');
218
-        $labels['Price.Nice'] = _t('ProductPage.PriceLabel', 'Price');
219
-        $labels['Available.Nice'] = _t('ProductPage.AvailableLabel', 'Available');
220
-        $labels['Category.ID'] = _t('ProductPage.IDLabel', 'Category');
221
-        $labels['Category.Title'] = _t('ProductPage.CategoryTitleLabel', 'Category');
222
-        $labels['Image.CMSThumbnail'] = _t('ProductPage.ImageLabel', 'Image');
223
-
224
-        return $labels;
225
-    }
226
-
227
-    /**
228
-     * @return \SilverStripe\Forms\FieldList
229
-     */
230
-    public function getCMSFields()
231
-    {
232
-        $this->beforeUpdateCMSFields(function (FieldList $fields) {
233
-            // Cateogry Dropdown field w/ add new
234
-            $source = function () {
235
-                return ProductCategory::get()->map()->toArray();
236
-            };
237
-            $catField = DropdownField::create('CategoryID', _t('ProductPage.Category', 'FoxyCart Category'), $source())
238
-                ->setEmptyString('')
239
-                ->setDescription(_t(
240
-                    'ProductPage.CategoryDescription',
241
-                    'Required, must also exist in 
59
+	/**
60
+	 * @var string
61
+	 */
62
+	private static $default_parent = ProductHolder::class;
63
+
64
+	/**
65
+	 * @var bool
66
+	 */
67
+	private static $can_be_root = false;
68
+
69
+	/**
70
+	 * @var array
71
+	 */
72
+	private static $db = [
73
+		'Price' => 'Currency',
74
+		'Weight' => 'Decimal',
75
+		'Code' => 'Varchar(100)',
76
+		'ReceiptTitle' => 'HTMLVarchar(255)',
77
+		'Available' => 'Boolean',
78
+	];
79
+
80
+	/**
81
+	 * @var array
82
+	 */
83
+	private static $has_one = [
84
+		'Category' => ProductCategory::class,
85
+	];
86
+
87
+	/**
88
+	 * @var array
89
+	 */
90
+	private static $has_many = [
91
+		'ProductOptions' => OptionItem::class,
92
+		'OrderDetails' => OrderDetail::class,
93
+	];
94
+
95
+	/**
96
+	 * @var array
97
+	 */
98
+	private static $many_many = [
99
+		'Images' => Image::class,
100
+	];
101
+
102
+	/**
103
+	 * @var array
104
+	 */
105
+	private static $many_many_extraFields = [
106
+		'Images' => [
107
+			'SortOrder' => 'Int',
108
+		],
109
+	];
110
+
111
+	/**
112
+	 * @var array
113
+	 */
114
+	private static $owns = [
115
+		'Images',
116
+	];
117
+
118
+	/**
119
+	 * @var array
120
+	 */
121
+	private static $belongs_many_many = [
122
+		'ProductHolders' => ProductHolder::class,
123
+	];
124
+
125
+	/**
126
+	 * @var string
127
+	 */
128
+	private static $singular_name = 'Product';
129
+
130
+	/**
131
+	 * @var string
132
+	 */
133
+	private static $plural_name = 'Products';
134
+
135
+	/**
136
+	 * @var string
137
+	 */
138
+	private static $description = 'A product that can be added to the shopping cart';
139
+
140
+	/**
141
+	 * @var array
142
+	 */
143
+	private static $indexes = [
144
+		'Code' => [
145
+			'type' => 'unique',
146
+			'columns' => ['Code'],
147
+		],
148
+	];
149
+
150
+	/**
151
+	 * @var array
152
+	 */
153
+	private static $defaults = [
154
+		'ShowInMenus' => false,
155
+		'Available' => true,
156
+		'Weight' => '0.0',
157
+	];
158
+
159
+	/**
160
+	 * @var array
161
+	 */
162
+	private static $summary_fields = [
163
+		'Image.CMSThumbnail',
164
+		'Title',
165
+		'Code',
166
+		'Price.Nice',
167
+		'Category.Title',
168
+	];
169
+
170
+	/**
171
+	 * @var array
172
+	 */
173
+	private static $searchable_fields = [
174
+		'Title',
175
+		'Code',
176
+		'Available',
177
+		'Category.ID',
178
+	];
179
+
180
+	/**
181
+	 * @var string
182
+	 */
183
+	private static $table_name = 'ProductPage';
184
+
185
+	/**
186
+	 * Construct a new ProductPage.
187
+	 *
188
+	 * @param array|null $record Used internally for rehydrating an object from database content.
189
+	 *                           Bypasses setters on this class, and hence should not be used
190
+	 *                           for populating data on new records.
191
+	 * @param boolean $isSingleton This this to true if this is a singleton() object, a stub for calling methods.
192
+	 *                             Singletons don't have their defaults set.
193
+	 * @param array $queryParams List of DataQuery params necessary to lazy load, or load related objects.
194
+	 */
195
+	public function __construct($record = null, $isSingleton = false, $queryParams = [])
196
+	{
197
+		parent::__construct($record, $isSingleton, $queryParams);
198
+
199
+		if (Controller::has_curr()) {
200
+			if (Controller::curr() instanceof ContentController) {
201
+				Requirements::javascript('dynamic/foxystripe: javascript/quantity.js');
202
+				Requirements::css('dynamic/foxystripe: client/dist/css/quantityfield.css');
203
+			}
204
+		}
205
+	}
206
+
207
+	/**
208
+	 * @param bool $includerelations
209
+	 *
210
+	 * @return array
211
+	 */
212
+	public function fieldLabels($includerelations = true)
213
+	{
214
+		$labels = parent::fieldLabels();
215
+
216
+		$labels['Title'] = _t('ProductPage.TitleLabel', 'Name');
217
+		$labels['Code'] = _t('ProductPage.CodeLabel', 'Code');
218
+		$labels['Price.Nice'] = _t('ProductPage.PriceLabel', 'Price');
219
+		$labels['Available.Nice'] = _t('ProductPage.AvailableLabel', 'Available');
220
+		$labels['Category.ID'] = _t('ProductPage.IDLabel', 'Category');
221
+		$labels['Category.Title'] = _t('ProductPage.CategoryTitleLabel', 'Category');
222
+		$labels['Image.CMSThumbnail'] = _t('ProductPage.ImageLabel', 'Image');
223
+
224
+		return $labels;
225
+	}
226
+
227
+	/**
228
+	 * @return \SilverStripe\Forms\FieldList
229
+	 */
230
+	public function getCMSFields()
231
+	{
232
+		$this->beforeUpdateCMSFields(function (FieldList $fields) {
233
+			// Cateogry Dropdown field w/ add new
234
+			$source = function () {
235
+				return ProductCategory::get()->map()->toArray();
236
+			};
237
+			$catField = DropdownField::create('CategoryID', _t('ProductPage.Category', 'FoxyCart Category'), $source())
238
+				->setEmptyString('')
239
+				->setDescription(_t(
240
+					'ProductPage.CategoryDescription',
241
+					'Required, must also exist in 
242 242
                     <a href="https://admin.foxycart.com/admin.php?ThisAction=ManageProductCategories" target="_blank">
243 243
                         FoxyCart Categories
244 244
                     </a>.
@@ -246,119 +246,119 @@  discard block
 block discarded – undo
246 246
                         <a href="admin/settings">
247 247
                             Settings > FoxyStripe > Categories
248 248
                         </a>'
249
-                ));
250
-            if (class_exists('QuickAddNewExtension')) {
251
-                $catField->useAddNew('ProductCategory', $source);
252
-            }
253
-
254
-            $fields->addFieldsToTab(
255
-                'Root.Main',
256
-                [
257
-                    TextField::create('Code')
258
-                        ->setTitle(_t('ProductPage.Code', 'Product Code'))
259
-                        ->setDescription(_t(
260
-                            'ProductPage.CodeDescription',
261
-                            'Required, must be unique. Product identifier used by FoxyCart in transactions'
262
-                        )),
263
-                    CurrencyField::create('Price')
264
-                        ->setTitle(_t('ProductPage.Price', 'Price'))
265
-                        ->setDescription(_t(
266
-                            'ProductPage.PriceDescription',
267
-                            'Base price for this product. Can be modified using Product Options'
268
-                        )),
269
-                    NumericField::create('Weight')
270
-                        ->setTitle(_t('ProductPage.Weight', 'Weight'))
271
-                        ->setDescription(_t(
272
-                            'ProductPage.WeightDescription',
273
-                            'Base weight for this product in lbs. Can be modified using Product Options'
274
-                        ))
275
-                        ->setScale(2),
276
-                    $catField,
277
-                ],
278
-                'Content'
279
-            );
280
-
281
-            // Product Options field
282
-            $config = GridFieldConfig_RelationEditor::create();
283
-            $config->addComponent(new GridFieldOrderableRows('SortOrder'));
284
-            $products = $this->ProductOptions()->sort('SortOrder');
285
-            $config->removeComponentsByType(GridFieldAddExistingAutocompleter::class);
286
-            $prodOptField = GridField::create(
287
-                'ProductOptions',
288
-                _t('ProductPage.ProductOptions', 'Options'),
289
-                $products,
290
-                $config
291
-            );
292
-
293
-            // Details tab
294
-            $fields->addFieldsToTab('Root.Details', [
295
-                CheckboxField::create('Available')
296
-                    ->setTitle(_t('ProductPage.Available', 'Available for purchase'))
297
-                    ->setDescription(_t(
298
-                        'ProductPage.AvailableDescription',
299
-                        'If unchecked, will remove "Add to Cart" form and instead display "Currently unavailable"'
300
-                    )),
301
-                TextField::create('ReceiptTitle')
302
-                    ->setTitle(_t('ProductPage.ReceiptTitle', 'Product Title for Receipt'))
303
-                    ->setDescription(_t(
304
-                        'ProductPage.ReceiptTitleDescription',
305
-                        'Optional'
306
-                    )),
307
-            ]);
308
-
309
-            // Options Tab
310
-            $fields->addFieldsToTab('Root.Options', [
311
-                $prodOptField
312
-                    ->setDescription(_t(
313
-                        'Page.OptionsDescrip',
314
-                        '<p>Product Options allow products to be customized by attributes such as size or color.
249
+				));
250
+			if (class_exists('QuickAddNewExtension')) {
251
+				$catField->useAddNew('ProductCategory', $source);
252
+			}
253
+
254
+			$fields->addFieldsToTab(
255
+				'Root.Main',
256
+				[
257
+					TextField::create('Code')
258
+						->setTitle(_t('ProductPage.Code', 'Product Code'))
259
+						->setDescription(_t(
260
+							'ProductPage.CodeDescription',
261
+							'Required, must be unique. Product identifier used by FoxyCart in transactions'
262
+						)),
263
+					CurrencyField::create('Price')
264
+						->setTitle(_t('ProductPage.Price', 'Price'))
265
+						->setDescription(_t(
266
+							'ProductPage.PriceDescription',
267
+							'Base price for this product. Can be modified using Product Options'
268
+						)),
269
+					NumericField::create('Weight')
270
+						->setTitle(_t('ProductPage.Weight', 'Weight'))
271
+						->setDescription(_t(
272
+							'ProductPage.WeightDescription',
273
+							'Base weight for this product in lbs. Can be modified using Product Options'
274
+						))
275
+						->setScale(2),
276
+					$catField,
277
+				],
278
+				'Content'
279
+			);
280
+
281
+			// Product Options field
282
+			$config = GridFieldConfig_RelationEditor::create();
283
+			$config->addComponent(new GridFieldOrderableRows('SortOrder'));
284
+			$products = $this->ProductOptions()->sort('SortOrder');
285
+			$config->removeComponentsByType(GridFieldAddExistingAutocompleter::class);
286
+			$prodOptField = GridField::create(
287
+				'ProductOptions',
288
+				_t('ProductPage.ProductOptions', 'Options'),
289
+				$products,
290
+				$config
291
+			);
292
+
293
+			// Details tab
294
+			$fields->addFieldsToTab('Root.Details', [
295
+				CheckboxField::create('Available')
296
+					->setTitle(_t('ProductPage.Available', 'Available for purchase'))
297
+					->setDescription(_t(
298
+						'ProductPage.AvailableDescription',
299
+						'If unchecked, will remove "Add to Cart" form and instead display "Currently unavailable"'
300
+					)),
301
+				TextField::create('ReceiptTitle')
302
+					->setTitle(_t('ProductPage.ReceiptTitle', 'Product Title for Receipt'))
303
+					->setDescription(_t(
304
+						'ProductPage.ReceiptTitleDescription',
305
+						'Optional'
306
+					)),
307
+			]);
308
+
309
+			// Options Tab
310
+			$fields->addFieldsToTab('Root.Options', [
311
+				$prodOptField
312
+					->setDescription(_t(
313
+						'Page.OptionsDescrip',
314
+						'<p>Product Options allow products to be customized by attributes such as size or color.
315 315
                     Options can also modify the product\'s price, weight or code.<br></p>'
316
-                    )),
317
-            ]);
318
-
319
-            // Images tab
320
-            $images = SortableUploadField::create('Images')
321
-                ->setSortColumn('SortOrder')
322
-                ->setIsMultiUpload(true)
323
-                ->setAllowedFileCategories('image')
324
-                ->setFolderName('Uploads/Products/Images');
325
-
326
-            $fields->addFieldsToTab('Root.Images', [
327
-                $images,
328
-            ]);
329
-
330
-            if (FoxyCart::store_name_warning() !== null) {
331
-                $fields->addFieldToTab('Root.Main', LiteralField::create('StoreSubDomainHeaderWarning', _t(
332
-                    'ProductPage.StoreSubDomainHeaderWarning',
333
-                    '<p class="message error">Store sub-domain must be entered in the 
316
+					)),
317
+			]);
318
+
319
+			// Images tab
320
+			$images = SortableUploadField::create('Images')
321
+				->setSortColumn('SortOrder')
322
+				->setIsMultiUpload(true)
323
+				->setAllowedFileCategories('image')
324
+				->setFolderName('Uploads/Products/Images');
325
+
326
+			$fields->addFieldsToTab('Root.Images', [
327
+				$images,
328
+			]);
329
+
330
+			if (FoxyCart::store_name_warning() !== null) {
331
+				$fields->addFieldToTab('Root.Main', LiteralField::create('StoreSubDomainHeaderWarning', _t(
332
+					'ProductPage.StoreSubDomainHeaderWarning',
333
+					'<p class="message error">Store sub-domain must be entered in the 
334 334
                         <a href="/admin/settings/">site settings</a></p>'
335
-                )), 'Title');
336
-            }
337
-        });
338
-
339
-        return parent::getCMSFields();
340
-    }
341
-
342
-    /**
343
-     * @return RequiredFields
344
-     */
345
-    public function getCMSValidator()
346
-    {
347
-        return new RequiredFields(['CategoryID', 'Price', 'Weight', 'Code']);
348
-    }
349
-
350
-    /**
351
-     * @return \SilverStripe\ORM\ValidationResult
352
-     */
353
-    public function validate()
354
-    {
355
-        $result = parent::validate();
356
-
357
-        if (ProductPage::get()->filter('Code', $this->Code)->exclude('ID', $this->ID)->first()) {
358
-            $result->addError('Code must be unique for each product.');
359
-        }
360
-
361
-        /*if($this->ID>0){
335
+				)), 'Title');
336
+			}
337
+		});
338
+
339
+		return parent::getCMSFields();
340
+	}
341
+
342
+	/**
343
+	 * @return RequiredFields
344
+	 */
345
+	public function getCMSValidator()
346
+	{
347
+		return new RequiredFields(['CategoryID', 'Price', 'Weight', 'Code']);
348
+	}
349
+
350
+	/**
351
+	 * @return \SilverStripe\ORM\ValidationResult
352
+	 */
353
+	public function validate()
354
+	{
355
+		$result = parent::validate();
356
+
357
+		if (ProductPage::get()->filter('Code', $this->Code)->exclude('ID', $this->ID)->first()) {
358
+			$result->addError('Code must be unique for each product.');
359
+		}
360
+
361
+		/*if($this->ID>0){
362 362
             if ($this->Price <= 0) {
363 363
                 $result->addError('Price must be a positive value');
364 364
             }
@@ -370,173 +370,173 @@  discard block
 block discarded – undo
370 370
             }
371 371
         }*/
372 372
 
373
-        return $result;
374
-    }
375
-
376
-    /**
377
-     * @return \SilverStripe\ORM\ManyManyList
378
-     */
379
-    public function getSortedImages()
380
-    {
381
-        return $this->Images()->Sort('SortOrder');
382
-    }
383
-
384
-    /**
385
-     * @return \SilverStripe\ORM\ManyManyList
386
-     */
387
-    public function SortedImages()
388
-    {
389
-        return $this->getSortedImages();
390
-    }
391
-
392
-    /**
393
-     * @return Image|bool
394
-     */
395
-    public function getImage()
396
-    {
397
-        if ($this->getSortedImages()->count() > 0) {
398
-            return $this->getSortedImages()->first();
399
-        }
400
-
401
-        return false;
402
-    }
403
-
404
-    /**
405
-     * @return Image|bool
406
-     */
407
-    public function Image()
408
-    {
409
-        return $this->getImage();
410
-    }
411
-
412
-    /**
413
-     * @throws \Exception
414
-     */
415
-    public function onBeforeWrite()
416
-    {
417
-        parent::onBeforeWrite();
418
-        if (!$this->CategoryID) {
419
-            $default = ProductCategory::get()->filter(['Code' => 'DEFAULT'])->first();
420
-            $this->CategoryID = $default->ID;
421
-        }
422
-
423
-        //update many_many lists when multi-group is on
424
-        if (FoxyStripeSetting::current_foxystripe_setting()->MultiGroup) {
425
-            $holders = $this->ProductHolders();
426
-            $product = self::get()->byID($this->ID);
427
-            if (isset($product->ParentID)) {
428
-                $origParent = $product->ParentID;
429
-            } else {
430
-                $origParent = null;
431
-            }
432
-            $currentParent = $this->ParentID;
433
-            if ($origParent != $currentParent) {
434
-                if ($holders->find('ID', $origParent)) {
435
-                    $holders->removeByID($origParent);
436
-                }
437
-            }
438
-            $holders->add($currentParent);
439
-        }
440
-
441
-        $this->Title = trim($this->Title);
442
-        $this->Code = trim($this->Code);
443
-        $this->ReceiptTitle = trim($this->ReceiptTitle);
444
-    }
445
-
446
-    public function onAfterWrite()
447
-    {
448
-        parent::onAfterWrite();
449
-    }
450
-
451
-    public function onBeforeDelete()
452
-    {
453
-        if ($this->Status != 'Published') {
454
-            if ($this->ProductOptions()) {
455
-                $options = $this->getComponents('ProductOptions');
456
-                foreach ($options as $option) {
457
-                    $option->delete();
458
-                }
459
-            }
460
-        }
461
-        parent::onBeforeDelete();
462
-    }
463
-
464
-    /**
465
-     * @param null $productCode
466
-     * @param null $optionName
467
-     * @param null $optionValue
468
-     * @param string $method
469
-     * @param bool $output
470
-     * @param bool $urlEncode
471
-     *
472
-     * @return null|string
473
-     */
474
-    public static function getGeneratedValue(
475
-        $productCode = null,
476
-        $optionName = null,
477
-        $optionValue = null,
478
-        $method = 'name',
479
-        $output = false,
480
-        $urlEncode = false
481
-    ) {
482
-        $optionName = ($optionName !== null) ? preg_replace('/\s/', '_', $optionName) : $optionName;
483
-
484
-        return (FoxyStripeSetting::current_foxystripe_setting()->CartValidation)
485
-            ? \FoxyCart_Helper::fc_hash_value($productCode, $optionName, $optionValue, $method, $output, $urlEncode) :
486
-            $optionValue;
487
-    }
488
-
489
-    /**
490
-     * @param Member $member
491
-     *
492
-     * @return bool
493
-     */
494
-    public function canEdit($member = null)
495
-    {
496
-        return Permission::check('Product_CANCRUD', 'any', $member);
497
-    }
498
-
499
-    public function canDelete($member = null)
500
-    {
501
-        return Permission::check('Product_CANCRUD', 'any', $member);
502
-    }
503
-
504
-    public function canCreate($member = null, $context = [])
505
-    {
506
-        return Permission::check('Product_CANCRUD', 'any', $member);
507
-    }
508
-
509
-    public function canPublish($member = null)
510
-    {
511
-        return Permission::check('Product_CANCRUD', 'any', $member);
512
-    }
513
-
514
-    public function providePermissions()
515
-    {
516
-        return [
517
-            'Product_CANCRUD' => 'Allow user to manage Products and related objects',
518
-        ];
519
-    }
520
-
521
-    /**
522
-     * @return bool
523
-     */
524
-    public function getIsAvailable()
525
-    {
526
-        if (!$this->Available) {
527
-            return false;
528
-        }
529
-
530
-        if (!$this->ProductOptions()->exists()) {
531
-            return true;
532
-        }
533
-
534
-        foreach ($this->ProductOptions() as $option) {
535
-            if ($option->Available) {
536
-                return true;
537
-            }
538
-        }
539
-
540
-        return false;
541
-    }
373
+		return $result;
374
+	}
375
+
376
+	/**
377
+	 * @return \SilverStripe\ORM\ManyManyList
378
+	 */
379
+	public function getSortedImages()
380
+	{
381
+		return $this->Images()->Sort('SortOrder');
382
+	}
383
+
384
+	/**
385
+	 * @return \SilverStripe\ORM\ManyManyList
386
+	 */
387
+	public function SortedImages()
388
+	{
389
+		return $this->getSortedImages();
390
+	}
391
+
392
+	/**
393
+	 * @return Image|bool
394
+	 */
395
+	public function getImage()
396
+	{
397
+		if ($this->getSortedImages()->count() > 0) {
398
+			return $this->getSortedImages()->first();
399
+		}
400
+
401
+		return false;
402
+	}
403
+
404
+	/**
405
+	 * @return Image|bool
406
+	 */
407
+	public function Image()
408
+	{
409
+		return $this->getImage();
410
+	}
411
+
412
+	/**
413
+	 * @throws \Exception
414
+	 */
415
+	public function onBeforeWrite()
416
+	{
417
+		parent::onBeforeWrite();
418
+		if (!$this->CategoryID) {
419
+			$default = ProductCategory::get()->filter(['Code' => 'DEFAULT'])->first();
420
+			$this->CategoryID = $default->ID;
421
+		}
422
+
423
+		//update many_many lists when multi-group is on
424
+		if (FoxyStripeSetting::current_foxystripe_setting()->MultiGroup) {
425
+			$holders = $this->ProductHolders();
426
+			$product = self::get()->byID($this->ID);
427
+			if (isset($product->ParentID)) {
428
+				$origParent = $product->ParentID;
429
+			} else {
430
+				$origParent = null;
431
+			}
432
+			$currentParent = $this->ParentID;
433
+			if ($origParent != $currentParent) {
434
+				if ($holders->find('ID', $origParent)) {
435
+					$holders->removeByID($origParent);
436
+				}
437
+			}
438
+			$holders->add($currentParent);
439
+		}
440
+
441
+		$this->Title = trim($this->Title);
442
+		$this->Code = trim($this->Code);
443
+		$this->ReceiptTitle = trim($this->ReceiptTitle);
444
+	}
445
+
446
+	public function onAfterWrite()
447
+	{
448
+		parent::onAfterWrite();
449
+	}
450
+
451
+	public function onBeforeDelete()
452
+	{
453
+		if ($this->Status != 'Published') {
454
+			if ($this->ProductOptions()) {
455
+				$options = $this->getComponents('ProductOptions');
456
+				foreach ($options as $option) {
457
+					$option->delete();
458
+				}
459
+			}
460
+		}
461
+		parent::onBeforeDelete();
462
+	}
463
+
464
+	/**
465
+	 * @param null $productCode
466
+	 * @param null $optionName
467
+	 * @param null $optionValue
468
+	 * @param string $method
469
+	 * @param bool $output
470
+	 * @param bool $urlEncode
471
+	 *
472
+	 * @return null|string
473
+	 */
474
+	public static function getGeneratedValue(
475
+		$productCode = null,
476
+		$optionName = null,
477
+		$optionValue = null,
478
+		$method = 'name',
479
+		$output = false,
480
+		$urlEncode = false
481
+	) {
482
+		$optionName = ($optionName !== null) ? preg_replace('/\s/', '_', $optionName) : $optionName;
483
+
484
+		return (FoxyStripeSetting::current_foxystripe_setting()->CartValidation)
485
+			? \FoxyCart_Helper::fc_hash_value($productCode, $optionName, $optionValue, $method, $output, $urlEncode) :
486
+			$optionValue;
487
+	}
488
+
489
+	/**
490
+	 * @param Member $member
491
+	 *
492
+	 * @return bool
493
+	 */
494
+	public function canEdit($member = null)
495
+	{
496
+		return Permission::check('Product_CANCRUD', 'any', $member);
497
+	}
498
+
499
+	public function canDelete($member = null)
500
+	{
501
+		return Permission::check('Product_CANCRUD', 'any', $member);
502
+	}
503
+
504
+	public function canCreate($member = null, $context = [])
505
+	{
506
+		return Permission::check('Product_CANCRUD', 'any', $member);
507
+	}
508
+
509
+	public function canPublish($member = null)
510
+	{
511
+		return Permission::check('Product_CANCRUD', 'any', $member);
512
+	}
513
+
514
+	public function providePermissions()
515
+	{
516
+		return [
517
+			'Product_CANCRUD' => 'Allow user to manage Products and related objects',
518
+		];
519
+	}
520
+
521
+	/**
522
+	 * @return bool
523
+	 */
524
+	public function getIsAvailable()
525
+	{
526
+		if (!$this->Available) {
527
+			return false;
528
+		}
529
+
530
+		if (!$this->ProductOptions()->exists()) {
531
+			return true;
532
+		}
533
+
534
+		foreach ($this->ProductOptions() as $option) {
535
+			if ($option->Available) {
536
+				return true;
537
+			}
538
+		}
539
+
540
+		return false;
541
+	}
542 542
 }
Please login to merge, or discard this patch.