Completed
Pull Request — 2 (#402)
by Jason
08:46
created
code/admin/OrderAdmin.php 1 patch
Indentation   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -2,13 +2,13 @@
 block discarded – undo
2 2
 
3 3
 class OrderAdmin extends ModelAdmin {
4 4
 
5
-	public static $managed_models = array(
6
-		'Order'
7
-	);
5
+    public static $managed_models = array(
6
+        'Order'
7
+    );
8 8
 	
9
-	static $url_segment = 'orders';
9
+    static $url_segment = 'orders';
10 10
 	
11
-	static $menu_title = 'Orders';
11
+    static $menu_title = 'Orders';
12 12
 
13 13
     public function getEditForm($id = null, $fields = null) {
14 14
         $form = parent::getEditForm($id, $fields);
Please login to merge, or discard this patch.
code/model/foxycart.cart_validation.php 1 patch
Indentation   +310 added lines, -310 removed lines patch added patch discarded remove patch
@@ -14,315 +14,315 @@
 block discarded – undo
14 14
  *   - Empty textareas are assumed to be "open"
15 15
  */
16 16
 class FoxyCart_Helper {
17
-	/**
18
-	 * API Key (Secret)
19
-	 *
20
-	 * @var string
21
-	 **/
22
-	private static $secret;
23
-
24
-	/**
25
-	 * Cart URL
26
-	 *
27
-	 * @var string
28
-	 * Notes: Could be 'https://yourdomain.foxycart.com/cart' or 'https://secure.yourdomain.com/cart'
29
-	 **/
30
-	// protected static $cart_url = 'https://yourdomain.foxycart.com/cart';
31
-	protected static $cart_url;
32
-
33
-	public static function setCartURL($storeName = null){
34
-		self::$cart_url = 'https://'.$storeName.'.faxycart.com/cart';
35
-	}
36
-
37
-	public static function setSecret($secret = null){
38
-		self::$secret = $secret;
39
-	}
40
-
41
-	public function __construct(){
42
-		self::setCartURL(FoxyCart::getFoxyCartStoreName());
43
-		self::setSecret(FoxyCart::getStoreKey());
44
-	}
45
-
46
-	public static function getSecret(){
47
-		return FoxyCart::getStoreKey();
48
-	}
49
-
50
-
51
-	/**
52
-	 * Cart Excludes
53
-	 *
54
-	 * Arrays of values and prefixes that should be ignored when signing links and forms.
55
-	 * @var array
56
-	 */
57
-	protected static $cart_excludes = array(
58
-		// Cart values
59
-		'cart', 'fcsid', 'empty', 'coupon', 'output', 'sub_token', 'redirect', 'callback', '_',
60
-		// Checkout pre-population values
61
-		'customer_email', 'customer_first_name', 'customer_last_name', 'customer_address1', 'customer_address2',
62
-		'customer_city', 'customer_state', 'customer_postal_code', 'customer_country', 'customer_phone', 'customer_company',
63
-		'shipping_first_name', 'shipping_last_name', 'shipping_address1', 'shipping_address2',
64
-		'shipping_city', 'shipping_state', 'shipping_postal_code', 'shipping_country', 'shipping_phone', 'shipping_company',
65
-	);
66
-	protected static $cart_excludes_prefixes = array(
67
-		'h:', 'x:', '__',
68
-	);
69
-
70
-	/**
71
-	 * Debugging
72
-	 *
73
-	 * Set to $debug to TRUE to enable debug logging.
74
-	 *
75
-	 */
76
-	protected static $debug = FALSE;
77
-	protected static $log = array();
78
-
79
-
80
-	/**
81
-	 * "Link Method": Generate HMAC SHA256 for GET Query Strings
82
-	 *
83
-	 * Notes: Can't parse_str because PHP doesn't support non-alphanumeric characters as array keys.
84
-	 * @return string
85
-	 **/
86
-	public static function fc_hash_querystring($qs, $output = TRUE) {
87
-		self::$log[] = '<strong>Signing link</strong> with data: '.htmlspecialchars(substr($qs, 0, 150)).'...';
88
-		$fail = self::$cart_url.'?'.$qs;
89
-
90
-		// If the link appears to be hashed already, don't bother
91
-		if (strpos($qs, '||')) {
92
-			self::$log[] = '<strong>Link appears to be signed already</strong>: '.htmlspecialchars($code[0]);
93
-			return $fail;
94
-		}
95
-
96
-		// Stick an ampersand on the beginning of the querystring to make matching the first element a little easier
97
-		$qs = '&'.urldecode($qs);
98
-
99
-		// Get all the prefixes, codes, and name=value pairs
100
-		preg_match_all('%(?P<amp>&(?:amp;)?)(?P<prefix>[a-z0-9]{1,3}:)?(?P<name>[^=]+)=(?P<value>[^&]+)%', $qs, $pairs, PREG_SET_ORDER);
101
-		self::$log[] = 'Found the following pairs to sign:<pre>'.htmlspecialchars(print_r($pairs, true)).'</pre>';
102
-
103
-		// Get all the "code" values, set the matches in $codes
104
-		$codes = array();
105
-		foreach ($pairs as $pair) {
106
-			if ($pair['name'] == 'code') {
107
-				$codes[$pair['prefix']] = $pair['value'];
108
-			}
109
-		}
110
-		if ( ! count($codes)) {
111
-			self::$log[] = '<strong style="color:#600;">No code found</strong> for the above link.';
112
-			return $fail;
113
-		}
114
-		self::$log[] = '<strong style="color:orange;">CODES found:</strong> '.htmlspecialchars(print_r($codes, true));
115
-
116
-		// Sign the name/value pairs
117
-		foreach ($pairs as $pair) {
118
-			// Skip the cart excludes
119
-			if (in_array($pair['name'], self::$cart_excludes) || in_array($pair['prefix'], self::$cart_excludes_prefixes)) {
120
-				self::$log[] = '<strong style="color:purple;">Skipping</strong> the reserved parameter or prefix "'.$pair['prefix'].$pair['name'].'" = '.$pair['value'];
121
-				continue;
122
-			}
123
-
124
-			// Continue to sign the value and replace the name=value in the querystring with name=value||hash
125
-			$value = self::fc_hash_value($codes[$pair['prefix']], $pair['name'], $pair['value'], 'value', FALSE, 'urlencode');
126
-			$replacement = $pair['amp'].$pair['prefix'].urlencode($pair['name']).'='.$value;
127
-			$qs = str_replace($pair[0], $replacement, $qs);
128
-			self::$log[] = 'Signed <strong>'.$pair['name'].'</strong> = <strong>'.$pair['value'].'</strong> with '.$replacement.'.<br />Replacing: '.$pair[0].'<br />With... '.$replacement;
129
-		}
130
-		$qs = ltrim($qs, '&'); // Get rid of that leading ampersand we added earlier
131
-
132
-		if ($output) {
133
-			echo self::$cart_url.'?'.$qs;
134
-		} else {
135
-			return self::$cart_url.'?'.$qs;
136
-		}
137
-	}
138
-
139
-
140
-	/**
141
-	 * "Form Method": Generate HMAC SHA256 for form elements or individual <input />s
142
-	 *
143
-	 * @return string
144
-	 **/
145
-	public static function fc_hash_value($product_code, $option_name, $option_value = '', $method = 'name', $output = TRUE, $urlencode = false) {
146
-		if (!$product_code || !$option_name) {
147
-			return FALSE;
148
-		}
149
-		if ($option_value == '--OPEN--') {
150
-			$hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
151
-			$value = ($urlencode) ? urlencode($option_name).'||'.$hash.'||open' : $option_name.'||'.$hash.'||open';
152
-		} else {
153
-			$hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
154
-			if ($method == 'name') {
155
-				$value = ($urlencode) ? urlencode($option_name).'||'.$hash : $option_name.'||'.$hash;
156
-			} else {
157
-				$value = ($urlencode) ? urlencode($option_value).'||'.$hash : $option_value.'||'.$hash;
158
-			}
159
-		}
160
-
161
-		if ($output) {
162
-			echo $value;
163
-		} else {
164
-			return $value;
165
-		}
166
-	}
167
-
168
-	/**
169
-	 * Raw HTML Signing: Sign all links and form elements in a block of HTML
170
-	 *
171
-	 * Accepts a string of HTML and signs all links and forms.
172
-	 * Requires link 'href' and form 'action' attributes to use 'https' and not 'http'.
173
-	 * Requires a 'code' to be set in every form.
174
-	 *
175
-	 * @return string
176
-	 **/
177
-	public static function fc_hash_html($html) {
178
-		// Initialize some counting
179
-		$count['temp'] = 0; // temp counter
180
-		$count['links'] = 0;
181
-		$count['forms'] = 0;
182
-		$count['inputs'] = 0;
183
-		$count['lists'] = 0;
184
-		$count['textareas'] = 0;
185
-
186
-		// Find and sign all the links
187
-		preg_match_all('%<a .*?href=[\'"]'.preg_quote(self::$cart_url).'(?:\.php)?\?(.+?)[\'"].*?>%i', $html, $querystrings);
188
-		// print_r($querystrings);
189
-		foreach ($querystrings[1] as $querystring) {
190
-			// If it's already signed, skip it.
191
-			if (preg_match('%&(?:amp;)?hash=%i', $querystring)) {
192
-				continue;
193
-			}
194
-			$pattern = '%(href=[\'"])'.preg_quote(self::$cart_url, '%').'(?:\.php)?\?'.preg_quote($querystring, '%').'([\'"])%i';
195
-			$signed = self::fc_hash_querystring($querystring, FALSE);
196
-			$html = preg_replace($pattern, '$1'.$signed.'$2', $html, -1, $count['temp']);
197
-			$count['links'] += $count['temp'];
198
-		}
199
-		unset($querystrings);
200
-
201
-		// Find and sign all form values
202
-		preg_match_all('%<form [^>]*?action=[\'"]'.preg_quote(self::$cart_url).'?[\'"].*?>(.+?)</form>%is', $html, $forms);
203
-		foreach ($forms[1] as $form) {
204
-			$count['forms']++;
205
-			self::$log[] = '<strong>Signing form</strong> with data: '.htmlspecialchars(substr($form, 0, 150)).'...';
206
-
207
-			// Store the original form so we can replace it when we're done
208
-			$form_original = $form;
209
-
210
-			// Check for the "code" input, set the matches in $codes
211
-			if (!preg_match_all('%<[^>]*?name=([\'"])([0-9]{1,3}:)?code\1[^>]*?>%i', $form, $codes, PREG_SET_ORDER)) {
212
-				self::$log[] = '<strong style="color:#600;">No code found</strong> for the above form.';
213
-				continue;
214
-			}
215
-			// For each code found, sign the appropriate inputs
216
-			foreach ($codes as $code) {
217
-				// If the form appears to be hashed already, don't bother
218
-				if (strpos($code[0], '||')) {
219
-					self::$log[] = '<strong>Form appears to be signed already</strong>: '.htmlspecialchars($code[0]);
220
-					continue;
221
-				}
222
-				// Get the code and the prefix
223
-				$prefix = (isset($code[2])) ? $code[2] : '';
224
-				preg_match('%<[^>]*?value=([\'"])(.+?)\1[^>]*?>%i', $code[0], $code);
225
-				$code = trim($code[2]);
226
-				self::$log[] = '<strong>Prefix for '.htmlspecialchars($code).'</strong>: '.htmlspecialchars($prefix);
227
-				if (!$code) { // If the code is empty, skip this form or specific prefixed elements
228
-					continue;
229
-				}
230
-
231
-				// Sign all <input /> elements with matching prefix
232
-				preg_match_all('%<input [^>]*?name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(?:.+?)\1[^>]*>%i', $form, $inputs);
233
-				foreach ($inputs[0] as $input) {
234
-					$count['inputs']++;
235
-					// Test to make sure both name and value attributes are found
236
-					if (preg_match('%name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1%i', $input, $name) > 0) {
237
-						preg_match('%value=([\'"])(.*?)\1%i', $input, $value);
238
-						$value = (count($value) > 0) ? $value : array('', '', '');
239
-						preg_match('%type=([\'"])(.*?)\1%i', $input, $type);
240
-						$type = (count($type) > 0) ? $type : array('', '', '');
241
-						// Skip the cart excludes
242
-						if (in_array($prefix.$name[2], self::$cart_excludes) || in_array(substr($prefix.$name[2], 0, 2), self::$cart_excludes_prefixes)) {
243
-							self::$log[] = '<strong style="color:purple;">Skipping</strong> the reserved parameter or prefix "'.$prefix.$name[2].'" = '.$value[2];
244
-							continue;
245
-						}
246
-						self::$log[] = '<strong>INPUT['.$type[2].']:</strong> Name: <strong>'.$prefix.htmlspecialchars(preg_quote($name[2])).'</strong>';
247
-						self::$log[] = '<strong>Replacement Pattern:</strong> ([\'"])'.$prefix.preg_quote($name[2]).'\1';
248
-						$value[2] = ($value[2] == '') ? '--OPEN--' : $value[2];
249
-						if ($type[2] == 'radio') {
250
-							$input_signed = preg_replace('%([\'"])'.preg_quote($value[2]).'\1%', '${1}'.self::fc_hash_value($code, $name[2], $value[2], 'value', FALSE)."$1", $input);
251
-						} else {
252
-							$input_signed = preg_replace('%([\'"])'.$prefix.preg_quote($name[2]).'\1%', '${1}'.$prefix.self::fc_hash_value($code, $name[2], $value[2], 'name', FALSE)."$1", $input);
253
-						}
254
-						self::$log[] = '<strong>INPUT:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
255
-						               '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$name[2]).
256
-						               '</strong> :: Value: <strong>'.htmlspecialchars($value[2]).
257
-						               '</strong><br />Initial input: '.htmlspecialchars($input).
258
-						               '<br />Signed: <span style="color:#060;">'.htmlspecialchars($input_signed).'</span>';
259
-						$form = str_replace($input, $input_signed, $form);
260
-					}
261
-				}
262
-				self::$log[] = '<strong>FORM after INPUTS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
263
-
264
-				// Sign all <option /> elements
265
-				preg_match_all('%<select [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.+?)</select>%is', $form, $lists, PREG_SET_ORDER);
266
-				foreach ($lists as $list) {
267
-					$count['lists']++;
268
-					preg_match_all('%<option [^>]*value=([\'"])(.+?)\1[^>]*>(?:.*?)</option>%i', $list[0], $options, PREG_SET_ORDER);
269
-					self::$log[] = '<strong>Options:</strong> <pre>'.htmlspecialchars(print_r($options, true)).'</pre>';
270
-					unset( $form_part_signed );
271
-					foreach ($options as $option) {
272
-						if( !isset($form_part_signed) ) $form_part_signed = $list[0];
273
-						$option_signed = preg_replace(
274
-							'%'.preg_quote($option[1]).preg_quote($option[2]).preg_quote($option[1]).'%',
275
-							$option[1].self::fc_hash_value($code, $list[2], $option[2], 'value', FALSE).$option[1],
276
-							$option[0]);
277
-						$form_part_signed = str_replace($option[0], $option_signed, $form_part_signed );
278
-						self::$log[] = '<strong>OPTION:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
279
-						               '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$list[2]).
280
-						               '</strong> :: Value: <strong>'.htmlspecialchars($option[2]).
281
-						               '</strong><br />Initial option: '.htmlspecialchars($option[0]).
282
-						               '<br />Signed: <span style="color:#060;">'.htmlspecialchars($option_signed).'</span>';
283
-					}
284
-					$form = str_replace($list[0], $form_part_signed, $form);
285
-				}
286
-				self::$log[] = '<strong>FORM after OPTIONS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
287
-
288
-				// Sign all <textarea /> elements
289
-				preg_match_all('%<textarea [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.*?)</textarea>%is', $form, $textareas, PREG_SET_ORDER);
290
-				// echo "\n\nTextareas: ".print_r($textareas, true);
291
-				foreach ($textareas as $textarea) {
292
-					$count['textareas']++;
293
-					// Tackle implied "--OPEN--" first, if textarea is empty
294
-					$textarea[3] = ($textarea[3] == '') ? '--OPEN--' : $textarea[3];
295
-					$textarea_signed = preg_replace('%([\'"])'.preg_quote($prefix.$textarea[2]).'\1%', "$1".self::fc_hash_value($code, $textarea[2], $textarea[3], 'name', FALSE)."$1", $textarea[0]);
296
-					$form = str_replace($textarea[0], $textarea_signed, $form);
297
-					self::$log[] = '<strong>TEXTAREA:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
298
-					               '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$textarea[2]).
299
-					               '</strong> :: Value: <strong>'.htmlspecialchars($textarea[3]).
300
-					               '</strong><br />Initial textarea: '.htmlspecialchars($textarea[0]).
301
-					               '<br />Signed: <span style="color:#060;">'.htmlspecialchars($textarea_signed).'</span>';
302
-				}
303
-				self::$log[] = '<strong>FORM after TEXTAREAS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
304
-
305
-				// Exclude all <button> elements
306
-				$form = preg_replace('%<button ([^>]*)name=([\'"])(.*?)\1([^>]*>.*?</button>)%i', "<button $1name=$2x:$3$4", $form);
307
-
308
-			}
309
-			// Replace the entire form
310
-			self::$log[] = '<strong>FORM after ALL:</strong> <pre>'.htmlspecialchars($form).'</pre>'.'replacing <pre>'.htmlspecialchars($form_original).'</pre>';
311
-			$html = str_replace($form_original, $form, $html);
312
-			self::$log[] = '<strong>FORM end</strong><hr />';
313
-		}
314
-
315
-		// Return the signed output
316
-		$output = '';
317
-		if (self::$debug) {
318
-			self::$log['Summary'] = $count['links'].' links signed. '.$count['forms'].' forms signed. '.$count['inputs'].' inputs signed. '.$count['lists'].' lists signed. '.$count['textareas'].' textareas signed.';
319
-			$output .= '<h3>FoxyCart HMAC Debugging:</h3><ul>';
320
-			foreach (self::$log as $name => $value) {
321
-				$output .= '<li><strong>'.$name.':</strong> '.$value.'</li>';
322
-			}
323
-			$output .= '</ul><hr />';
324
-		}
325
-		return $output.$html;
326
-	}
17
+    /**
18
+     * API Key (Secret)
19
+     *
20
+     * @var string
21
+     **/
22
+    private static $secret;
23
+
24
+    /**
25
+     * Cart URL
26
+     *
27
+     * @var string
28
+     * Notes: Could be 'https://yourdomain.foxycart.com/cart' or 'https://secure.yourdomain.com/cart'
29
+     **/
30
+    // protected static $cart_url = 'https://yourdomain.foxycart.com/cart';
31
+    protected static $cart_url;
32
+
33
+    public static function setCartURL($storeName = null){
34
+        self::$cart_url = 'https://'.$storeName.'.faxycart.com/cart';
35
+    }
36
+
37
+    public static function setSecret($secret = null){
38
+        self::$secret = $secret;
39
+    }
40
+
41
+    public function __construct(){
42
+        self::setCartURL(FoxyCart::getFoxyCartStoreName());
43
+        self::setSecret(FoxyCart::getStoreKey());
44
+    }
45
+
46
+    public static function getSecret(){
47
+        return FoxyCart::getStoreKey();
48
+    }
49
+
50
+
51
+    /**
52
+     * Cart Excludes
53
+     *
54
+     * Arrays of values and prefixes that should be ignored when signing links and forms.
55
+     * @var array
56
+     */
57
+    protected static $cart_excludes = array(
58
+        // Cart values
59
+        'cart', 'fcsid', 'empty', 'coupon', 'output', 'sub_token', 'redirect', 'callback', '_',
60
+        // Checkout pre-population values
61
+        'customer_email', 'customer_first_name', 'customer_last_name', 'customer_address1', 'customer_address2',
62
+        'customer_city', 'customer_state', 'customer_postal_code', 'customer_country', 'customer_phone', 'customer_company',
63
+        'shipping_first_name', 'shipping_last_name', 'shipping_address1', 'shipping_address2',
64
+        'shipping_city', 'shipping_state', 'shipping_postal_code', 'shipping_country', 'shipping_phone', 'shipping_company',
65
+    );
66
+    protected static $cart_excludes_prefixes = array(
67
+        'h:', 'x:', '__',
68
+    );
69
+
70
+    /**
71
+     * Debugging
72
+     *
73
+     * Set to $debug to TRUE to enable debug logging.
74
+     *
75
+     */
76
+    protected static $debug = FALSE;
77
+    protected static $log = array();
78
+
79
+
80
+    /**
81
+     * "Link Method": Generate HMAC SHA256 for GET Query Strings
82
+     *
83
+     * Notes: Can't parse_str because PHP doesn't support non-alphanumeric characters as array keys.
84
+     * @return string
85
+     **/
86
+    public static function fc_hash_querystring($qs, $output = TRUE) {
87
+        self::$log[] = '<strong>Signing link</strong> with data: '.htmlspecialchars(substr($qs, 0, 150)).'...';
88
+        $fail = self::$cart_url.'?'.$qs;
89
+
90
+        // If the link appears to be hashed already, don't bother
91
+        if (strpos($qs, '||')) {
92
+            self::$log[] = '<strong>Link appears to be signed already</strong>: '.htmlspecialchars($code[0]);
93
+            return $fail;
94
+        }
95
+
96
+        // Stick an ampersand on the beginning of the querystring to make matching the first element a little easier
97
+        $qs = '&'.urldecode($qs);
98
+
99
+        // Get all the prefixes, codes, and name=value pairs
100
+        preg_match_all('%(?P<amp>&(?:amp;)?)(?P<prefix>[a-z0-9]{1,3}:)?(?P<name>[^=]+)=(?P<value>[^&]+)%', $qs, $pairs, PREG_SET_ORDER);
101
+        self::$log[] = 'Found the following pairs to sign:<pre>'.htmlspecialchars(print_r($pairs, true)).'</pre>';
102
+
103
+        // Get all the "code" values, set the matches in $codes
104
+        $codes = array();
105
+        foreach ($pairs as $pair) {
106
+            if ($pair['name'] == 'code') {
107
+                $codes[$pair['prefix']] = $pair['value'];
108
+            }
109
+        }
110
+        if ( ! count($codes)) {
111
+            self::$log[] = '<strong style="color:#600;">No code found</strong> for the above link.';
112
+            return $fail;
113
+        }
114
+        self::$log[] = '<strong style="color:orange;">CODES found:</strong> '.htmlspecialchars(print_r($codes, true));
115
+
116
+        // Sign the name/value pairs
117
+        foreach ($pairs as $pair) {
118
+            // Skip the cart excludes
119
+            if (in_array($pair['name'], self::$cart_excludes) || in_array($pair['prefix'], self::$cart_excludes_prefixes)) {
120
+                self::$log[] = '<strong style="color:purple;">Skipping</strong> the reserved parameter or prefix "'.$pair['prefix'].$pair['name'].'" = '.$pair['value'];
121
+                continue;
122
+            }
123
+
124
+            // Continue to sign the value and replace the name=value in the querystring with name=value||hash
125
+            $value = self::fc_hash_value($codes[$pair['prefix']], $pair['name'], $pair['value'], 'value', FALSE, 'urlencode');
126
+            $replacement = $pair['amp'].$pair['prefix'].urlencode($pair['name']).'='.$value;
127
+            $qs = str_replace($pair[0], $replacement, $qs);
128
+            self::$log[] = 'Signed <strong>'.$pair['name'].'</strong> = <strong>'.$pair['value'].'</strong> with '.$replacement.'.<br />Replacing: '.$pair[0].'<br />With... '.$replacement;
129
+        }
130
+        $qs = ltrim($qs, '&'); // Get rid of that leading ampersand we added earlier
131
+
132
+        if ($output) {
133
+            echo self::$cart_url.'?'.$qs;
134
+        } else {
135
+            return self::$cart_url.'?'.$qs;
136
+        }
137
+    }
138
+
139
+
140
+    /**
141
+     * "Form Method": Generate HMAC SHA256 for form elements or individual <input />s
142
+     *
143
+     * @return string
144
+     **/
145
+    public static function fc_hash_value($product_code, $option_name, $option_value = '', $method = 'name', $output = TRUE, $urlencode = false) {
146
+        if (!$product_code || !$option_name) {
147
+            return FALSE;
148
+        }
149
+        if ($option_value == '--OPEN--') {
150
+            $hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
151
+            $value = ($urlencode) ? urlencode($option_name).'||'.$hash.'||open' : $option_name.'||'.$hash.'||open';
152
+        } else {
153
+            $hash = hash_hmac('sha256', $product_code.$option_name.$option_value, self::getSecret());
154
+            if ($method == 'name') {
155
+                $value = ($urlencode) ? urlencode($option_name).'||'.$hash : $option_name.'||'.$hash;
156
+            } else {
157
+                $value = ($urlencode) ? urlencode($option_value).'||'.$hash : $option_value.'||'.$hash;
158
+            }
159
+        }
160
+
161
+        if ($output) {
162
+            echo $value;
163
+        } else {
164
+            return $value;
165
+        }
166
+    }
167
+
168
+    /**
169
+     * Raw HTML Signing: Sign all links and form elements in a block of HTML
170
+     *
171
+     * Accepts a string of HTML and signs all links and forms.
172
+     * Requires link 'href' and form 'action' attributes to use 'https' and not 'http'.
173
+     * Requires a 'code' to be set in every form.
174
+     *
175
+     * @return string
176
+     **/
177
+    public static function fc_hash_html($html) {
178
+        // Initialize some counting
179
+        $count['temp'] = 0; // temp counter
180
+        $count['links'] = 0;
181
+        $count['forms'] = 0;
182
+        $count['inputs'] = 0;
183
+        $count['lists'] = 0;
184
+        $count['textareas'] = 0;
185
+
186
+        // Find and sign all the links
187
+        preg_match_all('%<a .*?href=[\'"]'.preg_quote(self::$cart_url).'(?:\.php)?\?(.+?)[\'"].*?>%i', $html, $querystrings);
188
+        // print_r($querystrings);
189
+        foreach ($querystrings[1] as $querystring) {
190
+            // If it's already signed, skip it.
191
+            if (preg_match('%&(?:amp;)?hash=%i', $querystring)) {
192
+                continue;
193
+            }
194
+            $pattern = '%(href=[\'"])'.preg_quote(self::$cart_url, '%').'(?:\.php)?\?'.preg_quote($querystring, '%').'([\'"])%i';
195
+            $signed = self::fc_hash_querystring($querystring, FALSE);
196
+            $html = preg_replace($pattern, '$1'.$signed.'$2', $html, -1, $count['temp']);
197
+            $count['links'] += $count['temp'];
198
+        }
199
+        unset($querystrings);
200
+
201
+        // Find and sign all form values
202
+        preg_match_all('%<form [^>]*?action=[\'"]'.preg_quote(self::$cart_url).'?[\'"].*?>(.+?)</form>%is', $html, $forms);
203
+        foreach ($forms[1] as $form) {
204
+            $count['forms']++;
205
+            self::$log[] = '<strong>Signing form</strong> with data: '.htmlspecialchars(substr($form, 0, 150)).'...';
206
+
207
+            // Store the original form so we can replace it when we're done
208
+            $form_original = $form;
209
+
210
+            // Check for the "code" input, set the matches in $codes
211
+            if (!preg_match_all('%<[^>]*?name=([\'"])([0-9]{1,3}:)?code\1[^>]*?>%i', $form, $codes, PREG_SET_ORDER)) {
212
+                self::$log[] = '<strong style="color:#600;">No code found</strong> for the above form.';
213
+                continue;
214
+            }
215
+            // For each code found, sign the appropriate inputs
216
+            foreach ($codes as $code) {
217
+                // If the form appears to be hashed already, don't bother
218
+                if (strpos($code[0], '||')) {
219
+                    self::$log[] = '<strong>Form appears to be signed already</strong>: '.htmlspecialchars($code[0]);
220
+                    continue;
221
+                }
222
+                // Get the code and the prefix
223
+                $prefix = (isset($code[2])) ? $code[2] : '';
224
+                preg_match('%<[^>]*?value=([\'"])(.+?)\1[^>]*?>%i', $code[0], $code);
225
+                $code = trim($code[2]);
226
+                self::$log[] = '<strong>Prefix for '.htmlspecialchars($code).'</strong>: '.htmlspecialchars($prefix);
227
+                if (!$code) { // If the code is empty, skip this form or specific prefixed elements
228
+                    continue;
229
+                }
230
+
231
+                // Sign all <input /> elements with matching prefix
232
+                preg_match_all('%<input [^>]*?name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(?:.+?)\1[^>]*>%i', $form, $inputs);
233
+                foreach ($inputs[0] as $input) {
234
+                    $count['inputs']++;
235
+                    // Test to make sure both name and value attributes are found
236
+                    if (preg_match('%name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1%i', $input, $name) > 0) {
237
+                        preg_match('%value=([\'"])(.*?)\1%i', $input, $value);
238
+                        $value = (count($value) > 0) ? $value : array('', '', '');
239
+                        preg_match('%type=([\'"])(.*?)\1%i', $input, $type);
240
+                        $type = (count($type) > 0) ? $type : array('', '', '');
241
+                        // Skip the cart excludes
242
+                        if (in_array($prefix.$name[2], self::$cart_excludes) || in_array(substr($prefix.$name[2], 0, 2), self::$cart_excludes_prefixes)) {
243
+                            self::$log[] = '<strong style="color:purple;">Skipping</strong> the reserved parameter or prefix "'.$prefix.$name[2].'" = '.$value[2];
244
+                            continue;
245
+                        }
246
+                        self::$log[] = '<strong>INPUT['.$type[2].']:</strong> Name: <strong>'.$prefix.htmlspecialchars(preg_quote($name[2])).'</strong>';
247
+                        self::$log[] = '<strong>Replacement Pattern:</strong> ([\'"])'.$prefix.preg_quote($name[2]).'\1';
248
+                        $value[2] = ($value[2] == '') ? '--OPEN--' : $value[2];
249
+                        if ($type[2] == 'radio') {
250
+                            $input_signed = preg_replace('%([\'"])'.preg_quote($value[2]).'\1%', '${1}'.self::fc_hash_value($code, $name[2], $value[2], 'value', FALSE)."$1", $input);
251
+                        } else {
252
+                            $input_signed = preg_replace('%([\'"])'.$prefix.preg_quote($name[2]).'\1%', '${1}'.$prefix.self::fc_hash_value($code, $name[2], $value[2], 'name', FALSE)."$1", $input);
253
+                        }
254
+                        self::$log[] = '<strong>INPUT:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
255
+                                        '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$name[2]).
256
+                                        '</strong> :: Value: <strong>'.htmlspecialchars($value[2]).
257
+                                        '</strong><br />Initial input: '.htmlspecialchars($input).
258
+                                        '<br />Signed: <span style="color:#060;">'.htmlspecialchars($input_signed).'</span>';
259
+                        $form = str_replace($input, $input_signed, $form);
260
+                    }
261
+                }
262
+                self::$log[] = '<strong>FORM after INPUTS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
263
+
264
+                // Sign all <option /> elements
265
+                preg_match_all('%<select [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.+?)</select>%is', $form, $lists, PREG_SET_ORDER);
266
+                foreach ($lists as $list) {
267
+                    $count['lists']++;
268
+                    preg_match_all('%<option [^>]*value=([\'"])(.+?)\1[^>]*>(?:.*?)</option>%i', $list[0], $options, PREG_SET_ORDER);
269
+                    self::$log[] = '<strong>Options:</strong> <pre>'.htmlspecialchars(print_r($options, true)).'</pre>';
270
+                    unset( $form_part_signed );
271
+                    foreach ($options as $option) {
272
+                        if( !isset($form_part_signed) ) $form_part_signed = $list[0];
273
+                        $option_signed = preg_replace(
274
+                            '%'.preg_quote($option[1]).preg_quote($option[2]).preg_quote($option[1]).'%',
275
+                            $option[1].self::fc_hash_value($code, $list[2], $option[2], 'value', FALSE).$option[1],
276
+                            $option[0]);
277
+                        $form_part_signed = str_replace($option[0], $option_signed, $form_part_signed );
278
+                        self::$log[] = '<strong>OPTION:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
279
+                                        '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$list[2]).
280
+                                        '</strong> :: Value: <strong>'.htmlspecialchars($option[2]).
281
+                                        '</strong><br />Initial option: '.htmlspecialchars($option[0]).
282
+                                        '<br />Signed: <span style="color:#060;">'.htmlspecialchars($option_signed).'</span>';
283
+                    }
284
+                    $form = str_replace($list[0], $form_part_signed, $form);
285
+                }
286
+                self::$log[] = '<strong>FORM after OPTIONS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
287
+
288
+                // Sign all <textarea /> elements
289
+                preg_match_all('%<textarea [^>]*name=([\'"])'.preg_quote($prefix).'(?![0-9]{1,3})(.+?)\1[^>]*>(.*?)</textarea>%is', $form, $textareas, PREG_SET_ORDER);
290
+                // echo "\n\nTextareas: ".print_r($textareas, true);
291
+                foreach ($textareas as $textarea) {
292
+                    $count['textareas']++;
293
+                    // Tackle implied "--OPEN--" first, if textarea is empty
294
+                    $textarea[3] = ($textarea[3] == '') ? '--OPEN--' : $textarea[3];
295
+                    $textarea_signed = preg_replace('%([\'"])'.preg_quote($prefix.$textarea[2]).'\1%', "$1".self::fc_hash_value($code, $textarea[2], $textarea[3], 'name', FALSE)."$1", $textarea[0]);
296
+                    $form = str_replace($textarea[0], $textarea_signed, $form);
297
+                    self::$log[] = '<strong>TEXTAREA:</strong> Code: <strong>'.htmlspecialchars($prefix.$code).
298
+                                    '</strong> :: Name: <strong>'.htmlspecialchars($prefix.$textarea[2]).
299
+                                    '</strong> :: Value: <strong>'.htmlspecialchars($textarea[3]).
300
+                                    '</strong><br />Initial textarea: '.htmlspecialchars($textarea[0]).
301
+                                    '<br />Signed: <span style="color:#060;">'.htmlspecialchars($textarea_signed).'</span>';
302
+                }
303
+                self::$log[] = '<strong>FORM after TEXTAREAS:</strong> <pre>'.htmlspecialchars($form).'</pre>';
304
+
305
+                // Exclude all <button> elements
306
+                $form = preg_replace('%<button ([^>]*)name=([\'"])(.*?)\1([^>]*>.*?</button>)%i', "<button $1name=$2x:$3$4", $form);
307
+
308
+            }
309
+            // Replace the entire form
310
+            self::$log[] = '<strong>FORM after ALL:</strong> <pre>'.htmlspecialchars($form).'</pre>'.'replacing <pre>'.htmlspecialchars($form_original).'</pre>';
311
+            $html = str_replace($form_original, $form, $html);
312
+            self::$log[] = '<strong>FORM end</strong><hr />';
313
+        }
314
+
315
+        // Return the signed output
316
+        $output = '';
317
+        if (self::$debug) {
318
+            self::$log['Summary'] = $count['links'].' links signed. '.$count['forms'].' forms signed. '.$count['inputs'].' inputs signed. '.$count['lists'].' lists signed. '.$count['textareas'].' textareas signed.';
319
+            $output .= '<h3>FoxyCart HMAC Debugging:</h3><ul>';
320
+            foreach (self::$log as $name => $value) {
321
+                $output .= '<li><strong>'.$name.':</strong> '.$value.'</li>';
322
+            }
323
+            $output .= '</ul><hr />';
324
+        }
325
+        return $output.$html;
326
+    }
327 327
 
328 328
 }
329 329
\ No newline at end of file
Please login to merge, or discard this patch.
code/objects/ProductImage.php 1 patch
Indentation   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -7,25 +7,25 @@  discard block
 block discarded – undo
7 7
 
8 8
 class ProductImage extends DataObject{
9 9
 
10
-	private static $db = array(
11
-		'Title' => 'Text',
12
-		'SortOrder' => 'Int'
13
-	);
10
+    private static $db = array(
11
+        'Title' => 'Text',
12
+        'SortOrder' => 'Int'
13
+    );
14 14
 
15
-	private static $has_one = array(
16
-		'Image' => 'Image',
17
-		'Parent' => 'SiteTree'
18
-	);
15
+    private static $has_one = array(
16
+        'Image' => 'Image',
17
+        'Parent' => 'SiteTree'
18
+    );
19 19
 
20
-	private static $default_sort = 'SortOrder';
20
+    private static $default_sort = 'SortOrder';
21 21
 
22
-	private static $summary_fields = array(
23
-		'Image.CMSThumbnail' => 'Image',
24
-		'Title' => 'Caption'
25
-	);
22
+    private static $summary_fields = array(
23
+        'Image.CMSThumbnail' => 'Image',
24
+        'Title' => 'Caption'
25
+    );
26 26
 
27
-	public function getCMSFields(){
28
-		$fields = FieldList::create(
27
+    public function getCMSFields(){
28
+        $fields = FieldList::create(
29 29
             TextField::create('Title')
30 30
                 ->setTitle(_t('ProductImage.Title', 'Product Image Title')),
31 31
             UploadField::create('Image')
@@ -34,25 +34,25 @@  discard block
 block discarded – undo
34 34
                 ->setAllowedExtensions(array('jpg', 'jpeg', 'gif', 'png'))
35 35
         );
36 36
 
37
-		$this->extend('updateCMSFields', $fields);
37
+        $this->extend('updateCMSFields', $fields);
38 38
 
39 39
         return $fields;
40
-	}
40
+    }
41 41
 
42
-	public function canView($member = false) {
43
-		return true;
44
-	}
42
+    public function canView($member = false) {
43
+        return true;
44
+    }
45 45
 
46
-	public function canEdit($member = null) {
47
-		return Permission::check('Product_CANCRUD');
48
-	}
46
+    public function canEdit($member = null) {
47
+        return Permission::check('Product_CANCRUD');
48
+    }
49 49
 
50
-	public function canDelete($member = null) {
51
-		return Permission::check('Product_CANCRUD');
52
-	}
50
+    public function canDelete($member = null) {
51
+        return Permission::check('Product_CANCRUD');
52
+    }
53 53
 
54
-	public function canCreate($member = null) {
55
-		return Permission::check('Product_CANCRUD');
56
-	}
54
+    public function canCreate($member = null) {
55
+        return Permission::check('Product_CANCRUD');
56
+    }
57 57
 
58 58
 }
Please login to merge, or discard this patch.
code/objects/ProductCategory.php 1 patch
Indentation   +37 added lines, -37 removed lines patch added patch discarded remove patch
@@ -8,9 +8,9 @@  discard block
 block discarded – undo
8 8
 class ProductCategory extends DataObject {
9 9
 
10 10
     private static $db = array(
11
-		'Title' => 'Varchar(255)',
12
-		'Code' => 'Varchar(50)'
13
-	);
11
+        'Title' => 'Varchar(255)',
12
+        'Code' => 'Varchar(50)'
13
+    );
14 14
 
15 15
     private static $singular_name = 'FoxyCart Category';
16 16
     private static $plural_name = 'FoxyCart Categories';
@@ -21,13 +21,13 @@  discard block
 block discarded – undo
21 21
         'Code' => 'Code'
22 22
     );
23 23
 
24
-	private static $indexes = array(
25
-		'Code' => true
26
-	);
24
+    private static $indexes = array(
25
+        'Code' => true
26
+    );
27 27
 
28 28
     public function getCMSFields() {
29 29
 
30
-		$fields = FieldList::create(
30
+        $fields = FieldList::create(
31 31
             LiteralField::create(
32 32
                 'PCIntro',
33 33
                 _t(
@@ -50,35 +50,35 @@  discard block
 block discarded – undo
50 50
         $this->extend('updateCMSFields', $fields);
51 51
 
52 52
         return $fields;
53
-	}
54
-
55
-	public function requireDefaultRecords() {
56
-		parent::requireDefaultRecords();
57
-		$allCats = DataObject::get('ProductCategory');
58
-		if(!$allCats->count()){
59
-			$cat = new ProductCategory();
60
-			$cat->Title = 'Default';
61
-			$cat->Code = 'DEFAULT';
62
-			$cat->write();
63
-		}
64
-	}
65
-
66
-	public function canView($member = false) {
67
-		return true;
68
-	}
69
-
70
-	public function canEdit($member = null) {
71
-		return Permission::check('Product_CANCRUD');
72
-	}
73
-
74
-	public function canDelete($member = null) {
75
-
76
-		//don't allow deletion of DEFAULT category
77
-		return ($this->Code == 'DEFAULT') ? false : Permission::check('Product_CANCRUD');
78
-	}
79
-
80
-	public function canCreate($member = null) {
81
-		return Permission::check('Product_CANCRUD');
82
-	}
53
+    }
54
+
55
+    public function requireDefaultRecords() {
56
+        parent::requireDefaultRecords();
57
+        $allCats = DataObject::get('ProductCategory');
58
+        if(!$allCats->count()){
59
+            $cat = new ProductCategory();
60
+            $cat->Title = 'Default';
61
+            $cat->Code = 'DEFAULT';
62
+            $cat->write();
63
+        }
64
+    }
65
+
66
+    public function canView($member = false) {
67
+        return true;
68
+    }
69
+
70
+    public function canEdit($member = null) {
71
+        return Permission::check('Product_CANCRUD');
72
+    }
73
+
74
+    public function canDelete($member = null) {
75
+
76
+        //don't allow deletion of DEFAULT category
77
+        return ($this->Code == 'DEFAULT') ? false : Permission::check('Product_CANCRUD');
78
+    }
79
+
80
+    public function canCreate($member = null) {
81
+        return Permission::check('Product_CANCRUD');
82
+    }
83 83
 
84 84
 }
Please login to merge, or discard this patch.
code/form/FoxyStripeDropdownField.php 1 patch
Indentation   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -50,39 +50,39 @@
 block discarded – undo
50 50
  */
51 51
 class FoxyStripeDropdownField extends DropdownField{
52 52
 
53
-	/**
54
-	 * Mark certain elements as disabled,
55
-	 * regardless of the {@link setDisabled()} settings.
56
-	 *
57
-	 * @param array $items Collection of array keys, as defined in the $source array
58
-	 */
59
-	public function setDisabledItems($items){
60
-		$controller = Controller::curr();
61
-		$code = $controller->data()->Code;
62
-		$updated = [];
63
-		if(is_array($items) && !empty($items)){
64
-			foreach($items as $item){
65
-				array_push($updated, ProductPage::getGeneratedValue($code, $this->getName(), $item, 'value'));
66
-			}
67
-		}
68
-		$this->disabledItems = $updated;
69
-		return $this;
70
-	}
53
+    /**
54
+     * Mark certain elements as disabled,
55
+     * regardless of the {@link setDisabled()} settings.
56
+     *
57
+     * @param array $items Collection of array keys, as defined in the $source array
58
+     */
59
+    public function setDisabledItems($items){
60
+        $controller = Controller::curr();
61
+        $code = $controller->data()->Code;
62
+        $updated = [];
63
+        if(is_array($items) && !empty($items)){
64
+            foreach($items as $item){
65
+                array_push($updated, ProductPage::getGeneratedValue($code, $this->getName(), $item, 'value'));
66
+            }
67
+        }
68
+        $this->disabledItems = $updated;
69
+        return $this;
70
+    }
71 71
 
72
-	/**
73
-	 * @param array $source
74
-	 */
75
-	public function setSource($source) {
76
-		$controller = Controller::curr();
77
-		$code = $controller->data()->Code;
78
-		$updated = [];
79
-		if(is_array($source) && !empty($source)){
80
-			foreach($source as $key => $val){
81
-				$updated[ProductPage::getGeneratedValue($code, $this->getName(), $key, 'value')] = $val;
82
-			}
83
-		}
84
-		$this->source = $updated;
85
-		return $this;
86
-	}
72
+    /**
73
+     * @param array $source
74
+     */
75
+    public function setSource($source) {
76
+        $controller = Controller::curr();
77
+        $code = $controller->data()->Code;
78
+        $updated = [];
79
+        if(is_array($source) && !empty($source)){
80
+            foreach($source as $key => $val){
81
+                $updated[ProductPage::getGeneratedValue($code, $this->getName(), $key, 'value')] = $val;
82
+            }
83
+        }
84
+        $this->source = $updated;
85
+        return $this;
86
+    }
87 87
 
88 88
 }
Please login to merge, or discard this patch.
code/pages/OrderHistoryPage.php 1 patch
Indentation   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -11,14 +11,14 @@  discard block
 block discarded – undo
11 11
     private static $plural_name = 'Order History Pages';
12 12
     private static $description = 'Show a customers past orders. Requires authentication';
13 13
 
14
-	public function getCMSFields(){
15
-		$fields = parent::getCMSFields();
14
+    public function getCMSFields(){
15
+        $fields = parent::getCMSFields();
16 16
 
17 17
 
18 18
 
19
-		$this->extend('updateCMSFields', $fields);
20
-		return $fields;
21
-	}
19
+        $this->extend('updateCMSFields', $fields);
20
+        return $fields;
21
+    }
22 22
 
23 23
     // return all current Member's Orders
24 24
     public function getOrders($limit = 10) {
@@ -36,7 +36,7 @@  discard block
 block discarded – undo
36 36
 
37 37
 class OrderHistoryPage_Controller extends Page_Controller {
38 38
 	
39
-	private static $allowed_actions = array(
39
+    private static $allowed_actions = array(
40 40
         'index'
41 41
     );
42 42
 
Please login to merge, or discard this patch.
code/extensions/CustomerExtension.php 1 patch
Indentation   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -25,10 +25,10 @@
 block discarded – undo
25 25
         $response = FoxyCart::putCustomer($this->owner);
26 26
 
27 27
         // Grab customer_id record from FoxyCart response, store in Member
28
-		if($response){
29
-        	$foxyResponse = new SimpleXMLElement($response);
30
-        	$this->owner->Customer_ID = (int) $foxyResponse->customer_id;
31
-		}
28
+        if($response){
29
+            $foxyResponse = new SimpleXMLElement($response);
30
+            $this->owner->Customer_ID = (int) $foxyResponse->customer_id;
31
+        }
32 32
     }
33 33
 
34 34
 }
35 35
\ No newline at end of file
Please login to merge, or discard this patch.
tests/StoreSettingsTest.php 1 patch
Indentation   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -2,30 +2,30 @@
 block discarded – undo
2 2
 
3 3
 class StoreSettingsTest extends FS_Test{
4 4
 
5
-	protected static $use_draft_site = true;
5
+    protected static $use_draft_site = true;
6 6
 
7
-	function setUp(){
8
-		parent::setUp();
7
+    function setUp(){
8
+        parent::setUp();
9 9
 
10
-		$siteConf = SiteConfig::current_site_config();
11
-		$siteConf->StoreName = 'foxystripe';
10
+        $siteConf = SiteConfig::current_site_config();
11
+        $siteConf->StoreName = 'foxystripe';
12 12
         $siteConf->requireDefaultRecords();
13
-		$siteConf->write();
14
-	}
13
+        $siteConf->write();
14
+    }
15 15
 
16
-	function testStoreKey(){
17
-		$pref = FoxyCart::getKeyPrefix();
18
-		$siteConf = SiteConfig::current_site_config();
16
+    function testStoreKey(){
17
+        $pref = FoxyCart::getKeyPrefix();
18
+        $siteConf = SiteConfig::current_site_config();
19 19
 
20
-		$this->assertTrue(ctype_alnum($siteConf->StoreKey));
20
+        $this->assertTrue(ctype_alnum($siteConf->StoreKey));
21 21
         $this->assertEquals(strlen($siteConf->StoreKey), 60);
22 22
         $this->assertEquals(substr($siteConf->StoreKey, 0, 6), $pref);
23
-	}
23
+    }
24 24
 
25
-	function testStoreName(){
26
-		$siteConf = SiteConfig::current_site_config();
25
+    function testStoreName(){
26
+        $siteConf = SiteConfig::current_site_config();
27 27
 
28 28
         $this->assertEquals($siteConf->StoreName, 'foxystripe');
29
-	}
29
+    }
30 30
 
31 31
 }
Please login to merge, or discard this patch.
tests/ProductPageTest.php 1 patch
Indentation   +145 added lines, -145 removed lines patch added patch discarded remove patch
@@ -2,242 +2,242 @@
 block discarded – undo
2 2
 
3 3
 class ProductPageTest extends FS_Test{
4 4
 
5
-	protected static $use_draft_site = true;
5
+    protected static $use_draft_site = true;
6 6
 
7
-	function setUp(){
8
-		parent::setUp();
7
+    function setUp(){
8
+        parent::setUp();
9 9
 
10
-		$groupForItem = OptionGroup::create();
11
-		$groupForItem->Title = 'Sample-Group';
12
-		$groupForItem->write();
10
+        $groupForItem = OptionGroup::create();
11
+        $groupForItem->Title = 'Sample-Group';
12
+        $groupForItem->write();
13 13
 
14
-		/*$productHolder = ProductHolder::create();
14
+        /*$productHolder = ProductHolder::create();
15 15
 		$productHolder->Title = 'Product Holder';
16 16
 		$productHolder->write();*/
17
-	}
17
+    }
18 18
 
19
-	function testProductCreation(){
19
+    function testProductCreation(){
20 20
 
21
-		$this->logInWithPermission('Product_CANCRUD');
22
-		$default = $this->objFromFixture('ProductCategory', 'default');
23
-		$holder = $this->objFromFixture('ProductHolder', 'default');
24
-		$product1 = $this->objFromFixture('ProductPage', 'product1');
21
+        $this->logInWithPermission('Product_CANCRUD');
22
+        $default = $this->objFromFixture('ProductCategory', 'default');
23
+        $holder = $this->objFromFixture('ProductHolder', 'default');
24
+        $product1 = $this->objFromFixture('ProductPage', 'product1');
25 25
 
26
-		$product1->doPublish();
27
-		$this->assertTrue($product1->isPublished());
26
+        $product1->doPublish();
27
+        $this->assertTrue($product1->isPublished());
28 28
 
29
-	}
29
+    }
30 30
 
31
-	function testProductDeletion(){
31
+    function testProductDeletion(){
32 32
 
33
-		$this->logInWithPermission('Product_CANCRUD');
34
-		$holder = $this->objFromFixture('ProductHolder', 'default');
35
-		$holder->doPublish();
36
-		$product2 = $this->objFromFixture('ProductPage', 'product2');
37
-		$productID = $product2->ID;
33
+        $this->logInWithPermission('Product_CANCRUD');
34
+        $holder = $this->objFromFixture('ProductHolder', 'default');
35
+        $holder->doPublish();
36
+        $product2 = $this->objFromFixture('ProductPage', 'product2');
37
+        $productID = $product2->ID;
38 38
 
39
-		$product2->doPublish();
40
-		$this->assertTrue($product2->isPublished());
39
+        $product2->doPublish();
40
+        $this->assertTrue($product2->isPublished());
41 41
 
42
-		$versions = DB::query('Select * FROM "ProductPage_versions" WHERE "RecordID" = '. $productID);
43
-		$versionsPostPublish = array();
44
-		foreach($versions as $versionRow) $versionsPostPublish[] = $versionRow;
42
+        $versions = DB::query('Select * FROM "ProductPage_versions" WHERE "RecordID" = '. $productID);
43
+        $versionsPostPublish = array();
44
+        foreach($versions as $versionRow) $versionsPostPublish[] = $versionRow;
45 45
 
46
-		$product2->delete();
47
-		$this->assertTrue(!$product2->isPublished());
46
+        $product2->delete();
47
+        $this->assertTrue(!$product2->isPublished());
48 48
 
49
-		$versions = DB::query('Select * FROM "ProductPage_versions" WHERE "RecordID" = '. $productID);
50
-		$versionsPostDelete = array();
51
-		foreach($versions as $versionRow) $versionsPostDelete[] = $versionRow;
49
+        $versions = DB::query('Select * FROM "ProductPage_versions" WHERE "RecordID" = '. $productID);
50
+        $versionsPostDelete = array();
51
+        foreach($versions as $versionRow) $versionsPostDelete[] = $versionRow;
52 52
 
53
-		$this->assertTrue($versionsPostPublish == $versionsPostDelete);
53
+        $this->assertTrue($versionsPostPublish == $versionsPostDelete);
54 54
 
55
-	}
55
+    }
56 56
 
57
-	function testProductTitleLeadingWhiteSpace(){
57
+    function testProductTitleLeadingWhiteSpace(){
58 58
 
59
-		$this->logInWithPermission('ADMIN');
59
+        $this->logInWithPermission('ADMIN');
60 60
 
61
-		$holder = $this->objFromFixture('ProductHolder', 'default');
62
-		$holder->doPublish();
61
+        $holder = $this->objFromFixture('ProductHolder', 'default');
62
+        $holder->doPublish();
63 63
 
64
-		$product = $this->objFromFixture('ProductPage', 'product1');
65
-		$product->Title = " Test with leading space";
66
-		$product->doPublish();
64
+        $product = $this->objFromFixture('ProductPage', 'product1');
65
+        $product->Title = " Test with leading space";
66
+        $product->doPublish();
67 67
 
68
-		$this->assertTrue($product->Title == 'Test with leading space');
68
+        $this->assertTrue($product->Title == 'Test with leading space');
69 69
 
70
-	}
70
+    }
71 71
 
72
-	function testProductTitleTrailingWhiteSpace(){
72
+    function testProductTitleTrailingWhiteSpace(){
73 73
 
74
-		$this->logInWithPermission('ADMIN');
74
+        $this->logInWithPermission('ADMIN');
75 75
 
76
-		$holder = $this->objFromFixture('ProductHolder', 'default');
77
-		$holder->doPublish();
76
+        $holder = $this->objFromFixture('ProductHolder', 'default');
77
+        $holder->doPublish();
78 78
 
79
-		$product = $this->objFromFixture('ProductPage', 'product1');
80
-		$product->Title = "Test with trailing space ";
81
-		$product->doPublish();
79
+        $product = $this->objFromFixture('ProductPage', 'product1');
80
+        $product->Title = "Test with trailing space ";
81
+        $product->doPublish();
82 82
 
83
-		$this->assertTrue($product->Title == 'Test with trailing space');
83
+        $this->assertTrue($product->Title == 'Test with trailing space');
84 84
 
85
-	}
85
+    }
86 86
 
87
-	function testProductCategoryCreation(){
87
+    function testProductCategoryCreation(){
88 88
 
89
-		$this->logInWithPermission('Product_CANCRUD');
90
-		$category = $this->objFromFixture('ProductCategory', 'apparel');
91
-		$category->write();
92
-		$categoryID = $category->ID;
89
+        $this->logInWithPermission('Product_CANCRUD');
90
+        $category = $this->objFromFixture('ProductCategory', 'apparel');
91
+        $category->write();
92
+        $categoryID = $category->ID;
93 93
 
94
-		$productCategory = ProductCategory::get()->filter(array('Code'=>'APPAREL'))->first();
94
+        $productCategory = ProductCategory::get()->filter(array('Code'=>'APPAREL'))->first();
95 95
 
96
-		$this->assertTrue($categoryID == $productCategory->ID);
96
+        $this->assertTrue($categoryID == $productCategory->ID);
97 97
 
98
-	}
98
+    }
99 99
 
100
-	function testProductCategoryDeletion(){
100
+    function testProductCategoryDeletion(){
101 101
 
102
-		$this->logInWithPermission('Product_CANCRUD');
102
+        $this->logInWithPermission('Product_CANCRUD');
103 103
 
104
-		$category = $this->objFromFixture('ProductCategory', 'default');
105
-		$category->write();
104
+        $category = $this->objFromFixture('ProductCategory', 'default');
105
+        $category->write();
106 106
 
107
-		$this->assertFalse($category->canDelete());
107
+        $this->assertFalse($category->canDelete());
108 108
 
109
-		$category2 = $this->objFromFixture('ProductCategory', 'apparel');
110
-		$category2->write();
111
-		$category2ID = $category2->ID;
109
+        $category2 = $this->objFromFixture('ProductCategory', 'apparel');
110
+        $category2->write();
111
+        $category2ID = $category2->ID;
112 112
 
113
-		$this->assertTrue($category2->canDelete());
113
+        $this->assertTrue($category2->canDelete());
114 114
 
115
-		$this->logOut();
115
+        $this->logOut();
116 116
 
117
-		$this->logInWithPermission('ADMIN');
117
+        $this->logInWithPermission('ADMIN');
118 118
 
119
-		$this->assertFalse($category->canDelete());
120
-		$this->assertTrue($category2->canDelete());
119
+        $this->assertFalse($category->canDelete());
120
+        $this->assertTrue($category2->canDelete());
121 121
 
122
-		$this->logOut();
123
-		$this->logInWithPermission('Product_CANCRUD');
122
+        $this->logOut();
123
+        $this->logInWithPermission('Product_CANCRUD');
124 124
 
125
-		$category2->delete();
125
+        $category2->delete();
126 126
 
127
-		$this->assertFalse(in_array($category2ID,ProductCategory::get()->column('ID')));
127
+        $this->assertFalse(in_array($category2ID,ProductCategory::get()->column('ID')));
128 128
 
129
-	}
129
+    }
130 130
 
131
-	function testOptionGroupCreation(){
131
+    function testOptionGroupCreation(){
132 132
 
133
-		$this->logInWithPermission('Product_CANCRUD');
133
+        $this->logInWithPermission('Product_CANCRUD');
134 134
 
135
-		$group = $this->objFromFixture('OptionGroup', 'size');
136
-		$group->write();
135
+        $group = $this->objFromFixture('OptionGroup', 'size');
136
+        $group->write();
137 137
 
138
-		$this->assertNotNull(OptionGroup::get()->first());
138
+        $this->assertNotNull(OptionGroup::get()->first());
139 139
 
140
-	}
140
+    }
141 141
 
142
-	function testOptionGroupDeletion(){
142
+    function testOptionGroupDeletion(){
143 143
 
144
-		$this->logInWithPermission('ADMIN');
145
-		$group = $this->objFromFixture('OptionGroup', 'color');
146
-		$group->write();
147
-		$groupID = $group->ID;
144
+        $this->logInWithPermission('ADMIN');
145
+        $group = $this->objFromFixture('OptionGroup', 'color');
146
+        $group->write();
147
+        $groupID = $group->ID;
148 148
 
149
-		$this->assertTrue($group->canDelete());
149
+        $this->assertTrue($group->canDelete());
150 150
 
151
-		$this->logOut();
152
-		$this->logInWithPermission('Product_CANCRUD');
151
+        $this->logOut();
152
+        $this->logInWithPermission('Product_CANCRUD');
153 153
 
154
-		$this->assertTrue($group->canDelete());
155
-		$group->delete();
154
+        $this->assertTrue($group->canDelete());
155
+        $group->delete();
156 156
 
157
-		$this->assertFalse(in_array($groupID, OptionGroup::get()->column('ID')));
157
+        $this->assertFalse(in_array($groupID, OptionGroup::get()->column('ID')));
158 158
 
159
-	}
159
+    }
160 160
 
161
-	function testOptionItemCreation(){
161
+    function testOptionItemCreation(){
162 162
 
163
-		$this->logInWithPermission('Product_CANCRUD');
163
+        $this->logInWithPermission('Product_CANCRUD');
164 164
 
165
-		$optionGroup = OptionGroup::get()->filter(array('Title' => 'Sample-Group'))->first();
165
+        $optionGroup = OptionGroup::get()->filter(array('Title' => 'Sample-Group'))->first();
166 166
 
167
-		$option = $this->objFromFixture('OptionItem', 'large');
168
-		$option->ProductOptionGroupID = $optionGroup->ID;
169
-		$option->write();
167
+        $option = $this->objFromFixture('OptionItem', 'large');
168
+        $option->ProductOptionGroupID = $optionGroup->ID;
169
+        $option->write();
170 170
 
171
-		$optionID = $option->ID;
171
+        $optionID = $option->ID;
172 172
 
173
-		$optionItem = OptionItem::get()->filter(array('ProductOptionGroupID' => $optionGroup->ID))->first();
173
+        $optionItem = OptionItem::get()->filter(array('ProductOptionGroupID' => $optionGroup->ID))->first();
174 174
 
175
-		$this->assertEquals($optionID, $optionItem->ID);
175
+        $this->assertEquals($optionID, $optionItem->ID);
176 176
 
177
-	}
177
+    }
178 178
 
179
-	function testOptionItemDeletion(){
179
+    function testOptionItemDeletion(){
180 180
 
181
-		$this->logInWithPermission('ADMIN');
181
+        $this->logInWithPermission('ADMIN');
182 182
 
183
-		$optionGroup = $this->objFromFixture('OptionGroup', 'size');
184
-		$optionGroup->write();
183
+        $optionGroup = $this->objFromFixture('OptionGroup', 'size');
184
+        $optionGroup->write();
185 185
 
186
-		$option = $this->objFromFixture('OptionItem', 'small');
187
-		$option->write();
186
+        $option = $this->objFromFixture('OptionItem', 'small');
187
+        $option->write();
188 188
 
189
-		$optionID = $option->ID;
189
+        $optionID = $option->ID;
190 190
 
191
-		$this->assertTrue($option->canDelete());
191
+        $this->assertTrue($option->canDelete());
192 192
 
193
-		$this->logOut();
194
-		$this->logInWithPermission('Product_CANCRUD');
193
+        $this->logOut();
194
+        $this->logInWithPermission('Product_CANCRUD');
195 195
 
196
-		$this->assertTrue($option->canDelete());
197
-		$option->delete();
196
+        $this->assertTrue($option->canDelete());
197
+        $option->delete();
198 198
 
199
-		$this->assertFalse(in_array($optionID, OptionItem::get()->column('ID')));
199
+        $this->assertFalse(in_array($optionID, OptionItem::get()->column('ID')));
200 200
 
201
-	}
201
+    }
202 202
 
203
-	public function testProductDraftOptionDeletion(){
203
+    public function testProductDraftOptionDeletion(){
204 204
 
205
-		self::$use_draft_site = false;//make sure we can publish
205
+        self::$use_draft_site = false;//make sure we can publish
206 206
 
207
-		$this->logInWithPermission('ADMIN');
207
+        $this->logInWithPermission('ADMIN');
208 208
 
209
-		$holder = $this->objFromFixture('ProductHolder', 'default');//build holder page, ProductPage can't be on root level
210
-		$holder->doPublish();
209
+        $holder = $this->objFromFixture('ProductHolder', 'default');//build holder page, ProductPage can't be on root level
210
+        $holder->doPublish();
211 211
 
212
-		$product = $this->objFromFixture('ProductPage', 'product1');//build product page
213
-		$product->doPublish();
212
+        $product = $this->objFromFixture('ProductPage', 'product1');//build product page
213
+        $product->doPublish();
214 214
 
215
-		$productID = $product->ID;
215
+        $productID = $product->ID;
216 216
 
217 217
 
218
-		$optionGroup = $this->objFromFixture('OptionGroup', 'size');//build the group for the options
219
-		$optionGroup->write();
220
-		$option = $this->objFromFixture('OptionItem', 'small');//build first option
221
-		$option->write();
222
-		$option2 = $this->objFromFixture('OptionItem', 'large');//build second option
223
-		$option2->write();
218
+        $optionGroup = $this->objFromFixture('OptionGroup', 'size');//build the group for the options
219
+        $optionGroup->write();
220
+        $option = $this->objFromFixture('OptionItem', 'small');//build first option
221
+        $option->write();
222
+        $option2 = $this->objFromFixture('OptionItem', 'large');//build second option
223
+        $option2->write();
224 224
 
225
-		$this->assertTrue($product->isPublished());//check that product is published
225
+        $this->assertTrue($product->isPublished());//check that product is published
226 226
 
227
-		$product->deleteFromStage('Stage');//remove product from draft site
227
+        $product->deleteFromStage('Stage');//remove product from draft site
228 228
 
229
-		$this->assertTrue($product->isPublished());//check product is still published
229
+        $this->assertTrue($product->isPublished());//check product is still published
230 230
 
231
-		$testOption = $this->objFromFixture('OptionItem', 'large');
231
+        $testOption = $this->objFromFixture('OptionItem', 'large');
232 232
 
233
-		$this->assertThat($testOption->ID, $this->logicalNot($this->equalTo(0)));//make sure the first option still exists
233
+        $this->assertThat($testOption->ID, $this->logicalNot($this->equalTo(0)));//make sure the first option still exists
234 234
 
235
-		$product->doRestoreToStage();//restore page to draft site
236
-		$product->doUnpublish();//unpublish page
237
-		$product->deleteFromStage('Stage');//remove product from draft site
235
+        $product->doRestoreToStage();//restore page to draft site
236
+        $product->doUnpublish();//unpublish page
237
+        $product->deleteFromStage('Stage');//remove product from draft site
238 238
 
239
-		$checkDeleted = OptionItem::get()->filter(array('Title' => 'Large', 'ProductID' => $productID))->first();//query same option as above
239
+        $checkDeleted = OptionItem::get()->filter(array('Title' => 'Large', 'ProductID' => $productID))->first();//query same option as above
240 240
 
241
-		$this->assertEquals($checkDeleted->ID, 0);//check that the ID is 0 (empty object/non-existent)
242
-	}
241
+        $this->assertEquals($checkDeleted->ID, 0);//check that the ID is 0 (empty object/non-existent)
242
+    }
243 243
 }
244 244
\ No newline at end of file
Please login to merge, or discard this patch.