Completed
Branch rest-authorization (c7240a)
by
unknown
13:01 queued 10:45
created
core/helpers/EEH_Inflector.helper.php 2 patches
Indentation   +380 added lines, -380 removed lines patch added patch discarded remove patch
@@ -33,384 +33,384 @@
 block discarded – undo
33 33
  */
34 34
 class EEH_Inflector
35 35
 {
36
-    // ------ CLASS METHODS ------ //
37
-    // ---- Public methods ---- //
38
-    // {{{ pluralize()
39
-
40
-    /**
41
-     * Just calls self::pluralize and strtolower on $word and returns it
42
-     * @param string $word
43
-     * @return string
44
-     */
45
-    public static function pluralize_and_lower($word)
46
-    {
47
-        return strtolower(self::pluralize($word));
48
-    }
49
-
50
-
51
-
52
-    /**
53
-     * @param string $word
54
-     * @return mixed
55
-     */
56
-    public static function singularize_and_upper($word)
57
-    {
58
-        return str_replace(' ', '_', self::humanize(self::singularize($word), 'all'));
59
-    }
60
-
61
-
62
-
63
-    /**
64
-     * Pluralizes English nouns.
65
-     *
66
-     * @access public
67
-     * @static
68
-     * @param    string    $word    English noun to pluralize
69
-     * @return string Plural noun
70
-     */
71
-    public static function pluralize($word)
72
-    {
73
-        $plural = array(
74
-            '/(quiz)$/i'               => '\1zes',
75
-            '/^(ox)$/i'                => '\1en',
76
-            '/([m|l])ouse$/i'          => '\1ice',
77
-            '/(matr|vert|ind)ix|ex$/i' => '\1ices',
78
-            '/(x|ch|ss|sh)$/i'         => '\1es',
79
-            '/([^aeiouy]|qu)ies$/i'    => '\1y',
80
-            '/([^aeiouy]|qu)y$/i'      => '\1ies',
81
-            '/(hive)$/i'               => '\1s',
82
-            '/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
83
-            '/sis$/i'                  => 'ses',
84
-            '/([ti])um$/i'             => '\1a',
85
-            '/(buffal|tomat)o$/i'      => '\1oes',
86
-            '/(bu)s$/i'                => '\1ses',
87
-            '/(alias|status)/i'        => '\1es',
88
-            '/(octop|vir)us$/i'        => '\1i',
89
-            '/(ax|test)is$/i'          => '\1es',
90
-            '/s$/i'                    => 's',
91
-            '/$/'                      => 's');
92
-
93
-        $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');
94
-
95
-        $irregular = array(
96
-            'person' => 'people',
97
-            'man'    => 'men',
98
-            'child'  => 'children',
99
-            'sex'    => 'sexes',
100
-            'move'   => 'moves');
101
-
102
-        $lowercased_word = strtolower($word);
103
-
104
-        foreach ($uncountable as $_uncountable) {
105
-            if (
106
-                substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable && // even though the word "price" ends in "rice", it can be pluralized, so check the previous character isnt a letter
107
-                    ! ctype_alpha($lowercased_word[ strlen($lowercased_word) - strlen($_uncountable) ])
108
-            ) {
109
-                return $word;
110
-            }
111
-        }
112
-
113
-        foreach ($irregular as $_plural => $_singular) {
114
-            if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) {
115
-                return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word);
116
-            }
117
-        }
118
-
119
-        foreach ($plural as $rule => $replacement) {
120
-            if (preg_match($rule, $word)) {
121
-                return preg_replace($rule, $replacement, $word);
122
-            }
123
-        }
124
-        return false;
125
-    }
126
-
127
-    // }}}
128
-    // {{{ singularize()
129
-
130
-    /**
131
-     * Singularizes English nouns.
132
-     *
133
-     * @access public
134
-     * @static
135
-     * @param    string    $word    English noun to singularize
136
-     * @return string Singular noun.
137
-     */
138
-    public static function singularize($word)
139
-    {
140
-        $singular = array(
141
-            '/(quiz)zes$/i'                                                    => '\1',
142
-            '/(matr)ices$/i'                                                   => '\1ix',
143
-            '/(vert|ind)ices$/i'                                               => '\1ex',
144
-            '/^(ox)en/i'                                                       => '\1',
145
-            '/(alias|status)es$/i'                                             => '\1',
146
-            '/([octop|vir])i$/i'                                               => '\1us',
147
-            '/(cris|ax|test)es$/i'                                             => '\1is',
148
-            '/(shoe)s$/i'                                                      => '\1',
149
-            '/(o)es$/i'                                                        => '\1',
150
-            '/(bus)es$/i'                                                      => '\1',
151
-            '/([m|l])ice$/i'                                                   => '\1ouse',
152
-            '/(x|ch|ss|sh)es$/i'                                               => '\1',
153
-            '/(m)ovies$/i'                                                     => '\1ovie',
154
-            '/(s)eries$/i'                                                     => '\1eries',
155
-            '/([^aeiouy]|qu)ies$/i'                                            => '\1y',
156
-            '/([lr])ves$/i'                                                    => '\1f',
157
-            '/(tive)s$/i'                                                      => '\1',
158
-            '/(hive)s$/i'                                                      => '\1',
159
-            '/([^f])ves$/i'                                                    => '\1fe',
160
-            '/(^analy)ses$/i'                                                  => '\1sis',
161
-            '/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
162
-            '/([ti])a$/i'                                                      => '\1um',
163
-            '/(n)ews$/i'                                                       => '\1ews',
164
-            '/s$/i'                                                            => '',
165
-        );
166
-
167
-        $uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');
168
-
169
-        $irregular = array(
170
-            'person' => 'people',
171
-            'man'    => 'men',
172
-            'child'  => 'children',
173
-            'sex'    => 'sexes',
174
-            'move'   => 'moves');
175
-
176
-        $lowercased_word = strtolower($word);
177
-        foreach ($uncountable as $_uncountable) {
178
-            if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
179
-                return $word;
180
-            }
181
-        }
182
-
183
-        foreach ($irregular as $_plural => $_singular) {
184
-            if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) {
185
-                return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word);
186
-            }
187
-        }
188
-
189
-        foreach ($singular as $rule => $replacement) {
190
-            if (preg_match($rule, $word)) {
191
-                return preg_replace($rule, $replacement, $word);
192
-            }
193
-        }
194
-
195
-        return $word;
196
-    }
197
-
198
-    // }}}
199
-    // {{{ titleize()
200
-
201
-    /**
202
-     * Converts an underscored or CamelCase word into a English
203
-     * sentence.
204
-     *
205
-     * The titleize static function converts text like "WelcomePage",
206
-     * "welcome_page" or  "welcome page" to this "Welcome
207
-     * Page".
208
-     * If second parameter is set to 'first' it will only
209
-     * capitalize the first character of the title.
210
-     *
211
-     * @access public
212
-     * @static
213
-     * @param    string    $word    Word to format as tile
214
-     * @param    string    $uppercase    If set to 'first' it will only uppercase the
215
-     * first character. Otherwise it will uppercase all
216
-     * the words in the title.
217
-     * @return string Text formatted as title
218
-     */
219
-    public static function titleize($word, $uppercase = '')
220
-    {
221
-        $uppercase = $uppercase === 'first' ? 'ucfirst' : 'ucwords';
222
-        return $uppercase(EEH_Inflector::humanize(EEH_Inflector::underscore($word)));
223
-    }
224
-
225
-    // }}}
226
-    // {{{ camelize()
227
-
228
-    /**
229
-     * Returns given word as CamelCased
230
-     *
231
-     * Converts a word like "send_email" to "SendEmail". It
232
-     * will remove non alphanumeric character from the word, so
233
-     * "who's online" will be converted to "WhoSOnline"
234
-     *
235
-     * @access public
236
-     * @static
237
-     * @see variablize
238
-     * @param    string    $word    Word to convert to camel case
239
-     * @return string UpperCamelCasedWord
240
-     */
241
-    public static function camelize($word)
242
-    {
243
-        return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
244
-    }
245
-
246
-
247
-
248
-    /**
249
-     * Camelizes all but the first word. This is handy converting a method which followed EE4 legacy naming convention
250
-     * with the new PSR-based naming conventions
251
-     * @param $word
252
-     * @return string
253
-     */
254
-    public static function camelize_all_but_first($word)
255
-    {
256
-        return lcfirst(EEH_Inflector::camelize($word));
257
-    }
258
-    // }}}
259
-    // {{{ underscore()
260
-
261
-    /**
262
-     * Converts a word "into_it_s_underscored_version"
263
-     *
264
-     * Convert any "CamelCased" or "ordinary Word" into an
265
-     * "underscored_word".
266
-     *
267
-     * This can be really useful for creating friendly URLs.
268
-     *
269
-     * @access public
270
-     * @static
271
-     * @param    string    $word    Word to underscore
272
-     * @return string Underscored word
273
-     */
274
-    public static function underscore($word)
275
-    {
276
-        return strtolower(preg_replace('/[^A-Z^a-z^0-9]+/', '_', preg_replace('/([a-zd])([A-Z])/', '1_2', preg_replace('/([A-Z]+)([A-Z][a-z])/', '1_2', $word))));
277
-    }
278
-
279
-    // }}}
280
-    // {{{ humanize()
281
-
282
-    /**
283
-     * Returns a human-readable string from $word
284
-     *
285
-     * Returns a human-readable string from $word, by replacing
286
-     * underscores with a space, and by upper-casing the initial
287
-     * character by default.
288
-     *
289
-     * If you need to uppercase all the words you just have to
290
-     * pass 'all' as a second parameter.
291
-     *
292
-     * @access public
293
-     * @static
294
-     * @param    string    $word    String to "humanize"
295
-     * @param    string    $uppercase    If set to 'all' it will uppercase all the words
296
-     * instead of just the first one.
297
-     * @return string Human-readable word
298
-     */
299
-    public static function humanize($word, $uppercase = '')
300
-    {
301
-        // make special exceptions for acronyms
302
-        $word = str_replace('wp_', 'WP_', $word);
303
-        $uppercase = $uppercase === 'all' ? 'ucwords' : 'ucfirst';
304
-        return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word)));
305
-    }
306
-
307
-    // }}}
308
-    // {{{ variablize()
309
-
310
-    /**
311
-     * Same as camelize but first char is underscored
312
-     *
313
-     * Converts a word like "send_email" to "sendEmail". It
314
-     * will remove non alphanumeric character from the word, so
315
-     * "who's online" will be converted to "whoSOnline"
316
-     *
317
-     * @access public
318
-     * @static
319
-     * @see camelize
320
-     * @param    string    $word    Word to lowerCamelCase
321
-     * @return string Returns a lowerCamelCasedWord
322
-     */
323
-    public static function variablize($word)
324
-    {
325
-        $word = EEH_Inflector::camelize($word);
326
-        return strtolower($word[0]) . substr($word, 1);
327
-    }
328
-
329
-    // }}}
330
-    // {{{ tableize()
331
-
332
-    /**
333
-     * Converts a class name to its table name according to rails
334
-     * naming conventions.
335
-     *
336
-     * Converts "Person" to "people"
337
-     *
338
-     * @access public
339
-     * @static
340
-     * @see classify
341
-     * @param    string    $class_name    Class name for getting related table_name.
342
-     * @return string plural_table_name
343
-     */
344
-    public static function tableize($class_name)
345
-    {
346
-        return EEH_Inflector::pluralize(EEH_Inflector::underscore($class_name));
347
-    }
348
-
349
-    // }}}
350
-    // {{{ classify()
351
-
352
-    /**
353
-     * Converts a table name to its class name according to rails
354
-     * naming conventions.
355
-     *
356
-     * Converts "people" to "Person"
357
-     *
358
-     * @access public
359
-     * @static
360
-     * @see tableize
361
-     * @param    string    $table_name    Table name for getting related ClassName.
362
-     * @return string SingularClassName
363
-     */
364
-    public static function classify($table_name)
365
-    {
366
-        return EEH_Inflector::camelize(EEH_Inflector::singularize($table_name));
367
-    }
368
-
369
-    // }}}
370
-    // {{{ ordinalize()
371
-
372
-    /**
373
-     * Converts number to its ordinal English form.
374
-     *
375
-     * This method converts 13 to 13th, 2 to 2nd ...
376
-     *
377
-     * @access public
378
-     * @static
379
-     * @param    integer    $number    Number to get its ordinal value
380
-     * @return string Ordinal representation of given string.
381
-     */
382
-    public static function ordinalize($number)
383
-    {
384
-        if (in_array(($number % 100), range(11, 13))) {
385
-            return $number . 'th';
386
-        } else {
387
-            switch (($number % 10)) {
388
-                case 1:
389
-                    return $number . 'st';
390
-                    break;
391
-                case 2:
392
-                    return $number . 'nd';
393
-                    break;
394
-                case 3:
395
-                    return $number . 'rd';
396
-                default:
397
-                    return $number . 'th';
398
-                    break;
399
-            }
400
-        }
401
-    }
402
-
403
-
404
-
405
-    /**
406
-     * @param $string
407
-     * @return string
408
-     */
409
-    public static function add_indefinite_article($string)
410
-    {
411
-        if (strtolower($string) === 'null') {
412
-            return $string;
413
-        }
414
-        return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ') . $string;
415
-    }
36
+	// ------ CLASS METHODS ------ //
37
+	// ---- Public methods ---- //
38
+	// {{{ pluralize()
39
+
40
+	/**
41
+	 * Just calls self::pluralize and strtolower on $word and returns it
42
+	 * @param string $word
43
+	 * @return string
44
+	 */
45
+	public static function pluralize_and_lower($word)
46
+	{
47
+		return strtolower(self::pluralize($word));
48
+	}
49
+
50
+
51
+
52
+	/**
53
+	 * @param string $word
54
+	 * @return mixed
55
+	 */
56
+	public static function singularize_and_upper($word)
57
+	{
58
+		return str_replace(' ', '_', self::humanize(self::singularize($word), 'all'));
59
+	}
60
+
61
+
62
+
63
+	/**
64
+	 * Pluralizes English nouns.
65
+	 *
66
+	 * @access public
67
+	 * @static
68
+	 * @param    string    $word    English noun to pluralize
69
+	 * @return string Plural noun
70
+	 */
71
+	public static function pluralize($word)
72
+	{
73
+		$plural = array(
74
+			'/(quiz)$/i'               => '\1zes',
75
+			'/^(ox)$/i'                => '\1en',
76
+			'/([m|l])ouse$/i'          => '\1ice',
77
+			'/(matr|vert|ind)ix|ex$/i' => '\1ices',
78
+			'/(x|ch|ss|sh)$/i'         => '\1es',
79
+			'/([^aeiouy]|qu)ies$/i'    => '\1y',
80
+			'/([^aeiouy]|qu)y$/i'      => '\1ies',
81
+			'/(hive)$/i'               => '\1s',
82
+			'/(?:([^f])fe|([lr])f)$/i' => '\1\2ves',
83
+			'/sis$/i'                  => 'ses',
84
+			'/([ti])um$/i'             => '\1a',
85
+			'/(buffal|tomat)o$/i'      => '\1oes',
86
+			'/(bu)s$/i'                => '\1ses',
87
+			'/(alias|status)/i'        => '\1es',
88
+			'/(octop|vir)us$/i'        => '\1i',
89
+			'/(ax|test)is$/i'          => '\1es',
90
+			'/s$/i'                    => 's',
91
+			'/$/'                      => 's');
92
+
93
+		$uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');
94
+
95
+		$irregular = array(
96
+			'person' => 'people',
97
+			'man'    => 'men',
98
+			'child'  => 'children',
99
+			'sex'    => 'sexes',
100
+			'move'   => 'moves');
101
+
102
+		$lowercased_word = strtolower($word);
103
+
104
+		foreach ($uncountable as $_uncountable) {
105
+			if (
106
+				substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable && // even though the word "price" ends in "rice", it can be pluralized, so check the previous character isnt a letter
107
+					! ctype_alpha($lowercased_word[ strlen($lowercased_word) - strlen($_uncountable) ])
108
+			) {
109
+				return $word;
110
+			}
111
+		}
112
+
113
+		foreach ($irregular as $_plural => $_singular) {
114
+			if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) {
115
+				return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word);
116
+			}
117
+		}
118
+
119
+		foreach ($plural as $rule => $replacement) {
120
+			if (preg_match($rule, $word)) {
121
+				return preg_replace($rule, $replacement, $word);
122
+			}
123
+		}
124
+		return false;
125
+	}
126
+
127
+	// }}}
128
+	// {{{ singularize()
129
+
130
+	/**
131
+	 * Singularizes English nouns.
132
+	 *
133
+	 * @access public
134
+	 * @static
135
+	 * @param    string    $word    English noun to singularize
136
+	 * @return string Singular noun.
137
+	 */
138
+	public static function singularize($word)
139
+	{
140
+		$singular = array(
141
+			'/(quiz)zes$/i'                                                    => '\1',
142
+			'/(matr)ices$/i'                                                   => '\1ix',
143
+			'/(vert|ind)ices$/i'                                               => '\1ex',
144
+			'/^(ox)en/i'                                                       => '\1',
145
+			'/(alias|status)es$/i'                                             => '\1',
146
+			'/([octop|vir])i$/i'                                               => '\1us',
147
+			'/(cris|ax|test)es$/i'                                             => '\1is',
148
+			'/(shoe)s$/i'                                                      => '\1',
149
+			'/(o)es$/i'                                                        => '\1',
150
+			'/(bus)es$/i'                                                      => '\1',
151
+			'/([m|l])ice$/i'                                                   => '\1ouse',
152
+			'/(x|ch|ss|sh)es$/i'                                               => '\1',
153
+			'/(m)ovies$/i'                                                     => '\1ovie',
154
+			'/(s)eries$/i'                                                     => '\1eries',
155
+			'/([^aeiouy]|qu)ies$/i'                                            => '\1y',
156
+			'/([lr])ves$/i'                                                    => '\1f',
157
+			'/(tive)s$/i'                                                      => '\1',
158
+			'/(hive)s$/i'                                                      => '\1',
159
+			'/([^f])ves$/i'                                                    => '\1fe',
160
+			'/(^analy)ses$/i'                                                  => '\1sis',
161
+			'/((a)naly|(b)a|(d)iagno|(p)arenthe|(p)rogno|(s)ynop|(t)he)ses$/i' => '\1\2sis',
162
+			'/([ti])a$/i'                                                      => '\1um',
163
+			'/(n)ews$/i'                                                       => '\1ews',
164
+			'/s$/i'                                                            => '',
165
+		);
166
+
167
+		$uncountable = array('equipment', 'information', 'rice', 'money', 'species', 'series', 'fish', 'sheep');
168
+
169
+		$irregular = array(
170
+			'person' => 'people',
171
+			'man'    => 'men',
172
+			'child'  => 'children',
173
+			'sex'    => 'sexes',
174
+			'move'   => 'moves');
175
+
176
+		$lowercased_word = strtolower($word);
177
+		foreach ($uncountable as $_uncountable) {
178
+			if (substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable) {
179
+				return $word;
180
+			}
181
+		}
182
+
183
+		foreach ($irregular as $_plural => $_singular) {
184
+			if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) {
185
+				return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word);
186
+			}
187
+		}
188
+
189
+		foreach ($singular as $rule => $replacement) {
190
+			if (preg_match($rule, $word)) {
191
+				return preg_replace($rule, $replacement, $word);
192
+			}
193
+		}
194
+
195
+		return $word;
196
+	}
197
+
198
+	// }}}
199
+	// {{{ titleize()
200
+
201
+	/**
202
+	 * Converts an underscored or CamelCase word into a English
203
+	 * sentence.
204
+	 *
205
+	 * The titleize static function converts text like "WelcomePage",
206
+	 * "welcome_page" or  "welcome page" to this "Welcome
207
+	 * Page".
208
+	 * If second parameter is set to 'first' it will only
209
+	 * capitalize the first character of the title.
210
+	 *
211
+	 * @access public
212
+	 * @static
213
+	 * @param    string    $word    Word to format as tile
214
+	 * @param    string    $uppercase    If set to 'first' it will only uppercase the
215
+	 * first character. Otherwise it will uppercase all
216
+	 * the words in the title.
217
+	 * @return string Text formatted as title
218
+	 */
219
+	public static function titleize($word, $uppercase = '')
220
+	{
221
+		$uppercase = $uppercase === 'first' ? 'ucfirst' : 'ucwords';
222
+		return $uppercase(EEH_Inflector::humanize(EEH_Inflector::underscore($word)));
223
+	}
224
+
225
+	// }}}
226
+	// {{{ camelize()
227
+
228
+	/**
229
+	 * Returns given word as CamelCased
230
+	 *
231
+	 * Converts a word like "send_email" to "SendEmail". It
232
+	 * will remove non alphanumeric character from the word, so
233
+	 * "who's online" will be converted to "WhoSOnline"
234
+	 *
235
+	 * @access public
236
+	 * @static
237
+	 * @see variablize
238
+	 * @param    string    $word    Word to convert to camel case
239
+	 * @return string UpperCamelCasedWord
240
+	 */
241
+	public static function camelize($word)
242
+	{
243
+		return str_replace(' ', '', ucwords(preg_replace('/[^A-Z^a-z^0-9]+/', ' ', $word)));
244
+	}
245
+
246
+
247
+
248
+	/**
249
+	 * Camelizes all but the first word. This is handy converting a method which followed EE4 legacy naming convention
250
+	 * with the new PSR-based naming conventions
251
+	 * @param $word
252
+	 * @return string
253
+	 */
254
+	public static function camelize_all_but_first($word)
255
+	{
256
+		return lcfirst(EEH_Inflector::camelize($word));
257
+	}
258
+	// }}}
259
+	// {{{ underscore()
260
+
261
+	/**
262
+	 * Converts a word "into_it_s_underscored_version"
263
+	 *
264
+	 * Convert any "CamelCased" or "ordinary Word" into an
265
+	 * "underscored_word".
266
+	 *
267
+	 * This can be really useful for creating friendly URLs.
268
+	 *
269
+	 * @access public
270
+	 * @static
271
+	 * @param    string    $word    Word to underscore
272
+	 * @return string Underscored word
273
+	 */
274
+	public static function underscore($word)
275
+	{
276
+		return strtolower(preg_replace('/[^A-Z^a-z^0-9]+/', '_', preg_replace('/([a-zd])([A-Z])/', '1_2', preg_replace('/([A-Z]+)([A-Z][a-z])/', '1_2', $word))));
277
+	}
278
+
279
+	// }}}
280
+	// {{{ humanize()
281
+
282
+	/**
283
+	 * Returns a human-readable string from $word
284
+	 *
285
+	 * Returns a human-readable string from $word, by replacing
286
+	 * underscores with a space, and by upper-casing the initial
287
+	 * character by default.
288
+	 *
289
+	 * If you need to uppercase all the words you just have to
290
+	 * pass 'all' as a second parameter.
291
+	 *
292
+	 * @access public
293
+	 * @static
294
+	 * @param    string    $word    String to "humanize"
295
+	 * @param    string    $uppercase    If set to 'all' it will uppercase all the words
296
+	 * instead of just the first one.
297
+	 * @return string Human-readable word
298
+	 */
299
+	public static function humanize($word, $uppercase = '')
300
+	{
301
+		// make special exceptions for acronyms
302
+		$word = str_replace('wp_', 'WP_', $word);
303
+		$uppercase = $uppercase === 'all' ? 'ucwords' : 'ucfirst';
304
+		return $uppercase(str_replace('_', ' ', preg_replace('/_id$/', '', $word)));
305
+	}
306
+
307
+	// }}}
308
+	// {{{ variablize()
309
+
310
+	/**
311
+	 * Same as camelize but first char is underscored
312
+	 *
313
+	 * Converts a word like "send_email" to "sendEmail". It
314
+	 * will remove non alphanumeric character from the word, so
315
+	 * "who's online" will be converted to "whoSOnline"
316
+	 *
317
+	 * @access public
318
+	 * @static
319
+	 * @see camelize
320
+	 * @param    string    $word    Word to lowerCamelCase
321
+	 * @return string Returns a lowerCamelCasedWord
322
+	 */
323
+	public static function variablize($word)
324
+	{
325
+		$word = EEH_Inflector::camelize($word);
326
+		return strtolower($word[0]) . substr($word, 1);
327
+	}
328
+
329
+	// }}}
330
+	// {{{ tableize()
331
+
332
+	/**
333
+	 * Converts a class name to its table name according to rails
334
+	 * naming conventions.
335
+	 *
336
+	 * Converts "Person" to "people"
337
+	 *
338
+	 * @access public
339
+	 * @static
340
+	 * @see classify
341
+	 * @param    string    $class_name    Class name for getting related table_name.
342
+	 * @return string plural_table_name
343
+	 */
344
+	public static function tableize($class_name)
345
+	{
346
+		return EEH_Inflector::pluralize(EEH_Inflector::underscore($class_name));
347
+	}
348
+
349
+	// }}}
350
+	// {{{ classify()
351
+
352
+	/**
353
+	 * Converts a table name to its class name according to rails
354
+	 * naming conventions.
355
+	 *
356
+	 * Converts "people" to "Person"
357
+	 *
358
+	 * @access public
359
+	 * @static
360
+	 * @see tableize
361
+	 * @param    string    $table_name    Table name for getting related ClassName.
362
+	 * @return string SingularClassName
363
+	 */
364
+	public static function classify($table_name)
365
+	{
366
+		return EEH_Inflector::camelize(EEH_Inflector::singularize($table_name));
367
+	}
368
+
369
+	// }}}
370
+	// {{{ ordinalize()
371
+
372
+	/**
373
+	 * Converts number to its ordinal English form.
374
+	 *
375
+	 * This method converts 13 to 13th, 2 to 2nd ...
376
+	 *
377
+	 * @access public
378
+	 * @static
379
+	 * @param    integer    $number    Number to get its ordinal value
380
+	 * @return string Ordinal representation of given string.
381
+	 */
382
+	public static function ordinalize($number)
383
+	{
384
+		if (in_array(($number % 100), range(11, 13))) {
385
+			return $number . 'th';
386
+		} else {
387
+			switch (($number % 10)) {
388
+				case 1:
389
+					return $number . 'st';
390
+					break;
391
+				case 2:
392
+					return $number . 'nd';
393
+					break;
394
+				case 3:
395
+					return $number . 'rd';
396
+				default:
397
+					return $number . 'th';
398
+					break;
399
+			}
400
+		}
401
+	}
402
+
403
+
404
+
405
+	/**
406
+	 * @param $string
407
+	 * @return string
408
+	 */
409
+	public static function add_indefinite_article($string)
410
+	{
411
+		if (strtolower($string) === 'null') {
412
+			return $string;
413
+		}
414
+		return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ') . $string;
415
+	}
416 416
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -104,15 +104,15 @@  discard block
 block discarded – undo
104 104
         foreach ($uncountable as $_uncountable) {
105 105
             if (
106 106
                 substr($lowercased_word, (-1 * strlen($_uncountable))) == $_uncountable && // even though the word "price" ends in "rice", it can be pluralized, so check the previous character isnt a letter
107
-                    ! ctype_alpha($lowercased_word[ strlen($lowercased_word) - strlen($_uncountable) ])
107
+                    ! ctype_alpha($lowercased_word[strlen($lowercased_word) - strlen($_uncountable)])
108 108
             ) {
109 109
                 return $word;
110 110
             }
111 111
         }
112 112
 
113 113
         foreach ($irregular as $_plural => $_singular) {
114
-            if (preg_match('/(' . $_plural . ')$/i', $word, $arr)) {
115
-                return preg_replace('/(' . $_plural . ')$/i', substr($arr[0], 0, 1) . substr($_singular, 1), $word);
114
+            if (preg_match('/('.$_plural.')$/i', $word, $arr)) {
115
+                return preg_replace('/('.$_plural.')$/i', substr($arr[0], 0, 1).substr($_singular, 1), $word);
116 116
             }
117 117
         }
118 118
 
@@ -181,8 +181,8 @@  discard block
 block discarded – undo
181 181
         }
182 182
 
183 183
         foreach ($irregular as $_plural => $_singular) {
184
-            if (preg_match('/(' . $_singular . ')$/i', $word, $arr)) {
185
-                return preg_replace('/(' . $_singular . ')$/i', substr($arr[0], 0, 1) . substr($_plural, 1), $word);
184
+            if (preg_match('/('.$_singular.')$/i', $word, $arr)) {
185
+                return preg_replace('/('.$_singular.')$/i', substr($arr[0], 0, 1).substr($_plural, 1), $word);
186 186
             }
187 187
         }
188 188
 
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
     public static function variablize($word)
324 324
     {
325 325
         $word = EEH_Inflector::camelize($word);
326
-        return strtolower($word[0]) . substr($word, 1);
326
+        return strtolower($word[0]).substr($word, 1);
327 327
     }
328 328
 
329 329
     // }}}
@@ -382,19 +382,19 @@  discard block
 block discarded – undo
382 382
     public static function ordinalize($number)
383 383
     {
384 384
         if (in_array(($number % 100), range(11, 13))) {
385
-            return $number . 'th';
385
+            return $number.'th';
386 386
         } else {
387 387
             switch (($number % 10)) {
388 388
                 case 1:
389
-                    return $number . 'st';
389
+                    return $number.'st';
390 390
                     break;
391 391
                 case 2:
392
-                    return $number . 'nd';
392
+                    return $number.'nd';
393 393
                     break;
394 394
                 case 3:
395
-                    return $number . 'rd';
395
+                    return $number.'rd';
396 396
                 default:
397
-                    return $number . 'th';
397
+                    return $number.'th';
398 398
                     break;
399 399
             }
400 400
         }
@@ -411,6 +411,6 @@  discard block
 block discarded – undo
411 411
         if (strtolower($string) === 'null') {
412 412
             return $string;
413 413
         }
414
-        return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ') . $string;
414
+        return (stripos('aeiou', $string[0]) !== false ? 'an ' : 'a ').$string;
415 415
     }
416 416
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Parse_Shortcodes.helper.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -208,14 +208,14 @@  discard block
 block discarded – undo
208 208
                 if ($sc_obj instanceof EE_Shortcodes) {
209 209
                     // we need to setup any dynamic shortcodes so that they work with the array_key_exists
210 210
                     preg_match_all('/(\[[A-Za-z0-9\_]+_\*)/', $shortcode, $matches);
211
-                    $sc_to_verify = ! empty($matches[0]) ? $matches[0][0] . ']' : $shortcode;
211
+                    $sc_to_verify = ! empty($matches[0]) ? $matches[0][0].']' : $shortcode;
212 212
 
213
-                    if (! array_key_exists($sc_to_verify, $sc_obj->get_shortcodes())) {
213
+                    if ( ! array_key_exists($sc_to_verify, $sc_obj->get_shortcodes())) {
214 214
                         continue; // the given shortcode isn't in this object
215 215
                     }
216 216
 
217 217
                     // if this isn't  a "list" type shortcode then we'll send along the data vanilla instead of in an array.
218
-                    if (! in_array($sc_to_verify, $list_type_shortcodes)) {
218
+                    if ( ! in_array($sc_to_verify, $list_type_shortcodes)) {
219 219
                         $data_send = ! is_object($this->_data) && isset($this->_data['data']) ? $this->_data['data'] : $this->_data;
220 220
                     } else {
221 221
                         $data_send = $this->_data;
@@ -271,7 +271,7 @@  discard block
 block discarded – undo
271 271
         foreach ($valid_shortcodes as $shortcode_ref) {
272 272
             $ref       = ucwords(str_replace('_', ' ', $shortcode_ref));
273 273
             $ref       = str_replace(' ', '_', $ref);
274
-            $classname = 'EE_' . $ref . '_Shortcodes';
274
+            $classname = 'EE_'.$ref.'_Shortcodes';
275 275
             if (class_exists($classname)) {
276 276
                 $this->_shortcode_objs[] = new $classname();
277 277
             }
Please login to merge, or discard this patch.
Indentation   +264 added lines, -264 removed lines patch added patch discarded remove patch
@@ -11,268 +11,268 @@
 block discarded – undo
11 11
  */
12 12
 class EEH_Parse_Shortcodes
13 13
 {
14
-    /**
15
-     * holds the template
16
-     *
17
-     * @access private
18
-     * @var mixed (string|array)
19
-     */
20
-    private $_template;
21
-
22
-
23
-    /**
24
-     * holds the incoming data object
25
-     *
26
-     * @access private
27
-     * @var object
28
-     */
29
-    private $_data;
30
-
31
-
32
-    /**
33
-     * will hold an array of EE_Shortcodes library objects.
34
-     *
35
-     * @access private
36
-     * @var EE_Shortcodes[]
37
-     */
38
-    private $_shortcode_objs = array();
39
-
40
-
41
-    public function __construct()
42
-    {
43
-    }
44
-
45
-
46
-    /**
47
-     * This kicks off the parsing of shortcodes in message templates
48
-     *
49
-     * @param  string                $template         This is the incoming string to be parsed
50
-     * @param  EE_Messages_Addressee $data             This is the incoming data object
51
-     * @param  array                 $valid_shortcodes An array of strings that correspond to EE_Shortcode libraries
52
-     * @param EE_message_type        $message_type     The message type that called the parser
53
-     * @param EE_messenger           $messenger        The active messenger for this parsing session.
54
-     * @param EE_Message             $message
55
-     * @return string                   The parsed template string
56
-     */
57
-    public function parse_message_template(
58
-        $template,
59
-        EE_Messages_Addressee $data,
60
-        $valid_shortcodes,
61
-        EE_message_type $message_type,
62
-        EE_messenger $messenger,
63
-        EE_Message $message
64
-    ) {
65
-        $extra_data = array(
66
-            'messenger'    => $messenger,
67
-            'message_type' => $message_type,
68
-            'message'      => $message,
69
-        );
70
-        $this->_init_data($template, $data, $valid_shortcodes, $extra_data);
71
-        $this->_template = is_array($template) ? $template['main'] : $template;
72
-        return $this->_parse_message_template();
73
-    }
74
-
75
-
76
-    public function parse_attendee_list_template(
77
-        $template,
78
-        EE_Registration $registration,
79
-        $valid_shortcodes,
80
-        $extra_data = array()
81
-    ) {
82
-        $this->_init_data($template, $registration, $valid_shortcodes, $extra_data);
83
-        $this->_template = is_array($template) ? $template['attendee_list'] : $template;
84
-        return $this->_parse_message_template();
85
-    }
86
-
87
-    public function parse_event_list_template($template, EE_Event $event, $valid_shortcodes, $extra_data = array())
88
-    {
89
-        $this->_init_data($template, $event, $valid_shortcodes, $extra_data);
90
-        $this->_template = is_array($template) ? $template['event_list'] : $template;
91
-        return $this->_parse_message_template();
92
-    }
93
-
94
-
95
-    public function parse_ticket_list_template($template, EE_Ticket $ticket, $valid_shortcodes, $extra_data = array())
96
-    {
97
-        $this->_init_data($template, $ticket, $valid_shortcodes, $extra_data);
98
-        $this->_template = is_array($template) ? $template['ticket_list'] : $template;
99
-        return $this->_parse_message_template();
100
-    }
101
-
102
-
103
-    public function parse_line_item_list_template(
104
-        $template,
105
-        EE_Line_Item $line_item,
106
-        $valid_shortcodes,
107
-        $extra_data = array()
108
-    ) {
109
-        $this->_init_data($template, $line_item, $valid_shortcodes, $extra_data);
110
-        $this->_template = is_array($template) ? $template['ticket_line_item_no_pms'] : $template;
111
-        return $this->_parse_message_template();
112
-    }
113
-
114
-
115
-    public function parse_payment_list_template(
116
-        $template,
117
-        EE_Payment $payment_item,
118
-        $valid_shortcodes,
119
-        $extra_data = array()
120
-    ) {
121
-        $this->_init_data($template, $payment_item, $valid_shortcodes, $extra_data);
122
-        $this->_template = is_array($template) ? $template['payment_list'] : $template;
123
-        return $this->_parse_message_template();
124
-    }
125
-
126
-
127
-    public function parse_datetime_list_template(
128
-        $template,
129
-        EE_Datetime $datetime,
130
-        $valid_shortcodes,
131
-        $extra_data = array()
132
-    ) {
133
-        $this->_init_data($template, $datetime, $valid_shortcodes, $extra_data);
134
-        $this->_template = is_array($template) ? $template['datetime_list'] : $template;
135
-        return $this->_parse_message_template();
136
-    }
137
-
138
-
139
-    public function parse_question_list_template($template, EE_Answer $answer, $valid_shortcodes, $extra_data = array())
140
-    {
141
-        $this->_init_data($template, $answer, $valid_shortcodes, $extra_data);
142
-        $this->_template = is_array($template) ? $template['question_list'] : $template;
143
-        return $this->_parse_message_template();
144
-    }
145
-
146
-
147
-    private function _init_data($template, $data, $valid_shortcodes, $extra_data = array())
148
-    {
149
-        $this->_reset_props();
150
-        $this->_data['template']   = $template;
151
-        $this->_data['data']       = $data;
152
-        $this->_data['extra_data'] = $extra_data;
153
-        $this->_set_shortcodes($valid_shortcodes);
154
-    }
155
-
156
-
157
-    private function _reset_props()
158
-    {
159
-        $this->_template       = $this->_data = null;
160
-        $this->_shortcode_objs = array();
161
-    }
162
-
163
-
164
-    /**
165
-     * takes the given template and parses it with the $_shortcodes property
166
-     *
167
-     * @access private
168
-     * @return string
169
-     */
170
-    private function _parse_message_template()
171
-    {
172
-        // now let's get a list of shortcodes that are found in the given template
173
-        preg_match_all('/(\[.+?\])/', $this->_template, $matches);
174
-        $shortcodes = (array) $matches[0]; // this should be an array of shortcodes in the template string.
175
-
176
-        $matched_code = array();
177
-        $sc_values    = array();
178
-
179
-        $list_type_shortcodes = array(
180
-            '[ATTENDEE_LIST]',
181
-            '[EVENT_LIST]',
182
-            '[TICKET_LIST]',
183
-            '[DATETIME_LIST]',
184
-            '[QUESTION_LIST]',
185
-            '[RECIPIENT_QUESTION_LIST]',
186
-            '[PRIMARY_REGISTRANT_QUESTION_LIST]',
187
-            '[RECIPIENT_TICKET_LIST]',
188
-            '[PRIMARY_REGISTRANT_TICKET_LIST]',
189
-            '[RECIPIENT_DATETIME_LIST]',
190
-            '[PRIMARY_REGISTRANT_DATETIME_LIST]',
191
-            '[TICKET_LINE_ITEM_LIST]',
192
-            '[TAX_LINE_ITEM_LIST]',
193
-            '[ADDITIONAL_LINE_ITEM_LIST]',
194
-            '[PRICE_MODIFIER_LINE_ITEM_LIST]',
195
-            '[PAYMENT_LIST_*]',
196
-        );
197
-
198
-        $list_type_shortcodes = apply_filters(
199
-            'FHEE__EEH_Parse_Shortcodes___parse_message_template__list_type_shortcodes',
200
-            $list_type_shortcodes
201
-        );
202
-
203
-        // now lets go ahead and loop through our parsers for each shortcode and setup the values
204
-        foreach ($shortcodes as $shortcode) {
205
-            foreach ($this->_shortcode_objs as $sc_obj) {
206
-                if ($sc_obj instanceof EE_Shortcodes) {
207
-                    // we need to setup any dynamic shortcodes so that they work with the array_key_exists
208
-                    preg_match_all('/(\[[A-Za-z0-9\_]+_\*)/', $shortcode, $matches);
209
-                    $sc_to_verify = ! empty($matches[0]) ? $matches[0][0] . ']' : $shortcode;
210
-
211
-                    if (! array_key_exists($sc_to_verify, $sc_obj->get_shortcodes())) {
212
-                        continue; // the given shortcode isn't in this object
213
-                    }
214
-
215
-                    // if this isn't  a "list" type shortcode then we'll send along the data vanilla instead of in an array.
216
-                    if (! in_array($sc_to_verify, $list_type_shortcodes)) {
217
-                        $data_send = ! is_object($this->_data) && isset($this->_data['data']) ? $this->_data['data'] : $this->_data;
218
-                    } else {
219
-                        $data_send = $this->_data;
220
-                    }
221
-
222
-                    // is this a conditional type shortcode?  If it is then we actually parse the template here.
223
-                    if ($this->_is_conditional_shortcode($shortcode)) {
224
-                        // most shortcode parsers are not going to have a match for this shortcode and will return an
225
-                        // empty string so we need to make sure that we're only replacing the template when there is a non empty string.
226
-                        $parsed = $sc_obj->parser($shortcode, $data_send, $this->_data['extra_data']);
227
-                        if ($parsed) {
228
-                            $this->_template = $parsed;
229
-                        }
230
-                    }
231
-
232
-                    $parsed = $sc_obj->parser($shortcode, $data_send, $this->_data['extra_data']);
233
-
234
-                    $matched_code[] = $shortcode;
235
-                    $sc_values[]    = $parsed;
236
-                }
237
-            }
238
-        }
239
-
240
-        // now we've got parsed values for all the shortcodes in the template so we can go ahead and swap the shortcodes out.
241
-        $parsed = str_replace(array_values($matched_code), array_values($sc_values), $this->_template);
242
-        return $parsed;
243
-    }
244
-
245
-
246
-    /**
247
-     * Simply returns whether the given shortcode matches the structure for a conditional shortcode.
248
-     *
249
-     * Does it match this format: `[IF_`
250
-     *
251
-     * @param $shortcode
252
-     */
253
-    protected function _is_conditional_shortcode($shortcode)
254
-    {
255
-        return strpos($shortcode, '[IF_') === 0;
256
-    }
257
-
258
-
259
-    /**
260
-     * This sets the shortcodes property from the incoming array of valid shortcodes that corresponds to names of
261
-     * various EE_Shortcode library objects
262
-     *
263
-     * @access private
264
-     * @param array $valid_shortcodes an array of strings corresponding to EE_Shortcode Library objects
265
-     * @return void
266
-     */
267
-    private function _set_shortcodes($valid_shortcodes)
268
-    {
269
-        foreach ($valid_shortcodes as $shortcode_ref) {
270
-            $ref       = ucwords(str_replace('_', ' ', $shortcode_ref));
271
-            $ref       = str_replace(' ', '_', $ref);
272
-            $classname = 'EE_' . $ref . '_Shortcodes';
273
-            if (class_exists($classname)) {
274
-                $this->_shortcode_objs[] = new $classname();
275
-            }
276
-        }
277
-    }
14
+	/**
15
+	 * holds the template
16
+	 *
17
+	 * @access private
18
+	 * @var mixed (string|array)
19
+	 */
20
+	private $_template;
21
+
22
+
23
+	/**
24
+	 * holds the incoming data object
25
+	 *
26
+	 * @access private
27
+	 * @var object
28
+	 */
29
+	private $_data;
30
+
31
+
32
+	/**
33
+	 * will hold an array of EE_Shortcodes library objects.
34
+	 *
35
+	 * @access private
36
+	 * @var EE_Shortcodes[]
37
+	 */
38
+	private $_shortcode_objs = array();
39
+
40
+
41
+	public function __construct()
42
+	{
43
+	}
44
+
45
+
46
+	/**
47
+	 * This kicks off the parsing of shortcodes in message templates
48
+	 *
49
+	 * @param  string                $template         This is the incoming string to be parsed
50
+	 * @param  EE_Messages_Addressee $data             This is the incoming data object
51
+	 * @param  array                 $valid_shortcodes An array of strings that correspond to EE_Shortcode libraries
52
+	 * @param EE_message_type        $message_type     The message type that called the parser
53
+	 * @param EE_messenger           $messenger        The active messenger for this parsing session.
54
+	 * @param EE_Message             $message
55
+	 * @return string                   The parsed template string
56
+	 */
57
+	public function parse_message_template(
58
+		$template,
59
+		EE_Messages_Addressee $data,
60
+		$valid_shortcodes,
61
+		EE_message_type $message_type,
62
+		EE_messenger $messenger,
63
+		EE_Message $message
64
+	) {
65
+		$extra_data = array(
66
+			'messenger'    => $messenger,
67
+			'message_type' => $message_type,
68
+			'message'      => $message,
69
+		);
70
+		$this->_init_data($template, $data, $valid_shortcodes, $extra_data);
71
+		$this->_template = is_array($template) ? $template['main'] : $template;
72
+		return $this->_parse_message_template();
73
+	}
74
+
75
+
76
+	public function parse_attendee_list_template(
77
+		$template,
78
+		EE_Registration $registration,
79
+		$valid_shortcodes,
80
+		$extra_data = array()
81
+	) {
82
+		$this->_init_data($template, $registration, $valid_shortcodes, $extra_data);
83
+		$this->_template = is_array($template) ? $template['attendee_list'] : $template;
84
+		return $this->_parse_message_template();
85
+	}
86
+
87
+	public function parse_event_list_template($template, EE_Event $event, $valid_shortcodes, $extra_data = array())
88
+	{
89
+		$this->_init_data($template, $event, $valid_shortcodes, $extra_data);
90
+		$this->_template = is_array($template) ? $template['event_list'] : $template;
91
+		return $this->_parse_message_template();
92
+	}
93
+
94
+
95
+	public function parse_ticket_list_template($template, EE_Ticket $ticket, $valid_shortcodes, $extra_data = array())
96
+	{
97
+		$this->_init_data($template, $ticket, $valid_shortcodes, $extra_data);
98
+		$this->_template = is_array($template) ? $template['ticket_list'] : $template;
99
+		return $this->_parse_message_template();
100
+	}
101
+
102
+
103
+	public function parse_line_item_list_template(
104
+		$template,
105
+		EE_Line_Item $line_item,
106
+		$valid_shortcodes,
107
+		$extra_data = array()
108
+	) {
109
+		$this->_init_data($template, $line_item, $valid_shortcodes, $extra_data);
110
+		$this->_template = is_array($template) ? $template['ticket_line_item_no_pms'] : $template;
111
+		return $this->_parse_message_template();
112
+	}
113
+
114
+
115
+	public function parse_payment_list_template(
116
+		$template,
117
+		EE_Payment $payment_item,
118
+		$valid_shortcodes,
119
+		$extra_data = array()
120
+	) {
121
+		$this->_init_data($template, $payment_item, $valid_shortcodes, $extra_data);
122
+		$this->_template = is_array($template) ? $template['payment_list'] : $template;
123
+		return $this->_parse_message_template();
124
+	}
125
+
126
+
127
+	public function parse_datetime_list_template(
128
+		$template,
129
+		EE_Datetime $datetime,
130
+		$valid_shortcodes,
131
+		$extra_data = array()
132
+	) {
133
+		$this->_init_data($template, $datetime, $valid_shortcodes, $extra_data);
134
+		$this->_template = is_array($template) ? $template['datetime_list'] : $template;
135
+		return $this->_parse_message_template();
136
+	}
137
+
138
+
139
+	public function parse_question_list_template($template, EE_Answer $answer, $valid_shortcodes, $extra_data = array())
140
+	{
141
+		$this->_init_data($template, $answer, $valid_shortcodes, $extra_data);
142
+		$this->_template = is_array($template) ? $template['question_list'] : $template;
143
+		return $this->_parse_message_template();
144
+	}
145
+
146
+
147
+	private function _init_data($template, $data, $valid_shortcodes, $extra_data = array())
148
+	{
149
+		$this->_reset_props();
150
+		$this->_data['template']   = $template;
151
+		$this->_data['data']       = $data;
152
+		$this->_data['extra_data'] = $extra_data;
153
+		$this->_set_shortcodes($valid_shortcodes);
154
+	}
155
+
156
+
157
+	private function _reset_props()
158
+	{
159
+		$this->_template       = $this->_data = null;
160
+		$this->_shortcode_objs = array();
161
+	}
162
+
163
+
164
+	/**
165
+	 * takes the given template and parses it with the $_shortcodes property
166
+	 *
167
+	 * @access private
168
+	 * @return string
169
+	 */
170
+	private function _parse_message_template()
171
+	{
172
+		// now let's get a list of shortcodes that are found in the given template
173
+		preg_match_all('/(\[.+?\])/', $this->_template, $matches);
174
+		$shortcodes = (array) $matches[0]; // this should be an array of shortcodes in the template string.
175
+
176
+		$matched_code = array();
177
+		$sc_values    = array();
178
+
179
+		$list_type_shortcodes = array(
180
+			'[ATTENDEE_LIST]',
181
+			'[EVENT_LIST]',
182
+			'[TICKET_LIST]',
183
+			'[DATETIME_LIST]',
184
+			'[QUESTION_LIST]',
185
+			'[RECIPIENT_QUESTION_LIST]',
186
+			'[PRIMARY_REGISTRANT_QUESTION_LIST]',
187
+			'[RECIPIENT_TICKET_LIST]',
188
+			'[PRIMARY_REGISTRANT_TICKET_LIST]',
189
+			'[RECIPIENT_DATETIME_LIST]',
190
+			'[PRIMARY_REGISTRANT_DATETIME_LIST]',
191
+			'[TICKET_LINE_ITEM_LIST]',
192
+			'[TAX_LINE_ITEM_LIST]',
193
+			'[ADDITIONAL_LINE_ITEM_LIST]',
194
+			'[PRICE_MODIFIER_LINE_ITEM_LIST]',
195
+			'[PAYMENT_LIST_*]',
196
+		);
197
+
198
+		$list_type_shortcodes = apply_filters(
199
+			'FHEE__EEH_Parse_Shortcodes___parse_message_template__list_type_shortcodes',
200
+			$list_type_shortcodes
201
+		);
202
+
203
+		// now lets go ahead and loop through our parsers for each shortcode and setup the values
204
+		foreach ($shortcodes as $shortcode) {
205
+			foreach ($this->_shortcode_objs as $sc_obj) {
206
+				if ($sc_obj instanceof EE_Shortcodes) {
207
+					// we need to setup any dynamic shortcodes so that they work with the array_key_exists
208
+					preg_match_all('/(\[[A-Za-z0-9\_]+_\*)/', $shortcode, $matches);
209
+					$sc_to_verify = ! empty($matches[0]) ? $matches[0][0] . ']' : $shortcode;
210
+
211
+					if (! array_key_exists($sc_to_verify, $sc_obj->get_shortcodes())) {
212
+						continue; // the given shortcode isn't in this object
213
+					}
214
+
215
+					// if this isn't  a "list" type shortcode then we'll send along the data vanilla instead of in an array.
216
+					if (! in_array($sc_to_verify, $list_type_shortcodes)) {
217
+						$data_send = ! is_object($this->_data) && isset($this->_data['data']) ? $this->_data['data'] : $this->_data;
218
+					} else {
219
+						$data_send = $this->_data;
220
+					}
221
+
222
+					// is this a conditional type shortcode?  If it is then we actually parse the template here.
223
+					if ($this->_is_conditional_shortcode($shortcode)) {
224
+						// most shortcode parsers are not going to have a match for this shortcode and will return an
225
+						// empty string so we need to make sure that we're only replacing the template when there is a non empty string.
226
+						$parsed = $sc_obj->parser($shortcode, $data_send, $this->_data['extra_data']);
227
+						if ($parsed) {
228
+							$this->_template = $parsed;
229
+						}
230
+					}
231
+
232
+					$parsed = $sc_obj->parser($shortcode, $data_send, $this->_data['extra_data']);
233
+
234
+					$matched_code[] = $shortcode;
235
+					$sc_values[]    = $parsed;
236
+				}
237
+			}
238
+		}
239
+
240
+		// now we've got parsed values for all the shortcodes in the template so we can go ahead and swap the shortcodes out.
241
+		$parsed = str_replace(array_values($matched_code), array_values($sc_values), $this->_template);
242
+		return $parsed;
243
+	}
244
+
245
+
246
+	/**
247
+	 * Simply returns whether the given shortcode matches the structure for a conditional shortcode.
248
+	 *
249
+	 * Does it match this format: `[IF_`
250
+	 *
251
+	 * @param $shortcode
252
+	 */
253
+	protected function _is_conditional_shortcode($shortcode)
254
+	{
255
+		return strpos($shortcode, '[IF_') === 0;
256
+	}
257
+
258
+
259
+	/**
260
+	 * This sets the shortcodes property from the incoming array of valid shortcodes that corresponds to names of
261
+	 * various EE_Shortcode library objects
262
+	 *
263
+	 * @access private
264
+	 * @param array $valid_shortcodes an array of strings corresponding to EE_Shortcode Library objects
265
+	 * @return void
266
+	 */
267
+	private function _set_shortcodes($valid_shortcodes)
268
+	{
269
+		foreach ($valid_shortcodes as $shortcode_ref) {
270
+			$ref       = ucwords(str_replace('_', ' ', $shortcode_ref));
271
+			$ref       = str_replace(' ', '_', $ref);
272
+			$classname = 'EE_' . $ref . '_Shortcodes';
273
+			if (class_exists($classname)) {
274
+				$this->_shortcode_objs[] = new $classname();
275
+			}
276
+		}
277
+	}
278 278
 }
Please login to merge, or discard this patch.
core/helpers/EEH_Export.helper.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -74,13 +74,13 @@  discard block
 block discarded – undo
74 74
             ) {
75 75
                 // its associative, so we want to output its keys as column headers
76 76
                 $keys = array_keys($item_in_top_level_array);
77
-                $new_file_contents .=  EEH_Export::get_csv_row($keys);
77
+                $new_file_contents .= EEH_Export::get_csv_row($keys);
78 78
             }
79 79
             // start writing data
80 80
             foreach ($data as $data_row) {
81 81
                 $new_file_contents .= EEH_Export::get_csv_row($data_row);
82 82
             }
83
-            return EEH_File::write_to_file($filepath, EEH_File::get_file_contents($filepath) . $new_file_contents);
83
+            return EEH_File::write_to_file($filepath, EEH_File::get_file_contents($filepath).$new_file_contents);
84 84
         } else {
85 85
             // no data TO write... so we can assume that's a success
86 86
             return true;
@@ -118,10 +118,10 @@  discard block
 block discarded – undo
118 118
             }
119 119
 
120 120
             $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
121
-                ( $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure ) : $field_value;
121
+                ($enclosure.str_replace($enclosure, $enclosure.$enclosure, $field_value).$enclosure) : $field_value;
122 122
         }
123 123
 
124
-        return  implode($delimiter, $output) . PHP_EOL;
124
+        return  implode($delimiter, $output).PHP_EOL;
125 125
     }
126 126
 
127 127
 
Please login to merge, or discard this patch.
Indentation   +161 added lines, -161 removed lines patch added patch discarded remove patch
@@ -13,165 +13,165 @@
 block discarded – undo
13 13
  */
14 14
 class EEH_Export
15 15
 {
16
-    /**
17
-     * Gets the 'normal' column named for fields
18
-     * @param EE_Model_Field_Base $field
19
-     * @return string
20
-     * @throws EE_Error
21
-     */
22
-    public static function get_column_name_for_field(EE_Model_Field_Base $field)
23
-    {
24
-        $column_name = wp_specialchars_decode($field->get_nicename(), ENT_QUOTES);
25
-        if (
26
-            apply_filters(
27
-                'FHEE__EEH_Export__get_column_name_for_field__add_field_name',
28
-                false,
29
-                $column_name,
30
-                $field
31
-            )
32
-        ) {
33
-            $column_name .= "["
34
-                . wp_specialchars_decode($field->get_name(), ENT_QUOTES)
35
-                . "]";
36
-        }
37
-        return $column_name;
38
-    }
39
-
40
-    /**
41
-     * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
42
-     *
43
-     * @param string    $filepath
44
-     * @param array     $data 2D array,         first numerically-indexed,
45
-     *                                          and next-level-down preferably indexed by string
46
-     * @param boolean   $write_column_headers   whether or not we should add the keys in the bottom-most array
47
-     *                                          as a row for headers in the CSV.
48
-     *                                            Eg, if $data looked like:
49
-     *                                            array(
50
-     *                                                  0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...),
51
-     *                                                  1=>array(...,...)
52
-     *                                            )
53
-     *
54
-     * @return boolean      if we successfully wrote to the CSV or not. If there's no $data,
55
-     *                      we consider that a success (because we wrote everything there was...nothing)
56
-     * @throws EE_Error
57
-     */
58
-    public static function write_data_array_to_csv($filepath, $data, $write_column_headers = true)
59
-    {
60
-
61
-        $new_file_contents = '';
62
-        // determine if $data is actually a 2d array
63
-        if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
64
-            // make sure top level is numerically indexed,
65
-
66
-            if (EEH_Array::is_associative_array($data)) {
67
-                throw new EE_Error(sprintf(esc_html__("top-level array must be numerically indexed. Does these look like numbers to you? %s", "event_espresso"), implode(",", array_keys($data))));
68
-            }
69
-            $item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
70
-            // now, is the last item in the top-level array of $data an associative or numeric array?
71
-            if (
72
-                $write_column_headers &&
73
-                    EEH_Array::is_associative_array($item_in_top_level_array)
74
-            ) {
75
-                // its associative, so we want to output its keys as column headers
76
-                $keys = array_keys($item_in_top_level_array);
77
-                $new_file_contents .=  EEH_Export::get_csv_row($keys);
78
-            }
79
-            // start writing data
80
-            foreach ($data as $data_row) {
81
-                $new_file_contents .= EEH_Export::get_csv_row($data_row);
82
-            }
83
-            return EEH_File::write_to_file($filepath, EEH_File::get_file_contents($filepath) . $new_file_contents);
84
-        } else {
85
-            // no data TO write... so we can assume that's a success
86
-            return true;
87
-        }
88
-    }
89
-
90
-
91
-
92
-     /**
93
-      *
94
-     *  Writes a row to the csv file
95
-     *  @param array $row - individual row of csv data
96
-     *  @param string $delimiter - csv delimiter
97
-     *  @param string $enclosure - csv enclosure
98
-     *  @param bool $mysql_null - allows php NULL to be overridden with MySQl's insertable NULL value
99
-     *  @return string of text for teh csv file
100
-     */
101
-    public static function get_csv_row(array $row, $delimiter = ',', $enclosure = '"', $mysql_null = false)
102
-    {
103
-        // Allow user to filter the csv delimiter and enclosure for other countries csv standards
104
-        $delimiter = apply_filters('FHEE__EE_CSV__fputcsv2__delimiter', $delimiter);
105
-        $enclosure = apply_filters('FHEE__EE_CSV__fputcsv2__enclosure', $enclosure);
106
-
107
-        $delimiter_esc = preg_quote($delimiter, '/');
108
-        $enclosure_esc = preg_quote($enclosure, '/');
109
-
110
-        $output = array();
111
-        foreach ($row as $field_value) {
112
-            if (is_object($field_value) || is_array($field_value)) {
113
-                $field_value = serialize($field_value);
114
-            }
115
-            if ($field_value === null && $mysql_null) {
116
-                $output[] = 'NULL';
117
-                continue;
118
-            }
119
-
120
-            $output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
121
-                ( $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure ) : $field_value;
122
-        }
123
-
124
-        return  implode($delimiter, $output) . PHP_EOL;
125
-    }
126
-
127
-
128
-
129
-    /**
130
-     * Shortcut for preparing a database result for display
131
-     * @param EEM_Base $model
132
-     * @param string $field_name
133
-     * @param string $raw_db_value
134
-     * @param boolean|string $pretty_schema true to display pretty, a string to use a specific "Schema", or false to NOT display pretty
135
-     * @return string
136
-     */
137
-    public static function prepare_value_from_db_for_display($model, $field_name, $raw_db_value, $pretty_schema = true)
138
-    {
139
-        $field_obj = $model->field_settings_for($field_name);
140
-        $value_on_model_obj = $field_obj->prepare_for_set_from_db($raw_db_value);
141
-        if ($field_obj instanceof EE_Datetime_Field) {
142
-            $field_obj->set_date_format(EEH_Export::get_date_format_for_export($field_obj->get_date_format($pretty_schema)), $pretty_schema);
143
-            $field_obj->set_time_format(EEH_Export::get_time_format_for_export($field_obj->get_time_format($pretty_schema)), $pretty_schema);
144
-        }
145
-        if ($pretty_schema === true) {
146
-            return $field_obj->prepare_for_pretty_echoing($value_on_model_obj);
147
-        } elseif (is_string($pretty_schema)) {
148
-            return $field_obj->prepare_for_pretty_echoing($value_on_model_obj, $pretty_schema);
149
-        } else {
150
-            return $field_obj->prepare_for_get($value_on_model_obj);
151
-        }
152
-    }
153
-
154
-
155
-
156
-    /**
157
-     * Gets the date format to use in exports. filterable
158
-     * @param string $current_format
159
-     * @return string
160
-     */
161
-    public static function get_date_format_for_export($current_format = null)
162
-    {
163
-        return apply_filters('FHEE__EE_CSV__get_date_format_for_csv__format', 'Y-m-d', $current_format);
164
-    }
165
-
166
-
167
-
168
-    /**
169
-     * Gets the time format we want to use in exports. Filterable
170
-     * @param string $current_format
171
-     * @return string
172
-     */
173
-    public static function get_time_format_for_export($current_format = null)
174
-    {
175
-        return apply_filters('FHEE__EE_CSV__get_time_format_for_csv__format', 'H:i:s', $current_format);
176
-    }
16
+	/**
17
+	 * Gets the 'normal' column named for fields
18
+	 * @param EE_Model_Field_Base $field
19
+	 * @return string
20
+	 * @throws EE_Error
21
+	 */
22
+	public static function get_column_name_for_field(EE_Model_Field_Base $field)
23
+	{
24
+		$column_name = wp_specialchars_decode($field->get_nicename(), ENT_QUOTES);
25
+		if (
26
+			apply_filters(
27
+				'FHEE__EEH_Export__get_column_name_for_field__add_field_name',
28
+				false,
29
+				$column_name,
30
+				$field
31
+			)
32
+		) {
33
+			$column_name .= "["
34
+				. wp_specialchars_decode($field->get_name(), ENT_QUOTES)
35
+				. "]";
36
+		}
37
+		return $column_name;
38
+	}
39
+
40
+	/**
41
+	 * Writes $data to the csv file open in $filehandle. uses the array indices of $data for column headers
42
+	 *
43
+	 * @param string    $filepath
44
+	 * @param array     $data 2D array,         first numerically-indexed,
45
+	 *                                          and next-level-down preferably indexed by string
46
+	 * @param boolean   $write_column_headers   whether or not we should add the keys in the bottom-most array
47
+	 *                                          as a row for headers in the CSV.
48
+	 *                                            Eg, if $data looked like:
49
+	 *                                            array(
50
+	 *                                                  0=>array('EVT_ID'=>1,'EVT_name'=>'monkey'...),
51
+	 *                                                  1=>array(...,...)
52
+	 *                                            )
53
+	 *
54
+	 * @return boolean      if we successfully wrote to the CSV or not. If there's no $data,
55
+	 *                      we consider that a success (because we wrote everything there was...nothing)
56
+	 * @throws EE_Error
57
+	 */
58
+	public static function write_data_array_to_csv($filepath, $data, $write_column_headers = true)
59
+	{
60
+
61
+		$new_file_contents = '';
62
+		// determine if $data is actually a 2d array
63
+		if ($data && is_array($data) && is_array(EEH_Array::get_one_item_from_array($data))) {
64
+			// make sure top level is numerically indexed,
65
+
66
+			if (EEH_Array::is_associative_array($data)) {
67
+				throw new EE_Error(sprintf(esc_html__("top-level array must be numerically indexed. Does these look like numbers to you? %s", "event_espresso"), implode(",", array_keys($data))));
68
+			}
69
+			$item_in_top_level_array = EEH_Array::get_one_item_from_array($data);
70
+			// now, is the last item in the top-level array of $data an associative or numeric array?
71
+			if (
72
+				$write_column_headers &&
73
+					EEH_Array::is_associative_array($item_in_top_level_array)
74
+			) {
75
+				// its associative, so we want to output its keys as column headers
76
+				$keys = array_keys($item_in_top_level_array);
77
+				$new_file_contents .=  EEH_Export::get_csv_row($keys);
78
+			}
79
+			// start writing data
80
+			foreach ($data as $data_row) {
81
+				$new_file_contents .= EEH_Export::get_csv_row($data_row);
82
+			}
83
+			return EEH_File::write_to_file($filepath, EEH_File::get_file_contents($filepath) . $new_file_contents);
84
+		} else {
85
+			// no data TO write... so we can assume that's a success
86
+			return true;
87
+		}
88
+	}
89
+
90
+
91
+
92
+	 /**
93
+	  *
94
+	  *  Writes a row to the csv file
95
+	  *  @param array $row - individual row of csv data
96
+	  *  @param string $delimiter - csv delimiter
97
+	  *  @param string $enclosure - csv enclosure
98
+	  *  @param bool $mysql_null - allows php NULL to be overridden with MySQl's insertable NULL value
99
+	  *  @return string of text for teh csv file
100
+	  */
101
+	public static function get_csv_row(array $row, $delimiter = ',', $enclosure = '"', $mysql_null = false)
102
+	{
103
+		// Allow user to filter the csv delimiter and enclosure for other countries csv standards
104
+		$delimiter = apply_filters('FHEE__EE_CSV__fputcsv2__delimiter', $delimiter);
105
+		$enclosure = apply_filters('FHEE__EE_CSV__fputcsv2__enclosure', $enclosure);
106
+
107
+		$delimiter_esc = preg_quote($delimiter, '/');
108
+		$enclosure_esc = preg_quote($enclosure, '/');
109
+
110
+		$output = array();
111
+		foreach ($row as $field_value) {
112
+			if (is_object($field_value) || is_array($field_value)) {
113
+				$field_value = serialize($field_value);
114
+			}
115
+			if ($field_value === null && $mysql_null) {
116
+				$output[] = 'NULL';
117
+				continue;
118
+			}
119
+
120
+			$output[] = preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field_value) ?
121
+				( $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field_value) . $enclosure ) : $field_value;
122
+		}
123
+
124
+		return  implode($delimiter, $output) . PHP_EOL;
125
+	}
126
+
127
+
128
+
129
+	/**
130
+	 * Shortcut for preparing a database result for display
131
+	 * @param EEM_Base $model
132
+	 * @param string $field_name
133
+	 * @param string $raw_db_value
134
+	 * @param boolean|string $pretty_schema true to display pretty, a string to use a specific "Schema", or false to NOT display pretty
135
+	 * @return string
136
+	 */
137
+	public static function prepare_value_from_db_for_display($model, $field_name, $raw_db_value, $pretty_schema = true)
138
+	{
139
+		$field_obj = $model->field_settings_for($field_name);
140
+		$value_on_model_obj = $field_obj->prepare_for_set_from_db($raw_db_value);
141
+		if ($field_obj instanceof EE_Datetime_Field) {
142
+			$field_obj->set_date_format(EEH_Export::get_date_format_for_export($field_obj->get_date_format($pretty_schema)), $pretty_schema);
143
+			$field_obj->set_time_format(EEH_Export::get_time_format_for_export($field_obj->get_time_format($pretty_schema)), $pretty_schema);
144
+		}
145
+		if ($pretty_schema === true) {
146
+			return $field_obj->prepare_for_pretty_echoing($value_on_model_obj);
147
+		} elseif (is_string($pretty_schema)) {
148
+			return $field_obj->prepare_for_pretty_echoing($value_on_model_obj, $pretty_schema);
149
+		} else {
150
+			return $field_obj->prepare_for_get($value_on_model_obj);
151
+		}
152
+	}
153
+
154
+
155
+
156
+	/**
157
+	 * Gets the date format to use in exports. filterable
158
+	 * @param string $current_format
159
+	 * @return string
160
+	 */
161
+	public static function get_date_format_for_export($current_format = null)
162
+	{
163
+		return apply_filters('FHEE__EE_CSV__get_date_format_for_csv__format', 'Y-m-d', $current_format);
164
+	}
165
+
166
+
167
+
168
+	/**
169
+	 * Gets the time format we want to use in exports. Filterable
170
+	 * @param string $current_format
171
+	 * @return string
172
+	 */
173
+	public static function get_time_format_for_export($current_format = null)
174
+	{
175
+		return apply_filters('FHEE__EE_CSV__get_time_format_for_csv__format', 'H:i:s', $current_format);
176
+	}
177 177
 }
Please login to merge, or discard this patch.
core/domain/values/model/CustomSelects.php 2 patches
Indentation   +336 added lines, -336 removed lines patch added patch discarded remove patch
@@ -17,340 +17,340 @@
 block discarded – undo
17 17
  */
18 18
 class CustomSelects
19 19
 {
20
-    const TYPE_SIMPLE = 'simple';
21
-    const TYPE_COMPLEX = 'complex';
22
-    const TYPE_STRUCTURED = 'structured';
23
-
24
-    private $valid_operators = array('COUNT', 'SUM');
25
-
26
-
27
-    /**
28
-     * Original incoming select array
29
-     *
30
-     * @var array
31
-     */
32
-    private $original_selects;
33
-
34
-    /**
35
-     * Select string that can be added to the query
36
-     *
37
-     * @var string
38
-     */
39
-    private $columns_to_select_expression;
40
-
41
-
42
-    /**
43
-     * An array of aliases for the columns included in the incoming select array.
44
-     *
45
-     * @var array
46
-     */
47
-    private $column_aliases_in_select;
48
-
49
-
50
-    /**
51
-     * Enum representation of the "type" of array coming into this value object.
52
-     *
53
-     * @var string
54
-     */
55
-    private $type = '';
56
-
57
-
58
-    /**
59
-     * CustomSelects constructor.
60
-     * Incoming selects can be in one of the following formats:
61
-     * ---- self::TYPE_SIMPLE array ----
62
-     * This is considered the "simple" type. In this case the array is an numerically indexed array with single or
63
-     * multiple columns to select as the values.
64
-     * eg. array( 'ATT_ID', 'REG_ID' )
65
-     * eg. array( '*' )
66
-     * If you want to use the columns in any WHERE, GROUP BY, or HAVING clauses, you must instead use the "complex" or
67
-     * "structured" method.
68
-     * ---- self::TYPE_COMPLEX array ----
69
-     * This is considered the "complex" type.  In this case the array is indexed by arbitrary strings that serve as
70
-     * column alias, and the value is an numerically indexed array where there are two values.  The first value (0) is
71
-     * the selection and the second value (1) is the data type.  Data types must be one of the types defined in
72
-     * EEM_Base::$_valid_wpdb_data_types.
73
-     * eg. array( 'count' => array('count(REG_ID)', '%d') )
74
-     * Complex array configuration allows for using the column alias in any WHERE, GROUP BY, or HAVING clauses.
75
-     * ---- self::TYPE_STRUCTURED array ---
76
-     * This is considered the "structured" type. This type is similar to the complex type except that the array attached
77
-     * to the column alias contains three values.  The first value is the qualified column name (which can include
78
-     * join syntax for models).  The second value is the operator performed on the column (i.e. 'COUNT', 'SUM' etc).,
79
-     * the third value is the data type.  Note, if the select does not have an operator, you can use an empty string for
80
-     * the second value.
81
-     * Note: for now SUM is only for simple single column expressions (i.e. SUM(Transaction.TXN_total))
82
-     * eg. array( 'registration_count' => array('Registration.REG_ID', 'count', '%d') );
83
-     * NOTE: mixing array types in the incoming $select will cause errors.
84
-     *
85
-     * @param array $selects
86
-     * @throws InvalidArgumentException
87
-     */
88
-    public function __construct(array $selects)
89
-    {
90
-        $this->original_selects = $selects;
91
-        $this->deriveType($selects);
92
-        $this->deriveParts($selects);
93
-    }
94
-
95
-
96
-    /**
97
-     * Derives what type of custom select has been sent in.
98
-     *
99
-     * @param array $selects
100
-     * @throws InvalidArgumentException
101
-     */
102
-    private function deriveType(array $selects)
103
-    {
104
-        // first if the first key for this array is an integer then its coming in as a simple format, so we'll also
105
-        // ensure all elements of the array are simple.
106
-        if (is_int(key($selects))) {
107
-            // let's ensure all keys are ints
108
-            $invalid_keys = array_filter(
109
-                array_keys($selects),
110
-                function ($value) {
111
-                    return ! is_int($value);
112
-                }
113
-            );
114
-            if (! empty($invalid_keys)) {
115
-                throw new InvalidArgumentException(
116
-                    sprintf(
117
-                        esc_html__(
118
-                            'Incoming array looks like its formatted for "%1$s" type selects, however it has elements that are not indexed numerically',
119
-                            'event_espresso'
120
-                        ),
121
-                        self::TYPE_SIMPLE
122
-                    )
123
-                );
124
-            }
125
-            $this->type = self::TYPE_SIMPLE;
126
-            return;
127
-        }
128
-        // made it here so that means we've got either complex or structured selects.  Let's find out which by popping
129
-        // the first array element off.
130
-        $first_element = reset($selects);
131
-
132
-        if (! is_array($first_element)) {
133
-            throw new InvalidArgumentException(
134
-                sprintf(
135
-                    esc_html__(
136
-                        'Incoming array looks like its formatted as a "%1$s" or "%2$s" type.  However, the values in the array must be arrays themselves and they are not.',
137
-                        'event_espresso'
138
-                    ),
139
-                    self::TYPE_COMPLEX,
140
-                    self::TYPE_STRUCTURED
141
-                )
142
-            );
143
-        }
144
-        $this->type = count($first_element) === 2
145
-            ? self::TYPE_COMPLEX
146
-            : self::TYPE_STRUCTURED;
147
-    }
148
-
149
-
150
-    /**
151
-     * Sets up the various properties for the vo depending on type.
152
-     *
153
-     * @param array $selects
154
-     * @throws InvalidArgumentException
155
-     */
156
-    private function deriveParts(array $selects)
157
-    {
158
-        $column_parts = array();
159
-        switch ($this->type) {
160
-            case self::TYPE_SIMPLE:
161
-                $column_parts = $selects;
162
-                $this->column_aliases_in_select = $selects;
163
-                break;
164
-            case self::TYPE_COMPLEX:
165
-                foreach ($selects as $alias => $parts) {
166
-                    $this->validateSelectValueForType($parts, $alias);
167
-                    $column_parts[] = "{$parts[0]} AS {$alias}";
168
-                    $this->column_aliases_in_select[] = $alias;
169
-                }
170
-                break;
171
-            case self::TYPE_STRUCTURED:
172
-                foreach ($selects as $alias => $parts) {
173
-                    $this->validateSelectValueForType($parts, $alias);
174
-                    $column_parts[] = $parts[1] !== ''
175
-                        ? $this->assembleSelectStringWithOperator($parts, $alias)
176
-                        : "{$parts[0]} AS {$alias}";
177
-                    $this->column_aliases_in_select[] = $alias;
178
-                }
179
-                break;
180
-        }
181
-        $this->columns_to_select_expression = implode(', ', $column_parts);
182
-    }
183
-
184
-
185
-    /**
186
-     * Validates self::TYPE_COMPLEX and self::TYPE_STRUCTURED select statement parts.
187
-     *
188
-     * @param array  $select_parts
189
-     * @param string $alias
190
-     * @throws InvalidArgumentException
191
-     */
192
-    private function validateSelectValueForType(array $select_parts, $alias)
193
-    {
194
-        $valid_data_types = array('%d', '%s', '%f');
195
-        if (count($select_parts) !== $this->expectedSelectPartCountForType()) {
196
-            throw new InvalidArgumentException(
197
-                sprintf(
198
-                    esc_html__(
199
-                        'The provided select part array for the %1$s column is expected to have a count of %2$d because the incoming select array is of type %3$s.  However the count was %4$d.',
200
-                        'event_espresso'
201
-                    ),
202
-                    $alias,
203
-                    $this->expectedSelectPartCountForType(),
204
-                    $this->type,
205
-                    count($select_parts)
206
-                )
207
-            );
208
-        }
209
-        // validate data type.
210
-        $data_type = $this->type === self::TYPE_COMPLEX ? $select_parts[1] : '';
211
-        $data_type = $this->type === self::TYPE_STRUCTURED ? $select_parts[2] : $data_type;
212
-
213
-        if (! in_array($data_type, $valid_data_types, true)) {
214
-            throw new InvalidArgumentException(
215
-                sprintf(
216
-                    esc_html__(
217
-                        'Datatype %1$s (for selection "%2$s" and alias "%3$s") is not a valid wpdb datatype (eg %%s)',
218
-                        'event_espresso'
219
-                    ),
220
-                    $data_type,
221
-                    $select_parts[0],
222
-                    $alias,
223
-                    implode(', ', $valid_data_types)
224
-                )
225
-            );
226
-        }
227
-    }
228
-
229
-
230
-    /**
231
-     * Each type will have an expected count of array elements, this returns what that expected count is.
232
-     *
233
-     * @param string $type
234
-     * @return int
235
-     */
236
-    private function expectedSelectPartCountForType($type = '')
237
-    {
238
-        $type = $type === '' ? $this->type : $type;
239
-        $types_count_map = array(
240
-            self::TYPE_COMPLEX    => 2,
241
-            self::TYPE_STRUCTURED => 3,
242
-        );
243
-        return isset($types_count_map[ $type ]) ? $types_count_map[ $type ] : 0;
244
-    }
245
-
246
-
247
-    /**
248
-     * Prepares the select statement part for for structured type selects.
249
-     *
250
-     * @param array  $select_parts
251
-     * @param string $alias
252
-     * @return string
253
-     * @throws InvalidArgumentException
254
-     */
255
-    private function assembleSelectStringWithOperator(array $select_parts, $alias)
256
-    {
257
-        $operator = strtoupper($select_parts[1]);
258
-        // validate operator
259
-        if (! in_array($operator, $this->valid_operators, true)) {
260
-            throw new InvalidArgumentException(
261
-                sprintf(
262
-                    esc_html__(
263
-                        'An invalid operator has been provided (%1$s) for the column %2$s.  Valid operators must be one of the following: %3$s.',
264
-                        'event_espresso'
265
-                    ),
266
-                    $operator,
267
-                    $alias,
268
-                    implode(', ', $this->valid_operators)
269
-                )
270
-            );
271
-        }
272
-        return $operator . '(' . $select_parts[0] . ') AS ' . $alias;
273
-    }
274
-
275
-
276
-    /**
277
-     * Return the datatype from the given select part.
278
-     * Remember the select_part has already been validated on object instantiation.
279
-     *
280
-     * @param array $select_part
281
-     * @return string
282
-     */
283
-    private function getDataTypeForSelectType(array $select_part)
284
-    {
285
-        switch ($this->type) {
286
-            case self::TYPE_COMPLEX:
287
-                return $select_part[1];
288
-            case self::TYPE_STRUCTURED:
289
-                return $select_part[2];
290
-            default:
291
-                return '';
292
-        }
293
-    }
294
-
295
-
296
-    /**
297
-     * Returns the original select array sent into the VO.
298
-     *
299
-     * @return array
300
-     */
301
-    public function originalSelects()
302
-    {
303
-        return $this->original_selects;
304
-    }
305
-
306
-
307
-    /**
308
-     * Returns the final assembled select expression derived from the incoming select array.
309
-     *
310
-     * @return string
311
-     */
312
-    public function columnsToSelectExpression()
313
-    {
314
-        return $this->columns_to_select_expression;
315
-    }
316
-
317
-
318
-    /**
319
-     * Returns all the column aliases derived from the incoming select array.
320
-     *
321
-     * @return array
322
-     */
323
-    public function columnAliases()
324
-    {
325
-        return $this->column_aliases_in_select;
326
-    }
327
-
328
-
329
-    /**
330
-     * Returns the enum type for the incoming select array.
331
-     *
332
-     * @return string
333
-     */
334
-    public function type()
335
-    {
336
-        return $this->type;
337
-    }
338
-
339
-
340
-    /**
341
-     * Return the datatype for the given column_alias
342
-     *
343
-     * @param string $column_alias
344
-     * @return string  (if there's no data type we return string as the default).
345
-     */
346
-    public function getDataTypeForAlias($column_alias)
347
-    {
348
-        if (
349
-            isset($this->original_selects[ $column_alias ])
350
-            && in_array($column_alias, $this->columnAliases(), true)
351
-        ) {
352
-            return $this->getDataTypeForSelectType($this->original_selects[ $column_alias ]);
353
-        }
354
-        return '%s';
355
-    }
20
+	const TYPE_SIMPLE = 'simple';
21
+	const TYPE_COMPLEX = 'complex';
22
+	const TYPE_STRUCTURED = 'structured';
23
+
24
+	private $valid_operators = array('COUNT', 'SUM');
25
+
26
+
27
+	/**
28
+	 * Original incoming select array
29
+	 *
30
+	 * @var array
31
+	 */
32
+	private $original_selects;
33
+
34
+	/**
35
+	 * Select string that can be added to the query
36
+	 *
37
+	 * @var string
38
+	 */
39
+	private $columns_to_select_expression;
40
+
41
+
42
+	/**
43
+	 * An array of aliases for the columns included in the incoming select array.
44
+	 *
45
+	 * @var array
46
+	 */
47
+	private $column_aliases_in_select;
48
+
49
+
50
+	/**
51
+	 * Enum representation of the "type" of array coming into this value object.
52
+	 *
53
+	 * @var string
54
+	 */
55
+	private $type = '';
56
+
57
+
58
+	/**
59
+	 * CustomSelects constructor.
60
+	 * Incoming selects can be in one of the following formats:
61
+	 * ---- self::TYPE_SIMPLE array ----
62
+	 * This is considered the "simple" type. In this case the array is an numerically indexed array with single or
63
+	 * multiple columns to select as the values.
64
+	 * eg. array( 'ATT_ID', 'REG_ID' )
65
+	 * eg. array( '*' )
66
+	 * If you want to use the columns in any WHERE, GROUP BY, or HAVING clauses, you must instead use the "complex" or
67
+	 * "structured" method.
68
+	 * ---- self::TYPE_COMPLEX array ----
69
+	 * This is considered the "complex" type.  In this case the array is indexed by arbitrary strings that serve as
70
+	 * column alias, and the value is an numerically indexed array where there are two values.  The first value (0) is
71
+	 * the selection and the second value (1) is the data type.  Data types must be one of the types defined in
72
+	 * EEM_Base::$_valid_wpdb_data_types.
73
+	 * eg. array( 'count' => array('count(REG_ID)', '%d') )
74
+	 * Complex array configuration allows for using the column alias in any WHERE, GROUP BY, or HAVING clauses.
75
+	 * ---- self::TYPE_STRUCTURED array ---
76
+	 * This is considered the "structured" type. This type is similar to the complex type except that the array attached
77
+	 * to the column alias contains three values.  The first value is the qualified column name (which can include
78
+	 * join syntax for models).  The second value is the operator performed on the column (i.e. 'COUNT', 'SUM' etc).,
79
+	 * the third value is the data type.  Note, if the select does not have an operator, you can use an empty string for
80
+	 * the second value.
81
+	 * Note: for now SUM is only for simple single column expressions (i.e. SUM(Transaction.TXN_total))
82
+	 * eg. array( 'registration_count' => array('Registration.REG_ID', 'count', '%d') );
83
+	 * NOTE: mixing array types in the incoming $select will cause errors.
84
+	 *
85
+	 * @param array $selects
86
+	 * @throws InvalidArgumentException
87
+	 */
88
+	public function __construct(array $selects)
89
+	{
90
+		$this->original_selects = $selects;
91
+		$this->deriveType($selects);
92
+		$this->deriveParts($selects);
93
+	}
94
+
95
+
96
+	/**
97
+	 * Derives what type of custom select has been sent in.
98
+	 *
99
+	 * @param array $selects
100
+	 * @throws InvalidArgumentException
101
+	 */
102
+	private function deriveType(array $selects)
103
+	{
104
+		// first if the first key for this array is an integer then its coming in as a simple format, so we'll also
105
+		// ensure all elements of the array are simple.
106
+		if (is_int(key($selects))) {
107
+			// let's ensure all keys are ints
108
+			$invalid_keys = array_filter(
109
+				array_keys($selects),
110
+				function ($value) {
111
+					return ! is_int($value);
112
+				}
113
+			);
114
+			if (! empty($invalid_keys)) {
115
+				throw new InvalidArgumentException(
116
+					sprintf(
117
+						esc_html__(
118
+							'Incoming array looks like its formatted for "%1$s" type selects, however it has elements that are not indexed numerically',
119
+							'event_espresso'
120
+						),
121
+						self::TYPE_SIMPLE
122
+					)
123
+				);
124
+			}
125
+			$this->type = self::TYPE_SIMPLE;
126
+			return;
127
+		}
128
+		// made it here so that means we've got either complex or structured selects.  Let's find out which by popping
129
+		// the first array element off.
130
+		$first_element = reset($selects);
131
+
132
+		if (! is_array($first_element)) {
133
+			throw new InvalidArgumentException(
134
+				sprintf(
135
+					esc_html__(
136
+						'Incoming array looks like its formatted as a "%1$s" or "%2$s" type.  However, the values in the array must be arrays themselves and they are not.',
137
+						'event_espresso'
138
+					),
139
+					self::TYPE_COMPLEX,
140
+					self::TYPE_STRUCTURED
141
+				)
142
+			);
143
+		}
144
+		$this->type = count($first_element) === 2
145
+			? self::TYPE_COMPLEX
146
+			: self::TYPE_STRUCTURED;
147
+	}
148
+
149
+
150
+	/**
151
+	 * Sets up the various properties for the vo depending on type.
152
+	 *
153
+	 * @param array $selects
154
+	 * @throws InvalidArgumentException
155
+	 */
156
+	private function deriveParts(array $selects)
157
+	{
158
+		$column_parts = array();
159
+		switch ($this->type) {
160
+			case self::TYPE_SIMPLE:
161
+				$column_parts = $selects;
162
+				$this->column_aliases_in_select = $selects;
163
+				break;
164
+			case self::TYPE_COMPLEX:
165
+				foreach ($selects as $alias => $parts) {
166
+					$this->validateSelectValueForType($parts, $alias);
167
+					$column_parts[] = "{$parts[0]} AS {$alias}";
168
+					$this->column_aliases_in_select[] = $alias;
169
+				}
170
+				break;
171
+			case self::TYPE_STRUCTURED:
172
+				foreach ($selects as $alias => $parts) {
173
+					$this->validateSelectValueForType($parts, $alias);
174
+					$column_parts[] = $parts[1] !== ''
175
+						? $this->assembleSelectStringWithOperator($parts, $alias)
176
+						: "{$parts[0]} AS {$alias}";
177
+					$this->column_aliases_in_select[] = $alias;
178
+				}
179
+				break;
180
+		}
181
+		$this->columns_to_select_expression = implode(', ', $column_parts);
182
+	}
183
+
184
+
185
+	/**
186
+	 * Validates self::TYPE_COMPLEX and self::TYPE_STRUCTURED select statement parts.
187
+	 *
188
+	 * @param array  $select_parts
189
+	 * @param string $alias
190
+	 * @throws InvalidArgumentException
191
+	 */
192
+	private function validateSelectValueForType(array $select_parts, $alias)
193
+	{
194
+		$valid_data_types = array('%d', '%s', '%f');
195
+		if (count($select_parts) !== $this->expectedSelectPartCountForType()) {
196
+			throw new InvalidArgumentException(
197
+				sprintf(
198
+					esc_html__(
199
+						'The provided select part array for the %1$s column is expected to have a count of %2$d because the incoming select array is of type %3$s.  However the count was %4$d.',
200
+						'event_espresso'
201
+					),
202
+					$alias,
203
+					$this->expectedSelectPartCountForType(),
204
+					$this->type,
205
+					count($select_parts)
206
+				)
207
+			);
208
+		}
209
+		// validate data type.
210
+		$data_type = $this->type === self::TYPE_COMPLEX ? $select_parts[1] : '';
211
+		$data_type = $this->type === self::TYPE_STRUCTURED ? $select_parts[2] : $data_type;
212
+
213
+		if (! in_array($data_type, $valid_data_types, true)) {
214
+			throw new InvalidArgumentException(
215
+				sprintf(
216
+					esc_html__(
217
+						'Datatype %1$s (for selection "%2$s" and alias "%3$s") is not a valid wpdb datatype (eg %%s)',
218
+						'event_espresso'
219
+					),
220
+					$data_type,
221
+					$select_parts[0],
222
+					$alias,
223
+					implode(', ', $valid_data_types)
224
+				)
225
+			);
226
+		}
227
+	}
228
+
229
+
230
+	/**
231
+	 * Each type will have an expected count of array elements, this returns what that expected count is.
232
+	 *
233
+	 * @param string $type
234
+	 * @return int
235
+	 */
236
+	private function expectedSelectPartCountForType($type = '')
237
+	{
238
+		$type = $type === '' ? $this->type : $type;
239
+		$types_count_map = array(
240
+			self::TYPE_COMPLEX    => 2,
241
+			self::TYPE_STRUCTURED => 3,
242
+		);
243
+		return isset($types_count_map[ $type ]) ? $types_count_map[ $type ] : 0;
244
+	}
245
+
246
+
247
+	/**
248
+	 * Prepares the select statement part for for structured type selects.
249
+	 *
250
+	 * @param array  $select_parts
251
+	 * @param string $alias
252
+	 * @return string
253
+	 * @throws InvalidArgumentException
254
+	 */
255
+	private function assembleSelectStringWithOperator(array $select_parts, $alias)
256
+	{
257
+		$operator = strtoupper($select_parts[1]);
258
+		// validate operator
259
+		if (! in_array($operator, $this->valid_operators, true)) {
260
+			throw new InvalidArgumentException(
261
+				sprintf(
262
+					esc_html__(
263
+						'An invalid operator has been provided (%1$s) for the column %2$s.  Valid operators must be one of the following: %3$s.',
264
+						'event_espresso'
265
+					),
266
+					$operator,
267
+					$alias,
268
+					implode(', ', $this->valid_operators)
269
+				)
270
+			);
271
+		}
272
+		return $operator . '(' . $select_parts[0] . ') AS ' . $alias;
273
+	}
274
+
275
+
276
+	/**
277
+	 * Return the datatype from the given select part.
278
+	 * Remember the select_part has already been validated on object instantiation.
279
+	 *
280
+	 * @param array $select_part
281
+	 * @return string
282
+	 */
283
+	private function getDataTypeForSelectType(array $select_part)
284
+	{
285
+		switch ($this->type) {
286
+			case self::TYPE_COMPLEX:
287
+				return $select_part[1];
288
+			case self::TYPE_STRUCTURED:
289
+				return $select_part[2];
290
+			default:
291
+				return '';
292
+		}
293
+	}
294
+
295
+
296
+	/**
297
+	 * Returns the original select array sent into the VO.
298
+	 *
299
+	 * @return array
300
+	 */
301
+	public function originalSelects()
302
+	{
303
+		return $this->original_selects;
304
+	}
305
+
306
+
307
+	/**
308
+	 * Returns the final assembled select expression derived from the incoming select array.
309
+	 *
310
+	 * @return string
311
+	 */
312
+	public function columnsToSelectExpression()
313
+	{
314
+		return $this->columns_to_select_expression;
315
+	}
316
+
317
+
318
+	/**
319
+	 * Returns all the column aliases derived from the incoming select array.
320
+	 *
321
+	 * @return array
322
+	 */
323
+	public function columnAliases()
324
+	{
325
+		return $this->column_aliases_in_select;
326
+	}
327
+
328
+
329
+	/**
330
+	 * Returns the enum type for the incoming select array.
331
+	 *
332
+	 * @return string
333
+	 */
334
+	public function type()
335
+	{
336
+		return $this->type;
337
+	}
338
+
339
+
340
+	/**
341
+	 * Return the datatype for the given column_alias
342
+	 *
343
+	 * @param string $column_alias
344
+	 * @return string  (if there's no data type we return string as the default).
345
+	 */
346
+	public function getDataTypeForAlias($column_alias)
347
+	{
348
+		if (
349
+			isset($this->original_selects[ $column_alias ])
350
+			&& in_array($column_alias, $this->columnAliases(), true)
351
+		) {
352
+			return $this->getDataTypeForSelectType($this->original_selects[ $column_alias ]);
353
+		}
354
+		return '%s';
355
+	}
356 356
 }
Please login to merge, or discard this patch.
Spacing   +9 added lines, -9 removed lines patch added patch discarded remove patch
@@ -107,11 +107,11 @@  discard block
 block discarded – undo
107 107
             // let's ensure all keys are ints
108 108
             $invalid_keys = array_filter(
109 109
                 array_keys($selects),
110
-                function ($value) {
110
+                function($value) {
111 111
                     return ! is_int($value);
112 112
                 }
113 113
             );
114
-            if (! empty($invalid_keys)) {
114
+            if ( ! empty($invalid_keys)) {
115 115
                 throw new InvalidArgumentException(
116 116
                     sprintf(
117 117
                         esc_html__(
@@ -129,7 +129,7 @@  discard block
 block discarded – undo
129 129
         // the first array element off.
130 130
         $first_element = reset($selects);
131 131
 
132
-        if (! is_array($first_element)) {
132
+        if ( ! is_array($first_element)) {
133 133
             throw new InvalidArgumentException(
134 134
                 sprintf(
135 135
                     esc_html__(
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
         $data_type = $this->type === self::TYPE_COMPLEX ? $select_parts[1] : '';
211 211
         $data_type = $this->type === self::TYPE_STRUCTURED ? $select_parts[2] : $data_type;
212 212
 
213
-        if (! in_array($data_type, $valid_data_types, true)) {
213
+        if ( ! in_array($data_type, $valid_data_types, true)) {
214 214
             throw new InvalidArgumentException(
215 215
                 sprintf(
216 216
                     esc_html__(
@@ -240,7 +240,7 @@  discard block
 block discarded – undo
240 240
             self::TYPE_COMPLEX    => 2,
241 241
             self::TYPE_STRUCTURED => 3,
242 242
         );
243
-        return isset($types_count_map[ $type ]) ? $types_count_map[ $type ] : 0;
243
+        return isset($types_count_map[$type]) ? $types_count_map[$type] : 0;
244 244
     }
245 245
 
246 246
 
@@ -256,7 +256,7 @@  discard block
 block discarded – undo
256 256
     {
257 257
         $operator = strtoupper($select_parts[1]);
258 258
         // validate operator
259
-        if (! in_array($operator, $this->valid_operators, true)) {
259
+        if ( ! in_array($operator, $this->valid_operators, true)) {
260 260
             throw new InvalidArgumentException(
261 261
                 sprintf(
262 262
                     esc_html__(
@@ -269,7 +269,7 @@  discard block
 block discarded – undo
269 269
                 )
270 270
             );
271 271
         }
272
-        return $operator . '(' . $select_parts[0] . ') AS ' . $alias;
272
+        return $operator.'('.$select_parts[0].') AS '.$alias;
273 273
     }
274 274
 
275 275
 
@@ -346,10 +346,10 @@  discard block
 block discarded – undo
346 346
     public function getDataTypeForAlias($column_alias)
347 347
     {
348 348
         if (
349
-            isset($this->original_selects[ $column_alias ])
349
+            isset($this->original_selects[$column_alias])
350 350
             && in_array($column_alias, $this->columnAliases(), true)
351 351
         ) {
352
-            return $this->getDataTypeForSelectType($this->original_selects[ $column_alias ]);
352
+            return $this->getDataTypeForSelectType($this->original_selects[$column_alias]);
353 353
         }
354 354
         return '%s';
355 355
     }
Please login to merge, or discard this patch.
core/domain/services/capabilities/CapabilitiesChecker.php 2 patches
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@
 block discarded – undo
62 62
             return true;
63 63
         }
64 64
         // at this point, $cap_check should be an individual instance of CapCheck
65
-        if (! $cap_check instanceof CapCheckInterface) {
65
+        if ( ! $cap_check instanceof CapCheckInterface) {
66 66
             throw new InvalidClassException(
67 67
                 '\EventEspresso\core\domain\services\capabilities\CapCheckInterface'
68 68
             );
Please login to merge, or discard this patch.
Indentation   +74 added lines, -74 removed lines patch added patch discarded remove patch
@@ -17,86 +17,86 @@
 block discarded – undo
17 17
  */
18 18
 class CapabilitiesChecker implements CapabilitiesCheckerInterface
19 19
 {
20
-    /**
21
-     * @type EE_Capabilities $capabilities
22
-     */
23
-    private $capabilities;
20
+	/**
21
+	 * @type EE_Capabilities $capabilities
22
+	 */
23
+	private $capabilities;
24 24
 
25 25
 
26
-    /**
27
-     * CapabilitiesChecker constructor
28
-     *
29
-     * @param EE_Capabilities $capabilities
30
-     */
31
-    public function __construct(EE_Capabilities $capabilities)
32
-    {
33
-        $this->capabilities = $capabilities;
34
-    }
26
+	/**
27
+	 * CapabilitiesChecker constructor
28
+	 *
29
+	 * @param EE_Capabilities $capabilities
30
+	 */
31
+	public function __construct(EE_Capabilities $capabilities)
32
+	{
33
+		$this->capabilities = $capabilities;
34
+	}
35 35
 
36 36
 
37
-    /**
38
-     * @return EE_Capabilities
39
-     */
40
-    protected function capabilities()
41
-    {
42
-        return $this->capabilities;
43
-    }
37
+	/**
38
+	 * @return EE_Capabilities
39
+	 */
40
+	protected function capabilities()
41
+	{
42
+		return $this->capabilities;
43
+	}
44 44
 
45 45
 
46
-    /**
47
-     * Verifies that the current user has ALL of the capabilities listed in the CapCheck DTO.
48
-     * If any of the individual capability checks fails, then the command will NOT be executed.
49
-     *
50
-     * @param CapCheckInterface|CapCheckInterface[] $cap_check
51
-     * @return bool
52
-     * @throws InvalidClassException
53
-     * @throws InsufficientPermissionsException
54
-     */
55
-    public function processCapCheck($cap_check)
56
-    {
57
-        if (is_array($cap_check)) {
58
-            foreach ($cap_check as $check) {
59
-                $this->processCapCheck($check);
60
-            }
61
-            return true;
62
-        }
63
-        // at this point, $cap_check should be an individual instance of CapCheck
64
-        if (! $cap_check instanceof CapCheckInterface) {
65
-            throw new InvalidClassException(
66
-                '\EventEspresso\core\domain\services\capabilities\CapCheckInterface'
67
-            );
68
-        }
69
-        // sometimes cap checks are conditional, and no capabilities are required
70
-        if ($cap_check instanceof PublicCapabilities) {
71
-            return true;
72
-        }
73
-        $capabilities = (array) $cap_check->capability();
74
-        foreach ($capabilities as $capability) {
75
-            if (
76
-                ! $this->capabilities()->current_user_can(
77
-                    $capability,
78
-                    $cap_check->context(),
79
-                    $cap_check->ID()
80
-                )
81
-            ) {
82
-                throw new InsufficientPermissionsException($cap_check->context());
83
-            }
84
-        }
85
-        return true;
86
-    }
46
+	/**
47
+	 * Verifies that the current user has ALL of the capabilities listed in the CapCheck DTO.
48
+	 * If any of the individual capability checks fails, then the command will NOT be executed.
49
+	 *
50
+	 * @param CapCheckInterface|CapCheckInterface[] $cap_check
51
+	 * @return bool
52
+	 * @throws InvalidClassException
53
+	 * @throws InsufficientPermissionsException
54
+	 */
55
+	public function processCapCheck($cap_check)
56
+	{
57
+		if (is_array($cap_check)) {
58
+			foreach ($cap_check as $check) {
59
+				$this->processCapCheck($check);
60
+			}
61
+			return true;
62
+		}
63
+		// at this point, $cap_check should be an individual instance of CapCheck
64
+		if (! $cap_check instanceof CapCheckInterface) {
65
+			throw new InvalidClassException(
66
+				'\EventEspresso\core\domain\services\capabilities\CapCheckInterface'
67
+			);
68
+		}
69
+		// sometimes cap checks are conditional, and no capabilities are required
70
+		if ($cap_check instanceof PublicCapabilities) {
71
+			return true;
72
+		}
73
+		$capabilities = (array) $cap_check->capability();
74
+		foreach ($capabilities as $capability) {
75
+			if (
76
+				! $this->capabilities()->current_user_can(
77
+					$capability,
78
+					$cap_check->context(),
79
+					$cap_check->ID()
80
+				)
81
+			) {
82
+				throw new InsufficientPermissionsException($cap_check->context());
83
+			}
84
+		}
85
+		return true;
86
+	}
87 87
 
88 88
 
89
-    /**
90
-     * @param string $capability - the capability to be checked, like: 'ee_edit_registrations'
91
-     * @param string $context    - what the user is attempting to do, like: 'Edit Registration'
92
-     * @param int    $ID         - (optional) ID for item where current_user_can is being called from
93
-     * @return bool
94
-     * @throws InvalidDataTypeException
95
-     * @throws InsufficientPermissionsException
96
-     * @throws InvalidClassException
97
-     */
98
-    public function process($capability, $context, $ID = 0)
99
-    {
100
-        return $this->processCapCheck(new CapCheck($capability, $context, $ID));
101
-    }
89
+	/**
90
+	 * @param string $capability - the capability to be checked, like: 'ee_edit_registrations'
91
+	 * @param string $context    - what the user is attempting to do, like: 'Edit Registration'
92
+	 * @param int    $ID         - (optional) ID for item where current_user_can is being called from
93
+	 * @return bool
94
+	 * @throws InvalidDataTypeException
95
+	 * @throws InsufficientPermissionsException
96
+	 * @throws InvalidClassException
97
+	 */
98
+	public function process($capability, $context, $ID = 0)
99
+	{
100
+		return $this->processCapCheck(new CapCheck($capability, $context, $ID));
101
+	}
102 102
 }
Please login to merge, or discard this patch.
core/domain/services/event/EventSpacesCalculator.php 2 patches
Spacing   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -181,14 +181,14 @@  discard block
 block discarded – undo
181 181
      */
182 182
     public function setActiveTickets(array $active_tickets = array())
183 183
     {
184
-        if (! empty($active_tickets)) {
184
+        if ( ! empty($active_tickets)) {
185 185
             foreach ($active_tickets as $active_ticket) {
186 186
                 $this->validateTicket($active_ticket);
187 187
             }
188 188
             // sort incoming array by ticket quantity (asc)
189 189
             usort(
190 190
                 $active_tickets,
191
-                function (EE_Ticket $a, EE_Ticket $b) {
191
+                function(EE_Ticket $a, EE_Ticket $b) {
192 192
                     if ($a->qty() === $b->qty()) {
193 193
                         return 0;
194 194
                     }
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
      */
211 211
     private function validateTicket($ticket)
212 212
     {
213
-        if (! $ticket instanceof EE_Ticket) {
213
+        if ( ! $ticket instanceof EE_Ticket) {
214 214
             throw new DomainException(
215 215
                 esc_html__(
216 216
                     'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
                 )
262 262
             );
263 263
         }
264
-        $this->datetimes[ $datetime->ID() ] = $datetime;
264
+        $this->datetimes[$datetime->ID()] = $datetime;
265 265
     }
266 266
 
267 267
 
@@ -340,7 +340,7 @@  discard block
 block discarded – undo
340 340
         $this->tickets_sold = array();
341 341
         $this->total_spaces = array();
342 342
         $active_tickets = $this->getActiveTickets();
343
-        if (! empty($active_tickets)) {
343
+        if ( ! empty($active_tickets)) {
344 344
             foreach ($active_tickets as $ticket) {
345 345
                 $this->validateTicket($ticket);
346 346
                 // we need to index our data arrays using strings for the purpose of sorting,
@@ -362,16 +362,16 @@  discard block
 block discarded – undo
362 362
                     // we are going to move all of our data into the following arrays:
363 363
                     // datetime spaces initially represents the reg limit for each datetime,
364 364
                     // but this will get adjusted as tickets are accounted for
365
-                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
365
+                    $this->datetime_spaces[$datetime_identifier] = $reg_limit;
366 366
                     // just an array of ticket IDs grouped by datetime
367
-                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
367
+                    $this->datetime_tickets[$datetime_identifier][] = $ticket_identifier;
368 368
                     // and an array of datetime IDs grouped by ticket
369
-                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
369
+                    $this->ticket_datetimes[$ticket_identifier][] = $datetime_identifier;
370 370
                 }
371 371
                 // total quantity of sold and reserved for each ticket
372
-                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
372
+                $this->tickets_sold[$ticket_identifier] = $ticket->sold() + $ticket->reserved();
373 373
                 // and the maximum ticket quantities for each ticket (adjusted for reg limit)
374
-                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
374
+                $this->ticket_quantities[$ticket_identifier] = $max_tickets;
375 375
             }
376 376
         }
377 377
         // sort datetime spaces by reg limit, but maintain our string indexes
@@ -430,11 +430,11 @@  discard block
 block discarded – undo
430 430
             \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
431 431
         }
432 432
         foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
433
-            if (isset($this->ticket_quantities[ $ticket_identifier ])) {
434
-                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
433
+            if (isset($this->ticket_quantities[$ticket_identifier])) {
434
+                $this->ticket_quantities[$ticket_identifier] -= $tickets_sold;
435 435
                 // don't let values go below zero
436
-                $this->ticket_quantities[ $ticket_identifier ] = max(
437
-                    $this->ticket_quantities[ $ticket_identifier ],
436
+                $this->ticket_quantities[$ticket_identifier] = max(
437
+                    $this->ticket_quantities[$ticket_identifier],
438 438
                     0
439 439
                 );
440 440
                 if ($this->debug) {
@@ -447,15 +447,15 @@  discard block
 block discarded – undo
447 447
                 }
448 448
             }
449 449
             if (
450
-                isset($this->ticket_datetimes[ $ticket_identifier ])
451
-                && is_array($this->ticket_datetimes[ $ticket_identifier ])
450
+                isset($this->ticket_datetimes[$ticket_identifier])
451
+                && is_array($this->ticket_datetimes[$ticket_identifier])
452 452
             ) {
453
-                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
454
-                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
455
-                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
453
+                foreach ($this->ticket_datetimes[$ticket_identifier] as $ticket_datetime) {
454
+                    if (isset($this->ticket_quantities[$ticket_identifier])) {
455
+                        $this->datetime_spaces[$ticket_datetime] -= $tickets_sold;
456 456
                         // don't let values go below zero
457
-                        $this->datetime_spaces[ $ticket_datetime ] = max(
458
-                            $this->datetime_spaces[ $ticket_datetime ],
457
+                        $this->datetime_spaces[$ticket_datetime] = max(
458
+                            $this->datetime_spaces[$ticket_datetime],
459 459
                             0
460 460
                         );
461 461
                         if ($this->debug) {
@@ -480,11 +480,11 @@  discard block
 block discarded – undo
480 480
     private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
481 481
     {
482 482
         // make sure a reg limit is set for the datetime
483
-        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
484
-            ? $this->datetime_spaces[ $datetime_identifier ]
483
+        $reg_limit = isset($this->datetime_spaces[$datetime_identifier])
484
+            ? $this->datetime_spaces[$datetime_identifier]
485 485
             : 0;
486 486
         // and bail if it is not
487
-        if (! $reg_limit) {
487
+        if ( ! $reg_limit) {
488 488
             if ($this->debug) {
489 489
                 \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
490 490
             }
@@ -501,7 +501,7 @@  discard block
 block discarded – undo
501 501
         }
502 502
         // number of allocated spaces always starts at zero
503 503
         $spaces_allocated = 0;
504
-        $this->total_spaces[ $datetime_identifier ] = 0;
504
+        $this->total_spaces[$datetime_identifier] = 0;
505 505
         foreach ($tickets as $ticket_identifier) {
506 506
             $spaces_allocated = $this->calculateAvailableSpacesForTicket(
507 507
                 $datetime_identifier,
@@ -514,7 +514,7 @@  discard block
 block discarded – undo
514 514
         $spaces_allocated = max($spaces_allocated, 0);
515 515
         if ($spaces_allocated) {
516 516
             // track any non-zero values
517
-            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
517
+            $this->total_spaces[$datetime_identifier] += $spaces_allocated;
518 518
             if ($this->debug) {
519 519
                 \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
520 520
             }
@@ -525,7 +525,7 @@  discard block
 block discarded – undo
525 525
         }
526 526
         if ($this->debug) {
527 527
             \EEH_Debug_Tools::printr(
528
-                $this->total_spaces[ $datetime_identifier ],
528
+                $this->total_spaces[$datetime_identifier],
529 529
                 '$total_spaces',
530 530
                 __FILE__,
531 531
                 __LINE__
@@ -550,8 +550,8 @@  discard block
 block discarded – undo
550 550
         $spaces_allocated
551 551
     ) {
552 552
         // make sure ticket quantity is set
553
-        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
554
-            ? $this->ticket_quantities[ $ticket_identifier ]
553
+        $ticket_quantity = isset($this->ticket_quantities[$ticket_identifier])
554
+            ? $this->ticket_quantities[$ticket_identifier]
555 555
             : 0;
556 556
         if ($this->debug) {
557 557
             \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
@@ -581,7 +581,7 @@  discard block
 block discarded – undo
581 581
                 //  or the maximum ticket quantity
582 582
                 $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
583 583
                 // adjust the available quantity in our tracking array
584
-                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
584
+                $this->ticket_quantities[$ticket_identifier] -= $ticket_quantity;
585 585
                 // and increment spaces allocated for this datetime
586 586
                 $spaces_allocated += $ticket_quantity;
587 587
                 $at_capacity = $spaces_allocated >= $reg_limit;
@@ -638,15 +638,15 @@  discard block
 block discarded – undo
638 638
                 $ticket_quantity
639 639
             );
640 640
             // skip to next ticket if nothing changed
641
-            if (! ($adjusted || $at_capacity)) {
641
+            if ( ! ($adjusted || $at_capacity)) {
642 642
                 continue;
643 643
             }
644 644
             // then all of it's tickets are now unavailable
645 645
             foreach ($datetime_tickets as $datetime_ticket) {
646 646
                 if (
647 647
                     ($ticket_identifier === $datetime_ticket || $at_capacity)
648
-                    && isset($this->ticket_quantities[ $datetime_ticket ])
649
-                    && $this->ticket_quantities[ $datetime_ticket ] > 0
648
+                    && isset($this->ticket_quantities[$datetime_ticket])
649
+                    && $this->ticket_quantities[$datetime_ticket] > 0
650 650
                 ) {
651 651
                     if ($this->debug) {
652 652
                         \EEH_Debug_Tools::printr(
@@ -660,14 +660,14 @@  discard block
 block discarded – undo
660 660
                     // otherwise just subtract the ticket quantity
661 661
                     $new_quantity = $at_capacity
662 662
                         ? 0
663
-                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
663
+                        : $this->ticket_quantities[$datetime_ticket] - $ticket_quantity;
664 664
                     // don't let ticket quantity go below zero
665
-                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
665
+                    $this->ticket_quantities[$datetime_ticket] = max($new_quantity, 0);
666 666
                     if ($this->debug) {
667 667
                         \EEH_Debug_Tools::printr(
668 668
                             $at_capacity
669 669
                                 ? "0 because Datetime {$datetime_identifier} is at capacity"
670
-                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
670
+                                : "{$this->ticket_quantities[$datetime_ticket]}",
671 671
                             " . . . . {$datetime_ticket} quantity set to ",
672 672
                             __FILE__,
673 673
                             __LINE__
@@ -677,8 +677,8 @@  discard block
 block discarded – undo
677 677
                 // but we also need to adjust spaces for any other datetimes this ticket has access to
678 678
                 if ($datetime_ticket === $ticket_identifier) {
679 679
                     if (
680
-                        isset($this->ticket_datetimes[ $datetime_ticket ])
681
-                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
680
+                        isset($this->ticket_datetimes[$datetime_ticket])
681
+                        && is_array($this->ticket_datetimes[$datetime_ticket])
682 682
                     ) {
683 683
                         if ($this->debug) {
684 684
                             \EEH_Debug_Tools::printr(
@@ -688,7 +688,7 @@  discard block
 block discarded – undo
688 688
                                 __LINE__
689 689
                             );
690 690
                         }
691
-                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
691
+                        foreach ($this->ticket_datetimes[$datetime_ticket] as $datetime) {
692 692
                             // don't adjust the current datetime twice
693 693
                             if ($datetime !== $datetime_identifier) {
694 694
                                 $this->adjustDatetimeSpaces(
@@ -709,24 +709,24 @@  discard block
 block discarded – undo
709 709
         // does datetime have spaces available?
710 710
         // and does the supplied ticket have access to this datetime ?
711 711
         if (
712
-            $this->datetime_spaces[ $datetime_identifier ] > 0
713
-            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
714
-            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
712
+            $this->datetime_spaces[$datetime_identifier] > 0
713
+            && isset($this->datetime_spaces[$datetime_identifier], $this->datetime_tickets[$datetime_identifier])
714
+            && in_array($ticket_identifier, $this->datetime_tickets[$datetime_identifier], true)
715 715
         ) {
716 716
             if ($this->debug) {
717 717
                 \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
718 718
                 \EEH_Debug_Tools::printr(
719
-                    "{$this->datetime_spaces[ $datetime_identifier ]}",
719
+                    "{$this->datetime_spaces[$datetime_identifier]}",
720 720
                     " . . current  {$datetime_identifier} spaces available",
721 721
                     __FILE__,
722 722
                     __LINE__
723 723
                 );
724 724
             }
725 725
             // then decrement the available spaces for the datetime
726
-            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
726
+            $this->datetime_spaces[$datetime_identifier] -= $ticket_quantity;
727 727
             // but don't let quantities go below zero
728
-            $this->datetime_spaces[ $datetime_identifier ] = max(
729
-                $this->datetime_spaces[ $datetime_identifier ],
728
+            $this->datetime_spaces[$datetime_identifier] = max(
729
+                $this->datetime_spaces[$datetime_identifier],
730 730
                 0
731 731
             );
732 732
             if ($this->debug) {
Please login to merge, or discard this patch.
Indentation   +715 added lines, -715 removed lines patch added patch discarded remove patch
@@ -25,719 +25,719 @@
 block discarded – undo
25 25
  */
26 26
 class EventSpacesCalculator
27 27
 {
28
-    /**
29
-     * @var EE_Event $event
30
-     */
31
-    private $event;
32
-
33
-    /**
34
-     * @var array $datetime_query_params
35
-     */
36
-    private $datetime_query_params;
37
-
38
-    /**
39
-     * @var EE_Ticket[] $active_tickets
40
-     */
41
-    private $active_tickets = array();
42
-
43
-    /**
44
-     * @var EE_Datetime[] $datetimes
45
-     */
46
-    private $datetimes = array();
47
-
48
-    /**
49
-     * Array of Ticket IDs grouped by Datetime
50
-     *
51
-     * @var array $datetimes
52
-     */
53
-    private $datetime_tickets = array();
54
-
55
-    /**
56
-     * Max spaces for each Datetime (reg limit - previous sold)
57
-     *
58
-     * @var array $datetime_spaces
59
-     */
60
-    private $datetime_spaces = array();
61
-
62
-    /**
63
-     * Array of Datetime IDs grouped by Ticket
64
-     *
65
-     * @var array[] $ticket_datetimes
66
-     */
67
-    private $ticket_datetimes = array();
68
-
69
-    /**
70
-     * maximum ticket quantities for each ticket (adjusted for reg limit)
71
-     *
72
-     * @var array $ticket_quantities
73
-     */
74
-    private $ticket_quantities = array();
75
-
76
-    /**
77
-     * total quantity of sold and reserved for each ticket
78
-     *
79
-     * @var array $tickets_sold
80
-     */
81
-    private $tickets_sold = array();
82
-
83
-    /**
84
-     * total spaces available across all datetimes
85
-     *
86
-     * @var array $total_spaces
87
-     */
88
-    private $total_spaces = array();
89
-
90
-    /**
91
-     * @var boolean $debug
92
-     */
93
-    private $debug = false; // true false
94
-
95
-    /**
96
-     * @var null|int $spaces_remaining
97
-     */
98
-    private $spaces_remaining;
99
-
100
-    /**
101
-     * @var null|int $total_spaces_available
102
-     */
103
-    private $total_spaces_available;
104
-
105
-
106
-    /**
107
-     * EventSpacesCalculator constructor.
108
-     *
109
-     * @param EE_Event $event
110
-     * @param array    $datetime_query_params
111
-     * @throws EE_Error
112
-     */
113
-    public function __construct(EE_Event $event, array $datetime_query_params = array())
114
-    {
115
-        if ($this->debug) {
116
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1);
117
-            \EEH_Debug_Tools::printr((string) $event->ID(), 'For event', __FILE__, __LINE__);
118
-        }
119
-        $this->event = $event;
120
-        $this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
121
-        $this->setHooks();
122
-    }
123
-
124
-
125
-    /**
126
-     * @return void
127
-     */
128
-    private function setHooks()
129
-    {
130
-        add_action('AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
131
-        add_action('AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
132
-        add_action('AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
133
-        add_action('AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
134
-        add_action('AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
135
-        add_action('AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
136
-        add_action('AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
137
-        add_action('AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
138
-    }
139
-
140
-
141
-    /**
142
-     * @return void
143
-     */
144
-    public function clearResults()
145
-    {
146
-        if ($this->debug) {
147
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1);
148
-        }
149
-        $this->spaces_remaining = null;
150
-        $this->total_spaces_available = null;
151
-    }
152
-
153
-
154
-    /**
155
-     * @return EE_Ticket[]
156
-     * @throws EE_Error
157
-     * @throws InvalidDataTypeException
158
-     * @throws InvalidInterfaceException
159
-     * @throws InvalidArgumentException
160
-     */
161
-    public function getActiveTickets()
162
-    {
163
-        if (empty($this->active_tickets)) {
164
-            $this->active_tickets = $this->event->tickets(
165
-                array(
166
-                    array('TKT_deleted' => false),
167
-                    'order_by' => array('TKT_qty' => 'ASC'),
168
-                )
169
-            );
170
-        }
171
-        return $this->active_tickets;
172
-    }
173
-
174
-
175
-    /**
176
-     * @param EE_Ticket[] $active_tickets
177
-     * @throws EE_Error
178
-     * @throws DomainException
179
-     * @throws UnexpectedEntityException
180
-     */
181
-    public function setActiveTickets(array $active_tickets = array())
182
-    {
183
-        if (! empty($active_tickets)) {
184
-            foreach ($active_tickets as $active_ticket) {
185
-                $this->validateTicket($active_ticket);
186
-            }
187
-            // sort incoming array by ticket quantity (asc)
188
-            usort(
189
-                $active_tickets,
190
-                function (EE_Ticket $a, EE_Ticket $b) {
191
-                    if ($a->qty() === $b->qty()) {
192
-                        return 0;
193
-                    }
194
-                    return ($a->qty() < $b->qty())
195
-                        ? -1
196
-                        : 1;
197
-                }
198
-            );
199
-        }
200
-        $this->active_tickets = $active_tickets;
201
-    }
202
-
203
-
204
-    /**
205
-     * @param $ticket
206
-     * @throws DomainException
207
-     * @throws EE_Error
208
-     * @throws UnexpectedEntityException
209
-     */
210
-    private function validateTicket($ticket)
211
-    {
212
-        if (! $ticket instanceof EE_Ticket) {
213
-            throw new DomainException(
214
-                esc_html__(
215
-                    'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
216
-                    'event_espresso'
217
-                )
218
-            );
219
-        }
220
-        if ($ticket->get_event_ID() !== $this->event->ID()) {
221
-            throw new DomainException(
222
-                sprintf(
223
-                    esc_html__(
224
-                        'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
225
-                        'event_espresso'
226
-                    ),
227
-                    $ticket->get_event_ID(),
228
-                    $this->event->ID()
229
-                )
230
-            );
231
-        }
232
-    }
233
-
234
-
235
-    /**
236
-     * @return EE_Datetime[]
237
-     */
238
-    public function getDatetimes()
239
-    {
240
-        return $this->datetimes;
241
-    }
242
-
243
-
244
-    /**
245
-     * @param EE_Datetime $datetime
246
-     * @throws EE_Error
247
-     * @throws DomainException
248
-     */
249
-    public function setDatetime(EE_Datetime $datetime)
250
-    {
251
-        if ($datetime->event()->ID() !== $this->event->ID()) {
252
-            throw new DomainException(
253
-                sprintf(
254
-                    esc_html__(
255
-                        'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
256
-                        'event_espresso'
257
-                    ),
258
-                    $datetime->event()->ID(),
259
-                    $this->event->ID()
260
-                )
261
-            );
262
-        }
263
-        $this->datetimes[ $datetime->ID() ] = $datetime;
264
-    }
265
-
266
-
267
-    /**
268
-     * calculate spaces remaining based on "saleable" tickets
269
-     *
270
-     * @return float|int
271
-     * @throws EE_Error
272
-     * @throws DomainException
273
-     * @throws UnexpectedEntityException
274
-     * @throws InvalidDataTypeException
275
-     * @throws InvalidInterfaceException
276
-     * @throws InvalidArgumentException
277
-     */
278
-    public function spacesRemaining()
279
-    {
280
-        if ($this->debug) {
281
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
282
-        }
283
-        if ($this->spaces_remaining === null) {
284
-            $this->initialize();
285
-            $this->spaces_remaining = $this->calculate();
286
-        }
287
-        return $this->spaces_remaining;
288
-    }
289
-
290
-
291
-    /**
292
-     * calculates total available spaces for an event with no regard for sold tickets
293
-     *
294
-     * @return int|float
295
-     * @throws EE_Error
296
-     * @throws DomainException
297
-     * @throws UnexpectedEntityException
298
-     * @throws InvalidDataTypeException
299
-     * @throws InvalidInterfaceException
300
-     * @throws InvalidArgumentException
301
-     */
302
-    public function totalSpacesAvailable()
303
-    {
304
-        if ($this->debug) {
305
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
306
-        }
307
-        if ($this->total_spaces_available === null) {
308
-            $this->initialize();
309
-            $this->total_spaces_available = $this->calculate(false);
310
-        }
311
-        return $this->total_spaces_available;
312
-    }
313
-
314
-
315
-    /**
316
-     * Loops through the active tickets for the event
317
-     * and builds a series of data arrays that will be used for calculating
318
-     * the total maximum available spaces, as well as the spaces remaining.
319
-     * Because ticket quantities affect datetime spaces and vice versa,
320
-     * we need to be constantly updating these data arrays as things change,
321
-     * which is the entire reason for their existence.
322
-     *
323
-     * @throws EE_Error
324
-     * @throws DomainException
325
-     * @throws UnexpectedEntityException
326
-     * @throws InvalidDataTypeException
327
-     * @throws InvalidInterfaceException
328
-     * @throws InvalidArgumentException
329
-     */
330
-    private function initialize()
331
-    {
332
-        if ($this->debug) {
333
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
334
-        }
335
-        $this->datetime_tickets = array();
336
-        $this->datetime_spaces = array();
337
-        $this->ticket_datetimes = array();
338
-        $this->ticket_quantities = array();
339
-        $this->tickets_sold = array();
340
-        $this->total_spaces = array();
341
-        $active_tickets = $this->getActiveTickets();
342
-        if (! empty($active_tickets)) {
343
-            foreach ($active_tickets as $ticket) {
344
-                $this->validateTicket($ticket);
345
-                // we need to index our data arrays using strings for the purpose of sorting,
346
-                // but we also need them to be unique, so  we'll just prepend a letter T to the ID
347
-                $ticket_identifier = "T{$ticket->ID()}";
348
-                // to start, we'll just consider the raw qty to be the maximum availability for this ticket,
349
-                // unless the ticket is past its "sell until" date, in which case the qty will be 0
350
-                $max_tickets = $ticket->is_expired() ? 0 : $ticket->qty();
351
-                // but we'll adjust that after looping over each datetime for the ticket and checking reg limits
352
-                $ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
353
-                foreach ($ticket_datetimes as $datetime) {
354
-                    // save all datetimes
355
-                    $this->setDatetime($datetime);
356
-                    $datetime_identifier = "D{$datetime->ID()}";
357
-                    $reg_limit = $datetime->reg_limit();
358
-                    // ticket quantity can not exceed datetime reg limit
359
-                    $max_tickets = min($max_tickets, $reg_limit);
360
-                    // as described earlier, because we need to be able to constantly adjust numbers for things,
361
-                    // we are going to move all of our data into the following arrays:
362
-                    // datetime spaces initially represents the reg limit for each datetime,
363
-                    // but this will get adjusted as tickets are accounted for
364
-                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
365
-                    // just an array of ticket IDs grouped by datetime
366
-                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
367
-                    // and an array of datetime IDs grouped by ticket
368
-                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
369
-                }
370
-                // total quantity of sold and reserved for each ticket
371
-                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
372
-                // and the maximum ticket quantities for each ticket (adjusted for reg limit)
373
-                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
374
-            }
375
-        }
376
-        // sort datetime spaces by reg limit, but maintain our string indexes
377
-        asort($this->datetime_spaces, SORT_NUMERIC);
378
-        // datetime tickets need to be sorted in the SAME order as the above array...
379
-        // so we'll just use array_merge() to take the structure of datetime_spaces
380
-        // but overwrite all of the data with that from datetime_tickets
381
-        $this->datetime_tickets = array_merge(
382
-            $this->datetime_spaces,
383
-            $this->datetime_tickets
384
-        );
385
-        if ($this->debug) {
386
-            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
387
-            \EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
388
-            \EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
389
-        }
390
-    }
391
-
392
-
393
-    /**
394
-     * performs calculations on initialized data
395
-     *
396
-     * @param bool $consider_sold
397
-     * @return int|float
398
-     */
399
-    private function calculate($consider_sold = true)
400
-    {
401
-        if ($this->debug) {
402
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
403
-            \EEH_Debug_Tools::printr($consider_sold, '$consider_sold', __FILE__, __LINE__);
404
-        }
405
-        if ($consider_sold) {
406
-            // subtract amounts sold from all ticket quantities and datetime spaces
407
-            $this->adjustTicketQuantitiesDueToSales();
408
-        }
409
-        foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
410
-            $this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
411
-        }
412
-        // total spaces available is just the sum of the spaces available for each datetime
413
-        $spaces_remaining = array_sum($this->total_spaces);
414
-        if ($this->debug) {
415
-            \EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
416
-            \EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
417
-            \EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
418
-        }
419
-        return $spaces_remaining;
420
-    }
421
-
422
-
423
-    /**
424
-     * subtracts amount of  tickets sold from ticket quantities and datetime spaces
425
-     */
426
-    private function adjustTicketQuantitiesDueToSales()
427
-    {
428
-        if ($this->debug) {
429
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
430
-        }
431
-        foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
432
-            if (isset($this->ticket_quantities[ $ticket_identifier ])) {
433
-                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
434
-                // don't let values go below zero
435
-                $this->ticket_quantities[ $ticket_identifier ] = max(
436
-                    $this->ticket_quantities[ $ticket_identifier ],
437
-                    0
438
-                );
439
-                if ($this->debug) {
440
-                    \EEH_Debug_Tools::printr(
441
-                        "{$tickets_sold} sales for ticket {$ticket_identifier} ",
442
-                        'subtracting',
443
-                        __FILE__,
444
-                        __LINE__
445
-                    );
446
-                }
447
-            }
448
-            if (
449
-                isset($this->ticket_datetimes[ $ticket_identifier ])
450
-                && is_array($this->ticket_datetimes[ $ticket_identifier ])
451
-            ) {
452
-                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
453
-                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
454
-                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
455
-                        // don't let values go below zero
456
-                        $this->datetime_spaces[ $ticket_datetime ] = max(
457
-                            $this->datetime_spaces[ $ticket_datetime ],
458
-                            0
459
-                        );
460
-                        if ($this->debug) {
461
-                            \EEH_Debug_Tools::printr(
462
-                                "{$tickets_sold} sales for datetime {$ticket_datetime} ",
463
-                                'subtracting',
464
-                                __FILE__,
465
-                                __LINE__
466
-                            );
467
-                        }
468
-                    }
469
-                }
470
-            }
471
-        }
472
-    }
473
-
474
-
475
-    /**
476
-     * @param string $datetime_identifier
477
-     * @param array  $tickets
478
-     */
479
-    private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
480
-    {
481
-        // make sure a reg limit is set for the datetime
482
-        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
483
-            ? $this->datetime_spaces[ $datetime_identifier ]
484
-            : 0;
485
-        // and bail if it is not
486
-        if (! $reg_limit) {
487
-            if ($this->debug) {
488
-                \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
489
-            }
490
-            return;
491
-        }
492
-        if ($this->debug) {
493
-            \EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
494
-            \EEH_Debug_Tools::printr(
495
-                "{$reg_limit}",
496
-                'REG LIMIT',
497
-                __FILE__,
498
-                __LINE__
499
-            );
500
-        }
501
-        // number of allocated spaces always starts at zero
502
-        $spaces_allocated = 0;
503
-        $this->total_spaces[ $datetime_identifier ] = 0;
504
-        foreach ($tickets as $ticket_identifier) {
505
-            $spaces_allocated = $this->calculateAvailableSpacesForTicket(
506
-                $datetime_identifier,
507
-                $reg_limit,
508
-                $ticket_identifier,
509
-                $spaces_allocated
510
-            );
511
-        }
512
-        // spaces can't be negative
513
-        $spaces_allocated = max($spaces_allocated, 0);
514
-        if ($spaces_allocated) {
515
-            // track any non-zero values
516
-            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
517
-            if ($this->debug) {
518
-                \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
519
-            }
520
-        } else {
521
-            if ($this->debug) {
522
-                \EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
523
-            }
524
-        }
525
-        if ($this->debug) {
526
-            \EEH_Debug_Tools::printr(
527
-                $this->total_spaces[ $datetime_identifier ],
528
-                '$total_spaces',
529
-                __FILE__,
530
-                __LINE__
531
-            );
532
-            \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
533
-            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
534
-        }
535
-    }
536
-
537
-
538
-    /**
539
-     * @param string $datetime_identifier
540
-     * @param int    $reg_limit
541
-     * @param string $ticket_identifier
542
-     * @param int    $spaces_allocated
543
-     * @return int
544
-     */
545
-    private function calculateAvailableSpacesForTicket(
546
-        $datetime_identifier,
547
-        $reg_limit,
548
-        $ticket_identifier,
549
-        $spaces_allocated
550
-    ) {
551
-        // make sure ticket quantity is set
552
-        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
553
-            ? $this->ticket_quantities[ $ticket_identifier ]
554
-            : 0;
555
-        if ($this->debug) {
556
-            \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
557
-            \EEH_Debug_Tools::printr(
558
-                "{$ticket_quantity}",
559
-                "ticket $ticket_identifier quantity: ",
560
-                __FILE__,
561
-                __LINE__,
562
-                2
563
-            );
564
-        }
565
-        if ($ticket_quantity) {
566
-            if ($this->debug) {
567
-                \EEH_Debug_Tools::printr(
568
-                    ($spaces_allocated <= $reg_limit)
569
-                        ? 'true'
570
-                        : 'false',
571
-                    ' . spaces_allocated <= reg_limit = ',
572
-                    __FILE__,
573
-                    __LINE__
574
-                );
575
-            }
576
-            // if the datetime is NOT at full capacity yet
577
-            if ($spaces_allocated <= $reg_limit) {
578
-                // then the maximum ticket quantity we can allocate is the lowest value of either:
579
-                //  the number of remaining spaces for the datetime, which is the limit - spaces already taken
580
-                //  or the maximum ticket quantity
581
-                $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
582
-                // adjust the available quantity in our tracking array
583
-                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
584
-                // and increment spaces allocated for this datetime
585
-                $spaces_allocated += $ticket_quantity;
586
-                $at_capacity = $spaces_allocated >= $reg_limit;
587
-                if ($this->debug) {
588
-                    \EEH_Debug_Tools::printr(
589
-                        "{$ticket_quantity} {$ticket_identifier} tickets",
590
-                        ' > > allocate ',
591
-                        __FILE__,
592
-                        __LINE__,
593
-                        3
594
-                    );
595
-                    if ($at_capacity) {
596
-                        \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
597
-                    }
598
-                }
599
-                // now adjust all other datetimes that allow access to this ticket
600
-                $this->adjustDatetimes(
601
-                    $datetime_identifier,
602
-                    $ticket_identifier,
603
-                    $ticket_quantity,
604
-                    $at_capacity
605
-                );
606
-            }
607
-        }
608
-        return $spaces_allocated;
609
-    }
610
-
611
-
612
-    /**
613
-     * subtracts ticket amounts from all datetime reg limits
614
-     * that allow access to the ticket specified,
615
-     * because that ticket could be used
616
-     * to attend any of the datetimes it has access to
617
-     *
618
-     * @param string $datetime_identifier
619
-     * @param string $ticket_identifier
620
-     * @param bool   $at_capacity
621
-     * @param int    $ticket_quantity
622
-     */
623
-    private function adjustDatetimes(
624
-        $datetime_identifier,
625
-        $ticket_identifier,
626
-        $ticket_quantity,
627
-        $at_capacity
628
-    ) {
629
-        /** @var array $datetime_tickets */
630
-        foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
631
-            if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
632
-                continue;
633
-            }
634
-            $adjusted = $this->adjustDatetimeSpaces(
635
-                $datetime_ID,
636
-                $ticket_identifier,
637
-                $ticket_quantity
638
-            );
639
-            // skip to next ticket if nothing changed
640
-            if (! ($adjusted || $at_capacity)) {
641
-                continue;
642
-            }
643
-            // then all of it's tickets are now unavailable
644
-            foreach ($datetime_tickets as $datetime_ticket) {
645
-                if (
646
-                    ($ticket_identifier === $datetime_ticket || $at_capacity)
647
-                    && isset($this->ticket_quantities[ $datetime_ticket ])
648
-                    && $this->ticket_quantities[ $datetime_ticket ] > 0
649
-                ) {
650
-                    if ($this->debug) {
651
-                        \EEH_Debug_Tools::printr(
652
-                            $datetime_ticket,
653
-                            ' . . . adjust ticket quantities for',
654
-                            __FILE__,
655
-                            __LINE__
656
-                        );
657
-                    }
658
-                    // if this datetime is at full capacity, set any tracked available quantities to zero
659
-                    // otherwise just subtract the ticket quantity
660
-                    $new_quantity = $at_capacity
661
-                        ? 0
662
-                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
663
-                    // don't let ticket quantity go below zero
664
-                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
665
-                    if ($this->debug) {
666
-                        \EEH_Debug_Tools::printr(
667
-                            $at_capacity
668
-                                ? "0 because Datetime {$datetime_identifier} is at capacity"
669
-                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
670
-                            " . . . . {$datetime_ticket} quantity set to ",
671
-                            __FILE__,
672
-                            __LINE__
673
-                        );
674
-                    }
675
-                }
676
-                // but we also need to adjust spaces for any other datetimes this ticket has access to
677
-                if ($datetime_ticket === $ticket_identifier) {
678
-                    if (
679
-                        isset($this->ticket_datetimes[ $datetime_ticket ])
680
-                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
681
-                    ) {
682
-                        if ($this->debug) {
683
-                            \EEH_Debug_Tools::printr(
684
-                                $datetime_ticket,
685
-                                ' . . adjust other Datetimes for',
686
-                                __FILE__,
687
-                                __LINE__
688
-                            );
689
-                        }
690
-                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
691
-                            // don't adjust the current datetime twice
692
-                            if ($datetime !== $datetime_identifier) {
693
-                                $this->adjustDatetimeSpaces(
694
-                                    $datetime,
695
-                                    $datetime_ticket,
696
-                                    $ticket_quantity
697
-                                );
698
-                            }
699
-                        }
700
-                    }
701
-                }
702
-            }
703
-        }
704
-    }
705
-
706
-    private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
707
-    {
708
-        // does datetime have spaces available?
709
-        // and does the supplied ticket have access to this datetime ?
710
-        if (
711
-            $this->datetime_spaces[ $datetime_identifier ] > 0
712
-            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
713
-            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
714
-        ) {
715
-            if ($this->debug) {
716
-                \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
717
-                \EEH_Debug_Tools::printr(
718
-                    "{$this->datetime_spaces[ $datetime_identifier ]}",
719
-                    " . . current  {$datetime_identifier} spaces available",
720
-                    __FILE__,
721
-                    __LINE__
722
-                );
723
-            }
724
-            // then decrement the available spaces for the datetime
725
-            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
726
-            // but don't let quantities go below zero
727
-            $this->datetime_spaces[ $datetime_identifier ] = max(
728
-                $this->datetime_spaces[ $datetime_identifier ],
729
-                0
730
-            );
731
-            if ($this->debug) {
732
-                \EEH_Debug_Tools::printr(
733
-                    "{$ticket_quantity}",
734
-                    " . . . {$datetime_identifier} capacity reduced by",
735
-                    __FILE__,
736
-                    __LINE__
737
-                );
738
-            }
739
-            return true;
740
-        }
741
-        return false;
742
-    }
28
+	/**
29
+	 * @var EE_Event $event
30
+	 */
31
+	private $event;
32
+
33
+	/**
34
+	 * @var array $datetime_query_params
35
+	 */
36
+	private $datetime_query_params;
37
+
38
+	/**
39
+	 * @var EE_Ticket[] $active_tickets
40
+	 */
41
+	private $active_tickets = array();
42
+
43
+	/**
44
+	 * @var EE_Datetime[] $datetimes
45
+	 */
46
+	private $datetimes = array();
47
+
48
+	/**
49
+	 * Array of Ticket IDs grouped by Datetime
50
+	 *
51
+	 * @var array $datetimes
52
+	 */
53
+	private $datetime_tickets = array();
54
+
55
+	/**
56
+	 * Max spaces for each Datetime (reg limit - previous sold)
57
+	 *
58
+	 * @var array $datetime_spaces
59
+	 */
60
+	private $datetime_spaces = array();
61
+
62
+	/**
63
+	 * Array of Datetime IDs grouped by Ticket
64
+	 *
65
+	 * @var array[] $ticket_datetimes
66
+	 */
67
+	private $ticket_datetimes = array();
68
+
69
+	/**
70
+	 * maximum ticket quantities for each ticket (adjusted for reg limit)
71
+	 *
72
+	 * @var array $ticket_quantities
73
+	 */
74
+	private $ticket_quantities = array();
75
+
76
+	/**
77
+	 * total quantity of sold and reserved for each ticket
78
+	 *
79
+	 * @var array $tickets_sold
80
+	 */
81
+	private $tickets_sold = array();
82
+
83
+	/**
84
+	 * total spaces available across all datetimes
85
+	 *
86
+	 * @var array $total_spaces
87
+	 */
88
+	private $total_spaces = array();
89
+
90
+	/**
91
+	 * @var boolean $debug
92
+	 */
93
+	private $debug = false; // true false
94
+
95
+	/**
96
+	 * @var null|int $spaces_remaining
97
+	 */
98
+	private $spaces_remaining;
99
+
100
+	/**
101
+	 * @var null|int $total_spaces_available
102
+	 */
103
+	private $total_spaces_available;
104
+
105
+
106
+	/**
107
+	 * EventSpacesCalculator constructor.
108
+	 *
109
+	 * @param EE_Event $event
110
+	 * @param array    $datetime_query_params
111
+	 * @throws EE_Error
112
+	 */
113
+	public function __construct(EE_Event $event, array $datetime_query_params = array())
114
+	{
115
+		if ($this->debug) {
116
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1);
117
+			\EEH_Debug_Tools::printr((string) $event->ID(), 'For event', __FILE__, __LINE__);
118
+		}
119
+		$this->event = $event;
120
+		$this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
121
+		$this->setHooks();
122
+	}
123
+
124
+
125
+	/**
126
+	 * @return void
127
+	 */
128
+	private function setHooks()
129
+	{
130
+		add_action('AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
131
+		add_action('AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
132
+		add_action('AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
133
+		add_action('AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
134
+		add_action('AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
135
+		add_action('AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
136
+		add_action('AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
137
+		add_action('AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
138
+	}
139
+
140
+
141
+	/**
142
+	 * @return void
143
+	 */
144
+	public function clearResults()
145
+	{
146
+		if ($this->debug) {
147
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 1);
148
+		}
149
+		$this->spaces_remaining = null;
150
+		$this->total_spaces_available = null;
151
+	}
152
+
153
+
154
+	/**
155
+	 * @return EE_Ticket[]
156
+	 * @throws EE_Error
157
+	 * @throws InvalidDataTypeException
158
+	 * @throws InvalidInterfaceException
159
+	 * @throws InvalidArgumentException
160
+	 */
161
+	public function getActiveTickets()
162
+	{
163
+		if (empty($this->active_tickets)) {
164
+			$this->active_tickets = $this->event->tickets(
165
+				array(
166
+					array('TKT_deleted' => false),
167
+					'order_by' => array('TKT_qty' => 'ASC'),
168
+				)
169
+			);
170
+		}
171
+		return $this->active_tickets;
172
+	}
173
+
174
+
175
+	/**
176
+	 * @param EE_Ticket[] $active_tickets
177
+	 * @throws EE_Error
178
+	 * @throws DomainException
179
+	 * @throws UnexpectedEntityException
180
+	 */
181
+	public function setActiveTickets(array $active_tickets = array())
182
+	{
183
+		if (! empty($active_tickets)) {
184
+			foreach ($active_tickets as $active_ticket) {
185
+				$this->validateTicket($active_ticket);
186
+			}
187
+			// sort incoming array by ticket quantity (asc)
188
+			usort(
189
+				$active_tickets,
190
+				function (EE_Ticket $a, EE_Ticket $b) {
191
+					if ($a->qty() === $b->qty()) {
192
+						return 0;
193
+					}
194
+					return ($a->qty() < $b->qty())
195
+						? -1
196
+						: 1;
197
+				}
198
+			);
199
+		}
200
+		$this->active_tickets = $active_tickets;
201
+	}
202
+
203
+
204
+	/**
205
+	 * @param $ticket
206
+	 * @throws DomainException
207
+	 * @throws EE_Error
208
+	 * @throws UnexpectedEntityException
209
+	 */
210
+	private function validateTicket($ticket)
211
+	{
212
+		if (! $ticket instanceof EE_Ticket) {
213
+			throw new DomainException(
214
+				esc_html__(
215
+					'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
216
+					'event_espresso'
217
+				)
218
+			);
219
+		}
220
+		if ($ticket->get_event_ID() !== $this->event->ID()) {
221
+			throw new DomainException(
222
+				sprintf(
223
+					esc_html__(
224
+						'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
225
+						'event_espresso'
226
+					),
227
+					$ticket->get_event_ID(),
228
+					$this->event->ID()
229
+				)
230
+			);
231
+		}
232
+	}
233
+
234
+
235
+	/**
236
+	 * @return EE_Datetime[]
237
+	 */
238
+	public function getDatetimes()
239
+	{
240
+		return $this->datetimes;
241
+	}
242
+
243
+
244
+	/**
245
+	 * @param EE_Datetime $datetime
246
+	 * @throws EE_Error
247
+	 * @throws DomainException
248
+	 */
249
+	public function setDatetime(EE_Datetime $datetime)
250
+	{
251
+		if ($datetime->event()->ID() !== $this->event->ID()) {
252
+			throw new DomainException(
253
+				sprintf(
254
+					esc_html__(
255
+						'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
256
+						'event_espresso'
257
+					),
258
+					$datetime->event()->ID(),
259
+					$this->event->ID()
260
+				)
261
+			);
262
+		}
263
+		$this->datetimes[ $datetime->ID() ] = $datetime;
264
+	}
265
+
266
+
267
+	/**
268
+	 * calculate spaces remaining based on "saleable" tickets
269
+	 *
270
+	 * @return float|int
271
+	 * @throws EE_Error
272
+	 * @throws DomainException
273
+	 * @throws UnexpectedEntityException
274
+	 * @throws InvalidDataTypeException
275
+	 * @throws InvalidInterfaceException
276
+	 * @throws InvalidArgumentException
277
+	 */
278
+	public function spacesRemaining()
279
+	{
280
+		if ($this->debug) {
281
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
282
+		}
283
+		if ($this->spaces_remaining === null) {
284
+			$this->initialize();
285
+			$this->spaces_remaining = $this->calculate();
286
+		}
287
+		return $this->spaces_remaining;
288
+	}
289
+
290
+
291
+	/**
292
+	 * calculates total available spaces for an event with no regard for sold tickets
293
+	 *
294
+	 * @return int|float
295
+	 * @throws EE_Error
296
+	 * @throws DomainException
297
+	 * @throws UnexpectedEntityException
298
+	 * @throws InvalidDataTypeException
299
+	 * @throws InvalidInterfaceException
300
+	 * @throws InvalidArgumentException
301
+	 */
302
+	public function totalSpacesAvailable()
303
+	{
304
+		if ($this->debug) {
305
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
306
+		}
307
+		if ($this->total_spaces_available === null) {
308
+			$this->initialize();
309
+			$this->total_spaces_available = $this->calculate(false);
310
+		}
311
+		return $this->total_spaces_available;
312
+	}
313
+
314
+
315
+	/**
316
+	 * Loops through the active tickets for the event
317
+	 * and builds a series of data arrays that will be used for calculating
318
+	 * the total maximum available spaces, as well as the spaces remaining.
319
+	 * Because ticket quantities affect datetime spaces and vice versa,
320
+	 * we need to be constantly updating these data arrays as things change,
321
+	 * which is the entire reason for their existence.
322
+	 *
323
+	 * @throws EE_Error
324
+	 * @throws DomainException
325
+	 * @throws UnexpectedEntityException
326
+	 * @throws InvalidDataTypeException
327
+	 * @throws InvalidInterfaceException
328
+	 * @throws InvalidArgumentException
329
+	 */
330
+	private function initialize()
331
+	{
332
+		if ($this->debug) {
333
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
334
+		}
335
+		$this->datetime_tickets = array();
336
+		$this->datetime_spaces = array();
337
+		$this->ticket_datetimes = array();
338
+		$this->ticket_quantities = array();
339
+		$this->tickets_sold = array();
340
+		$this->total_spaces = array();
341
+		$active_tickets = $this->getActiveTickets();
342
+		if (! empty($active_tickets)) {
343
+			foreach ($active_tickets as $ticket) {
344
+				$this->validateTicket($ticket);
345
+				// we need to index our data arrays using strings for the purpose of sorting,
346
+				// but we also need them to be unique, so  we'll just prepend a letter T to the ID
347
+				$ticket_identifier = "T{$ticket->ID()}";
348
+				// to start, we'll just consider the raw qty to be the maximum availability for this ticket,
349
+				// unless the ticket is past its "sell until" date, in which case the qty will be 0
350
+				$max_tickets = $ticket->is_expired() ? 0 : $ticket->qty();
351
+				// but we'll adjust that after looping over each datetime for the ticket and checking reg limits
352
+				$ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
353
+				foreach ($ticket_datetimes as $datetime) {
354
+					// save all datetimes
355
+					$this->setDatetime($datetime);
356
+					$datetime_identifier = "D{$datetime->ID()}";
357
+					$reg_limit = $datetime->reg_limit();
358
+					// ticket quantity can not exceed datetime reg limit
359
+					$max_tickets = min($max_tickets, $reg_limit);
360
+					// as described earlier, because we need to be able to constantly adjust numbers for things,
361
+					// we are going to move all of our data into the following arrays:
362
+					// datetime spaces initially represents the reg limit for each datetime,
363
+					// but this will get adjusted as tickets are accounted for
364
+					$this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
365
+					// just an array of ticket IDs grouped by datetime
366
+					$this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
367
+					// and an array of datetime IDs grouped by ticket
368
+					$this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
369
+				}
370
+				// total quantity of sold and reserved for each ticket
371
+				$this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
372
+				// and the maximum ticket quantities for each ticket (adjusted for reg limit)
373
+				$this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
374
+			}
375
+		}
376
+		// sort datetime spaces by reg limit, but maintain our string indexes
377
+		asort($this->datetime_spaces, SORT_NUMERIC);
378
+		// datetime tickets need to be sorted in the SAME order as the above array...
379
+		// so we'll just use array_merge() to take the structure of datetime_spaces
380
+		// but overwrite all of the data with that from datetime_tickets
381
+		$this->datetime_tickets = array_merge(
382
+			$this->datetime_spaces,
383
+			$this->datetime_tickets
384
+		);
385
+		if ($this->debug) {
386
+			\EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
387
+			\EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
388
+			\EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
389
+		}
390
+	}
391
+
392
+
393
+	/**
394
+	 * performs calculations on initialized data
395
+	 *
396
+	 * @param bool $consider_sold
397
+	 * @return int|float
398
+	 */
399
+	private function calculate($consider_sold = true)
400
+	{
401
+		if ($this->debug) {
402
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
403
+			\EEH_Debug_Tools::printr($consider_sold, '$consider_sold', __FILE__, __LINE__);
404
+		}
405
+		if ($consider_sold) {
406
+			// subtract amounts sold from all ticket quantities and datetime spaces
407
+			$this->adjustTicketQuantitiesDueToSales();
408
+		}
409
+		foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
410
+			$this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
411
+		}
412
+		// total spaces available is just the sum of the spaces available for each datetime
413
+		$spaces_remaining = array_sum($this->total_spaces);
414
+		if ($this->debug) {
415
+			\EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
416
+			\EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
417
+			\EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
418
+		}
419
+		return $spaces_remaining;
420
+	}
421
+
422
+
423
+	/**
424
+	 * subtracts amount of  tickets sold from ticket quantities and datetime spaces
425
+	 */
426
+	private function adjustTicketQuantitiesDueToSales()
427
+	{
428
+		if ($this->debug) {
429
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
430
+		}
431
+		foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
432
+			if (isset($this->ticket_quantities[ $ticket_identifier ])) {
433
+				$this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
434
+				// don't let values go below zero
435
+				$this->ticket_quantities[ $ticket_identifier ] = max(
436
+					$this->ticket_quantities[ $ticket_identifier ],
437
+					0
438
+				);
439
+				if ($this->debug) {
440
+					\EEH_Debug_Tools::printr(
441
+						"{$tickets_sold} sales for ticket {$ticket_identifier} ",
442
+						'subtracting',
443
+						__FILE__,
444
+						__LINE__
445
+					);
446
+				}
447
+			}
448
+			if (
449
+				isset($this->ticket_datetimes[ $ticket_identifier ])
450
+				&& is_array($this->ticket_datetimes[ $ticket_identifier ])
451
+			) {
452
+				foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
453
+					if (isset($this->ticket_quantities[ $ticket_identifier ])) {
454
+						$this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
455
+						// don't let values go below zero
456
+						$this->datetime_spaces[ $ticket_datetime ] = max(
457
+							$this->datetime_spaces[ $ticket_datetime ],
458
+							0
459
+						);
460
+						if ($this->debug) {
461
+							\EEH_Debug_Tools::printr(
462
+								"{$tickets_sold} sales for datetime {$ticket_datetime} ",
463
+								'subtracting',
464
+								__FILE__,
465
+								__LINE__
466
+							);
467
+						}
468
+					}
469
+				}
470
+			}
471
+		}
472
+	}
473
+
474
+
475
+	/**
476
+	 * @param string $datetime_identifier
477
+	 * @param array  $tickets
478
+	 */
479
+	private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
480
+	{
481
+		// make sure a reg limit is set for the datetime
482
+		$reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
483
+			? $this->datetime_spaces[ $datetime_identifier ]
484
+			: 0;
485
+		// and bail if it is not
486
+		if (! $reg_limit) {
487
+			if ($this->debug) {
488
+				\EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
489
+			}
490
+			return;
491
+		}
492
+		if ($this->debug) {
493
+			\EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
494
+			\EEH_Debug_Tools::printr(
495
+				"{$reg_limit}",
496
+				'REG LIMIT',
497
+				__FILE__,
498
+				__LINE__
499
+			);
500
+		}
501
+		// number of allocated spaces always starts at zero
502
+		$spaces_allocated = 0;
503
+		$this->total_spaces[ $datetime_identifier ] = 0;
504
+		foreach ($tickets as $ticket_identifier) {
505
+			$spaces_allocated = $this->calculateAvailableSpacesForTicket(
506
+				$datetime_identifier,
507
+				$reg_limit,
508
+				$ticket_identifier,
509
+				$spaces_allocated
510
+			);
511
+		}
512
+		// spaces can't be negative
513
+		$spaces_allocated = max($spaces_allocated, 0);
514
+		if ($spaces_allocated) {
515
+			// track any non-zero values
516
+			$this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
517
+			if ($this->debug) {
518
+				\EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
519
+			}
520
+		} else {
521
+			if ($this->debug) {
522
+				\EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
523
+			}
524
+		}
525
+		if ($this->debug) {
526
+			\EEH_Debug_Tools::printr(
527
+				$this->total_spaces[ $datetime_identifier ],
528
+				'$total_spaces',
529
+				__FILE__,
530
+				__LINE__
531
+			);
532
+			\EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
533
+			\EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
534
+		}
535
+	}
536
+
537
+
538
+	/**
539
+	 * @param string $datetime_identifier
540
+	 * @param int    $reg_limit
541
+	 * @param string $ticket_identifier
542
+	 * @param int    $spaces_allocated
543
+	 * @return int
544
+	 */
545
+	private function calculateAvailableSpacesForTicket(
546
+		$datetime_identifier,
547
+		$reg_limit,
548
+		$ticket_identifier,
549
+		$spaces_allocated
550
+	) {
551
+		// make sure ticket quantity is set
552
+		$ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
553
+			? $this->ticket_quantities[ $ticket_identifier ]
554
+			: 0;
555
+		if ($this->debug) {
556
+			\EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
557
+			\EEH_Debug_Tools::printr(
558
+				"{$ticket_quantity}",
559
+				"ticket $ticket_identifier quantity: ",
560
+				__FILE__,
561
+				__LINE__,
562
+				2
563
+			);
564
+		}
565
+		if ($ticket_quantity) {
566
+			if ($this->debug) {
567
+				\EEH_Debug_Tools::printr(
568
+					($spaces_allocated <= $reg_limit)
569
+						? 'true'
570
+						: 'false',
571
+					' . spaces_allocated <= reg_limit = ',
572
+					__FILE__,
573
+					__LINE__
574
+				);
575
+			}
576
+			// if the datetime is NOT at full capacity yet
577
+			if ($spaces_allocated <= $reg_limit) {
578
+				// then the maximum ticket quantity we can allocate is the lowest value of either:
579
+				//  the number of remaining spaces for the datetime, which is the limit - spaces already taken
580
+				//  or the maximum ticket quantity
581
+				$ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
582
+				// adjust the available quantity in our tracking array
583
+				$this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
584
+				// and increment spaces allocated for this datetime
585
+				$spaces_allocated += $ticket_quantity;
586
+				$at_capacity = $spaces_allocated >= $reg_limit;
587
+				if ($this->debug) {
588
+					\EEH_Debug_Tools::printr(
589
+						"{$ticket_quantity} {$ticket_identifier} tickets",
590
+						' > > allocate ',
591
+						__FILE__,
592
+						__LINE__,
593
+						3
594
+					);
595
+					if ($at_capacity) {
596
+						\EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
597
+					}
598
+				}
599
+				// now adjust all other datetimes that allow access to this ticket
600
+				$this->adjustDatetimes(
601
+					$datetime_identifier,
602
+					$ticket_identifier,
603
+					$ticket_quantity,
604
+					$at_capacity
605
+				);
606
+			}
607
+		}
608
+		return $spaces_allocated;
609
+	}
610
+
611
+
612
+	/**
613
+	 * subtracts ticket amounts from all datetime reg limits
614
+	 * that allow access to the ticket specified,
615
+	 * because that ticket could be used
616
+	 * to attend any of the datetimes it has access to
617
+	 *
618
+	 * @param string $datetime_identifier
619
+	 * @param string $ticket_identifier
620
+	 * @param bool   $at_capacity
621
+	 * @param int    $ticket_quantity
622
+	 */
623
+	private function adjustDatetimes(
624
+		$datetime_identifier,
625
+		$ticket_identifier,
626
+		$ticket_quantity,
627
+		$at_capacity
628
+	) {
629
+		/** @var array $datetime_tickets */
630
+		foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
631
+			if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
632
+				continue;
633
+			}
634
+			$adjusted = $this->adjustDatetimeSpaces(
635
+				$datetime_ID,
636
+				$ticket_identifier,
637
+				$ticket_quantity
638
+			);
639
+			// skip to next ticket if nothing changed
640
+			if (! ($adjusted || $at_capacity)) {
641
+				continue;
642
+			}
643
+			// then all of it's tickets are now unavailable
644
+			foreach ($datetime_tickets as $datetime_ticket) {
645
+				if (
646
+					($ticket_identifier === $datetime_ticket || $at_capacity)
647
+					&& isset($this->ticket_quantities[ $datetime_ticket ])
648
+					&& $this->ticket_quantities[ $datetime_ticket ] > 0
649
+				) {
650
+					if ($this->debug) {
651
+						\EEH_Debug_Tools::printr(
652
+							$datetime_ticket,
653
+							' . . . adjust ticket quantities for',
654
+							__FILE__,
655
+							__LINE__
656
+						);
657
+					}
658
+					// if this datetime is at full capacity, set any tracked available quantities to zero
659
+					// otherwise just subtract the ticket quantity
660
+					$new_quantity = $at_capacity
661
+						? 0
662
+						: $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
663
+					// don't let ticket quantity go below zero
664
+					$this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
665
+					if ($this->debug) {
666
+						\EEH_Debug_Tools::printr(
667
+							$at_capacity
668
+								? "0 because Datetime {$datetime_identifier} is at capacity"
669
+								: "{$this->ticket_quantities[ $datetime_ticket ]}",
670
+							" . . . . {$datetime_ticket} quantity set to ",
671
+							__FILE__,
672
+							__LINE__
673
+						);
674
+					}
675
+				}
676
+				// but we also need to adjust spaces for any other datetimes this ticket has access to
677
+				if ($datetime_ticket === $ticket_identifier) {
678
+					if (
679
+						isset($this->ticket_datetimes[ $datetime_ticket ])
680
+						&& is_array($this->ticket_datetimes[ $datetime_ticket ])
681
+					) {
682
+						if ($this->debug) {
683
+							\EEH_Debug_Tools::printr(
684
+								$datetime_ticket,
685
+								' . . adjust other Datetimes for',
686
+								__FILE__,
687
+								__LINE__
688
+							);
689
+						}
690
+						foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
691
+							// don't adjust the current datetime twice
692
+							if ($datetime !== $datetime_identifier) {
693
+								$this->adjustDatetimeSpaces(
694
+									$datetime,
695
+									$datetime_ticket,
696
+									$ticket_quantity
697
+								);
698
+							}
699
+						}
700
+					}
701
+				}
702
+			}
703
+		}
704
+	}
705
+
706
+	private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
707
+	{
708
+		// does datetime have spaces available?
709
+		// and does the supplied ticket have access to this datetime ?
710
+		if (
711
+			$this->datetime_spaces[ $datetime_identifier ] > 0
712
+			&& isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
713
+			&& in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
714
+		) {
715
+			if ($this->debug) {
716
+				\EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
717
+				\EEH_Debug_Tools::printr(
718
+					"{$this->datetime_spaces[ $datetime_identifier ]}",
719
+					" . . current  {$datetime_identifier} spaces available",
720
+					__FILE__,
721
+					__LINE__
722
+				);
723
+			}
724
+			// then decrement the available spaces for the datetime
725
+			$this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
726
+			// but don't let quantities go below zero
727
+			$this->datetime_spaces[ $datetime_identifier ] = max(
728
+				$this->datetime_spaces[ $datetime_identifier ],
729
+				0
730
+			);
731
+			if ($this->debug) {
732
+				\EEH_Debug_Tools::printr(
733
+					"{$ticket_quantity}",
734
+					" . . . {$datetime_identifier} capacity reduced by",
735
+					__FILE__,
736
+					__LINE__
737
+				);
738
+			}
739
+			return true;
740
+		}
741
+		return false;
742
+	}
743 743
 }
Please login to merge, or discard this patch.
core/domain/entities/shortcodes/EspressoEventAttendees.php 2 patches
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -116,7 +116,7 @@  discard block
 block discarded – undo
116 116
         $attributes['limit'] = (int) $attributes['limit'];
117 117
         $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN);
118 118
         // don't display on archives unless 'display_on_archives' is true
119
-        if ($attributes['limit'] === 0 || (! $display_on_archives && is_archive())) {
119
+        if ($attributes['limit'] === 0 || ( ! $display_on_archives && is_archive())) {
120 120
             return '';
121 121
         }
122 122
         try {
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
      */
318 318
     private function getDatetime(array $attributes)
319 319
     {
320
-        if (! empty($attributes['datetime_id'])) {
320
+        if ( ! empty($attributes['datetime_id'])) {
321 321
             $datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']);
322 322
             if ($datetime instanceof EE_Datetime) {
323 323
                 return $datetime;
@@ -337,7 +337,7 @@  discard block
 block discarded – undo
337 337
      */
338 338
     private function getTicket(array $attributes)
339 339
     {
340
-        if (! empty($attributes['ticket_id'])) {
340
+        if ( ! empty($attributes['ticket_id'])) {
341 341
             $ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']);
342 342
             if ($ticket instanceof EE_Ticket) {
343 343
                 return $ticket;
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
     private function setAdditionalQueryParams(array $attributes)
355 355
     {
356 356
         $reg_status_array = EEM_Registration::reg_status_array();
357
-        if (isset($reg_status_array[ $attributes['status'] ])) {
357
+        if (isset($reg_status_array[$attributes['status']])) {
358 358
             $this->query_params[0]['Registration.STS_ID'] = $attributes['status'];
359 359
         }
360 360
         if (absint($attributes['limit'])) {
Please login to merge, or discard this patch.
Indentation   +310 added lines, -310 removed lines patch added patch discarded remove patch
@@ -30,339 +30,339 @@
 block discarded – undo
30 30
  */
31 31
 class EspressoEventAttendees extends EspressoShortcode
32 32
 {
33
-    private $query_params = array(
34
-        0 => array(),
35
-    );
33
+	private $query_params = array(
34
+		0 => array(),
35
+	);
36 36
 
37
-    private $template_args = array(
38
-        'contacts' => array(),
39
-        'event'    => null,
40
-        'datetime' => null,
41
-        'ticket'   => null,
42
-    );
37
+	private $template_args = array(
38
+		'contacts' => array(),
39
+		'event'    => null,
40
+		'datetime' => null,
41
+		'ticket'   => null,
42
+	);
43 43
 
44
-    /**
45
-     * the actual shortcode tag that gets registered with WordPress
46
-     *
47
-     * @return string
48
-     */
49
-    public function getTag()
50
-    {
51
-        return 'ESPRESSO_EVENT_ATTENDEES';
52
-    }
44
+	/**
45
+	 * the actual shortcode tag that gets registered with WordPress
46
+	 *
47
+	 * @return string
48
+	 */
49
+	public function getTag()
50
+	{
51
+		return 'ESPRESSO_EVENT_ATTENDEES';
52
+	}
53 53
 
54 54
 
55
-    /**
56
-     * the time in seconds to cache the results of the processShortcode() method
57
-     * 0 means the processShortcode() results will NOT be cached at all
58
-     *
59
-     * @return int
60
-     */
61
-    public function cacheExpiration()
62
-    {
63
-        return 0;
64
-    }
55
+	/**
56
+	 * the time in seconds to cache the results of the processShortcode() method
57
+	 * 0 means the processShortcode() results will NOT be cached at all
58
+	 *
59
+	 * @return int
60
+	 */
61
+	public function cacheExpiration()
62
+	{
63
+		return 0;
64
+	}
65 65
 
66 66
 
67
-    /**
68
-     * a place for adding any initialization code that needs to run prior to wp_header().
69
-     * this may be required for shortcodes that utilize a corresponding module,
70
-     * and need to enqueue assets for that module
71
-     *
72
-     * @return void
73
-     */
74
-    public function initializeShortcode()
75
-    {
76
-        $this->shortcodeHasBeenInitialized();
77
-    }
67
+	/**
68
+	 * a place for adding any initialization code that needs to run prior to wp_header().
69
+	 * this may be required for shortcodes that utilize a corresponding module,
70
+	 * and need to enqueue assets for that module
71
+	 *
72
+	 * @return void
73
+	 */
74
+	public function initializeShortcode()
75
+	{
76
+		$this->shortcodeHasBeenInitialized();
77
+	}
78 78
 
79 79
 
80
-    /**
81
-     * process_shortcode - ESPRESSO_EVENT_ATTENDEES - Returns a list of attendees to an event.
82
-     *  [ESPRESSO_EVENT_ATTENDEES]
83
-     *  - defaults to attendees for earliest active event, or earliest upcoming event.
84
-     *  [ESPRESSO_EVENT_ATTENDEES event_id=123]
85
-     *  - attendees for specific event.
86
-     *  [ESPRESSO_EVENT_ATTENDEES datetime_id=245]
87
-     *  - attendees for a specific datetime.
88
-     *  [ESPRESSO_EVENT_ATTENDEES ticket_id=123]
89
-     *  - attendees for a specific ticket.
90
-     *  [ESPRESSO_EVENT_ATTENDEES status=all]
91
-     *  - specific registration status (use status id) or all for all attendees regardless of status.
92
-     *  Note default is to only return approved attendees
93
-     *  [ESPRESSO_EVENT_ATTENDEES show_gravatar=true]
94
-     *  - default is to not return gravatar.  Otherwise if this is set then return gravatar for email address given.
95
-     *  [ESPRESSO_EVENT_ATTENDEES display_on_archives=true]
96
-     *  - default is to not display attendees list on archive pages.
97
-     * Note: because of the relationship between event_id, ticket_id, and datetime_id:
98
-     * If more than one of those params is included, then preference is given to the following:
99
-     *  - event_id is used whenever its present and any others are ignored.
100
-     *  - if no event_id then datetime is used whenever its present and any others are ignored.
101
-     *  - otherwise ticket_id is used if present.
102
-     *
103
-     * @param array $attributes
104
-     * @return string
105
-     * @throws EE_Error
106
-     * @throws InvalidDataTypeException
107
-     * @throws InvalidInterfaceException
108
-     * @throws InvalidArgumentException
109
-     * @throws DomainException
110
-     */
111
-    public function processShortcode($attributes = array())
112
-    {
113
-        // grab attributes and merge with defaults
114
-        $attributes = $this->getAttributes((array) $attributes);
115
-        $attributes['limit'] = (int) $attributes['limit'];
116
-        $display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN);
117
-        // don't display on archives unless 'display_on_archives' is true
118
-        if ($attributes['limit'] === 0 || (! $display_on_archives && is_archive())) {
119
-            return '';
120
-        }
121
-        try {
122
-            $this->setBaseTemplateArguments($attributes);
123
-            $this->validateEntities($attributes);
124
-            $this->setBaseQueryParams();
125
-        } catch (EntityNotFoundException $e) {
126
-            if (WP_DEBUG) {
127
-                return '<div class="important-notice ee-error">'
128
-                       . $e->getMessage()
129
-                       . '</div>';
130
-            }
131
-            return '';
132
-        }
133
-        $this->setAdditionalQueryParams($attributes);
134
-        // get contacts!
135
-        $this->template_args['contacts'] = EEM_Attendee::instance()->get_all($this->query_params);
136
-        // all set let's load up the template and return.
137
-        return EEH_Template::locate_template(
138
-            'loop-espresso_event_attendees.php',
139
-            $this->template_args
140
-        );
141
-    }
80
+	/**
81
+	 * process_shortcode - ESPRESSO_EVENT_ATTENDEES - Returns a list of attendees to an event.
82
+	 *  [ESPRESSO_EVENT_ATTENDEES]
83
+	 *  - defaults to attendees for earliest active event, or earliest upcoming event.
84
+	 *  [ESPRESSO_EVENT_ATTENDEES event_id=123]
85
+	 *  - attendees for specific event.
86
+	 *  [ESPRESSO_EVENT_ATTENDEES datetime_id=245]
87
+	 *  - attendees for a specific datetime.
88
+	 *  [ESPRESSO_EVENT_ATTENDEES ticket_id=123]
89
+	 *  - attendees for a specific ticket.
90
+	 *  [ESPRESSO_EVENT_ATTENDEES status=all]
91
+	 *  - specific registration status (use status id) or all for all attendees regardless of status.
92
+	 *  Note default is to only return approved attendees
93
+	 *  [ESPRESSO_EVENT_ATTENDEES show_gravatar=true]
94
+	 *  - default is to not return gravatar.  Otherwise if this is set then return gravatar for email address given.
95
+	 *  [ESPRESSO_EVENT_ATTENDEES display_on_archives=true]
96
+	 *  - default is to not display attendees list on archive pages.
97
+	 * Note: because of the relationship between event_id, ticket_id, and datetime_id:
98
+	 * If more than one of those params is included, then preference is given to the following:
99
+	 *  - event_id is used whenever its present and any others are ignored.
100
+	 *  - if no event_id then datetime is used whenever its present and any others are ignored.
101
+	 *  - otherwise ticket_id is used if present.
102
+	 *
103
+	 * @param array $attributes
104
+	 * @return string
105
+	 * @throws EE_Error
106
+	 * @throws InvalidDataTypeException
107
+	 * @throws InvalidInterfaceException
108
+	 * @throws InvalidArgumentException
109
+	 * @throws DomainException
110
+	 */
111
+	public function processShortcode($attributes = array())
112
+	{
113
+		// grab attributes and merge with defaults
114
+		$attributes = $this->getAttributes((array) $attributes);
115
+		$attributes['limit'] = (int) $attributes['limit'];
116
+		$display_on_archives = filter_var($attributes['display_on_archives'], FILTER_VALIDATE_BOOLEAN);
117
+		// don't display on archives unless 'display_on_archives' is true
118
+		if ($attributes['limit'] === 0 || (! $display_on_archives && is_archive())) {
119
+			return '';
120
+		}
121
+		try {
122
+			$this->setBaseTemplateArguments($attributes);
123
+			$this->validateEntities($attributes);
124
+			$this->setBaseQueryParams();
125
+		} catch (EntityNotFoundException $e) {
126
+			if (WP_DEBUG) {
127
+				return '<div class="important-notice ee-error">'
128
+					   . $e->getMessage()
129
+					   . '</div>';
130
+			}
131
+			return '';
132
+		}
133
+		$this->setAdditionalQueryParams($attributes);
134
+		// get contacts!
135
+		$this->template_args['contacts'] = EEM_Attendee::instance()->get_all($this->query_params);
136
+		// all set let's load up the template and return.
137
+		return EEH_Template::locate_template(
138
+			'loop-espresso_event_attendees.php',
139
+			$this->template_args
140
+		);
141
+	}
142 142
 
143 143
 
144
-    /**
145
-     * merge incoming attributes with filtered defaults
146
-     *
147
-     * @param array $attributes
148
-     * @return array
149
-     */
150
-    private function getAttributes(array $attributes)
151
-    {
152
-        return (array) apply_filters(
153
-            'EES_Espresso_Event_Attendees__process_shortcode__default_shortcode_atts',
154
-            $attributes + array(
155
-                'event_id'            => null,
156
-                'datetime_id'         => null,
157
-                'ticket_id'           => null,
158
-                'status'              => EEM_Registration::status_id_approved,
159
-                'show_gravatar'       => false,
160
-                'display_on_archives' => false,
161
-                'limit'               => 999,
162
-            )
163
-        );
164
-    }
144
+	/**
145
+	 * merge incoming attributes with filtered defaults
146
+	 *
147
+	 * @param array $attributes
148
+	 * @return array
149
+	 */
150
+	private function getAttributes(array $attributes)
151
+	{
152
+		return (array) apply_filters(
153
+			'EES_Espresso_Event_Attendees__process_shortcode__default_shortcode_atts',
154
+			$attributes + array(
155
+				'event_id'            => null,
156
+				'datetime_id'         => null,
157
+				'ticket_id'           => null,
158
+				'status'              => EEM_Registration::status_id_approved,
159
+				'show_gravatar'       => false,
160
+				'display_on_archives' => false,
161
+				'limit'               => 999,
162
+			)
163
+		);
164
+	}
165 165
 
166 166
 
167
-    /**
168
-     * Set all the base template arguments from the incoming attributes.
169
-     * * Note: because of the relationship between event_id, ticket_id, and datetime_id:
170
-     * If more than one of those params is included, then preference is given to the following:
171
-     *  - event_id is used whenever its present and any others are ignored.
172
-     *  - if no event_id then datetime is used whenever its present and any others are ignored.
173
-     *  - otherwise ticket_id is used if present.
174
-     *
175
-     * @param array $attributes
176
-     * @throws EE_Error
177
-     * @throws InvalidDataTypeException
178
-     * @throws InvalidInterfaceException
179
-     * @throws InvalidArgumentException
180
-     */
181
-    private function setBaseTemplateArguments(array $attributes)
182
-    {
183
-        $this->template_args['show_gravatar'] = $attributes['show_gravatar'];
184
-        $this->template_args['event'] = $this->getEvent($attributes);
185
-        $this->template_args['datetime'] = empty($attributes['event_id'])
186
-            ? $this->getDatetime($attributes)
187
-            : null;
188
-        $this->template_args['ticket'] = empty($attributes['datetime_id']) && empty($attributes['event_id'])
189
-            ? $this->getTicket($attributes)
190
-            : null;
191
-    }
167
+	/**
168
+	 * Set all the base template arguments from the incoming attributes.
169
+	 * * Note: because of the relationship between event_id, ticket_id, and datetime_id:
170
+	 * If more than one of those params is included, then preference is given to the following:
171
+	 *  - event_id is used whenever its present and any others are ignored.
172
+	 *  - if no event_id then datetime is used whenever its present and any others are ignored.
173
+	 *  - otherwise ticket_id is used if present.
174
+	 *
175
+	 * @param array $attributes
176
+	 * @throws EE_Error
177
+	 * @throws InvalidDataTypeException
178
+	 * @throws InvalidInterfaceException
179
+	 * @throws InvalidArgumentException
180
+	 */
181
+	private function setBaseTemplateArguments(array $attributes)
182
+	{
183
+		$this->template_args['show_gravatar'] = $attributes['show_gravatar'];
184
+		$this->template_args['event'] = $this->getEvent($attributes);
185
+		$this->template_args['datetime'] = empty($attributes['event_id'])
186
+			? $this->getDatetime($attributes)
187
+			: null;
188
+		$this->template_args['ticket'] = empty($attributes['datetime_id']) && empty($attributes['event_id'])
189
+			? $this->getTicket($attributes)
190
+			: null;
191
+	}
192 192
 
193 193
 
194
-    /**
195
-     * Validates the presence of entities for the given attribute values.
196
-     *
197
-     * @param array $attributes
198
-     * @throws EntityNotFoundException
199
-     */
200
-    private function validateEntities(array $attributes)
201
-    {
202
-        if (
203
-            ! $this->template_args['event'] instanceof EE_Event
204
-            || (
205
-                empty($attributes['event_id'])
206
-                && $attributes['datetime_id']
207
-                && ! $this->template_args['datetime'] instanceof EE_Datetime
208
-            )
209
-            || (
210
-                empty($attributes['event_id'])
211
-                && empty($attributes['datetime_id'])
212
-                && $attributes['ticket_id']
213
-                && ! $this->template_args['ticket'] instanceof EE_Ticket
214
-            )
215
-        ) {
216
-            throw new EntityNotFoundException(
217
-                '',
218
-                '',
219
-                esc_html__(
220
-                    'The [ESPRESSO_EVENT_ATTENDEES] shortcode has been used incorrectly.  Please double check the arguments you used for any typos.  In the case of ID type arguments, its possible the given ID does not correspond to existing data in the database.',
221
-                    'event_espresso'
222
-                )
223
-            );
224
-        }
225
-    }
194
+	/**
195
+	 * Validates the presence of entities for the given attribute values.
196
+	 *
197
+	 * @param array $attributes
198
+	 * @throws EntityNotFoundException
199
+	 */
200
+	private function validateEntities(array $attributes)
201
+	{
202
+		if (
203
+			! $this->template_args['event'] instanceof EE_Event
204
+			|| (
205
+				empty($attributes['event_id'])
206
+				&& $attributes['datetime_id']
207
+				&& ! $this->template_args['datetime'] instanceof EE_Datetime
208
+			)
209
+			|| (
210
+				empty($attributes['event_id'])
211
+				&& empty($attributes['datetime_id'])
212
+				&& $attributes['ticket_id']
213
+				&& ! $this->template_args['ticket'] instanceof EE_Ticket
214
+			)
215
+		) {
216
+			throw new EntityNotFoundException(
217
+				'',
218
+				'',
219
+				esc_html__(
220
+					'The [ESPRESSO_EVENT_ATTENDEES] shortcode has been used incorrectly.  Please double check the arguments you used for any typos.  In the case of ID type arguments, its possible the given ID does not correspond to existing data in the database.',
221
+					'event_espresso'
222
+				)
223
+			);
224
+		}
225
+	}
226 226
 
227 227
 
228
-    /**
229
-     * Sets the query params for the base query elements.
230
-     */
231
-    private function setBaseQueryParams()
232
-    {
233
-        switch (true) {
234
-            case $this->template_args['datetime'] instanceof EE_Datetime:
235
-                $this->query_params = array(
236
-                    0                          => array(
237
-                        'Registration.Ticket.Datetime.DTT_ID' => $this->template_args['datetime']->ID(),
238
-                    ),
239
-                    'default_where_conditions' => 'this_model_only',
240
-                );
241
-                break;
242
-            case $this->template_args['ticket'] instanceof EE_Ticket:
243
-                $this->query_params[0] = array(
244
-                    'Registration.TKT_ID' => $this->template_args['ticket']->ID(),
245
-                );
246
-                break;
247
-            case $this->template_args['event'] instanceof EE_Event:
248
-                $this->query_params[0] = array(
249
-                    'Registration.EVT_ID' => $this->template_args['event']->ID(),
250
-                );
251
-                break;
252
-        }
253
-    }
228
+	/**
229
+	 * Sets the query params for the base query elements.
230
+	 */
231
+	private function setBaseQueryParams()
232
+	{
233
+		switch (true) {
234
+			case $this->template_args['datetime'] instanceof EE_Datetime:
235
+				$this->query_params = array(
236
+					0                          => array(
237
+						'Registration.Ticket.Datetime.DTT_ID' => $this->template_args['datetime']->ID(),
238
+					),
239
+					'default_where_conditions' => 'this_model_only',
240
+				);
241
+				break;
242
+			case $this->template_args['ticket'] instanceof EE_Ticket:
243
+				$this->query_params[0] = array(
244
+					'Registration.TKT_ID' => $this->template_args['ticket']->ID(),
245
+				);
246
+				break;
247
+			case $this->template_args['event'] instanceof EE_Event:
248
+				$this->query_params[0] = array(
249
+					'Registration.EVT_ID' => $this->template_args['event']->ID(),
250
+				);
251
+				break;
252
+		}
253
+	}
254 254
 
255 255
 
256
-    /**
257
-     * @param array $attributes
258
-     * @return EE_Event|null
259
-     * @throws EE_Error
260
-     * @throws InvalidDataTypeException
261
-     * @throws InvalidInterfaceException
262
-     * @throws InvalidArgumentException
263
-     */
264
-    private function getEvent(array $attributes)
265
-    {
266
-        switch (true) {
267
-            case ! empty($attributes['event_id']):
268
-                $event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']);
269
-                break;
270
-            case ! empty($attributes['datetime_id']):
271
-                $event = EEM_Event::instance()->get_one(array(
272
-                    array(
273
-                        'Datetime.DTT_ID' => $attributes['datetime_id'],
274
-                    ),
275
-                ));
276
-                break;
277
-            case ! empty($attributes['ticket_id']):
278
-                $event = EEM_Event::instance()->get_one(array(
279
-                    array(
280
-                        'Datetime.Ticket.TKT_ID' => $attributes['ticket_id'],
281
-                    ),
282
-                    'default_where_conditions' => 'none'
283
-                ));
284
-                break;
285
-            case is_espresso_event():
286
-                $event = EEH_Event_View::get_event();
287
-                break;
288
-            default:
289
-                // one last shot...
290
-                // try getting the earliest active event
291
-                $events = EEM_Event::instance()->get_active_events(array(
292
-                    'limit'    => 1,
293
-                    'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'),
294
-                ));
295
-                //  if none then get the next upcoming
296
-                $events = empty($events)
297
-                    ? EEM_Event::instance()->get_upcoming_events(array(
298
-                        'limit'    => 1,
299
-                        'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'),
300
-                    ))
301
-                    : $events;
302
-                $event = reset($events);
303
-        }
256
+	/**
257
+	 * @param array $attributes
258
+	 * @return EE_Event|null
259
+	 * @throws EE_Error
260
+	 * @throws InvalidDataTypeException
261
+	 * @throws InvalidInterfaceException
262
+	 * @throws InvalidArgumentException
263
+	 */
264
+	private function getEvent(array $attributes)
265
+	{
266
+		switch (true) {
267
+			case ! empty($attributes['event_id']):
268
+				$event = EEM_Event::instance()->get_one_by_ID($attributes['event_id']);
269
+				break;
270
+			case ! empty($attributes['datetime_id']):
271
+				$event = EEM_Event::instance()->get_one(array(
272
+					array(
273
+						'Datetime.DTT_ID' => $attributes['datetime_id'],
274
+					),
275
+				));
276
+				break;
277
+			case ! empty($attributes['ticket_id']):
278
+				$event = EEM_Event::instance()->get_one(array(
279
+					array(
280
+						'Datetime.Ticket.TKT_ID' => $attributes['ticket_id'],
281
+					),
282
+					'default_where_conditions' => 'none'
283
+				));
284
+				break;
285
+			case is_espresso_event():
286
+				$event = EEH_Event_View::get_event();
287
+				break;
288
+			default:
289
+				// one last shot...
290
+				// try getting the earliest active event
291
+				$events = EEM_Event::instance()->get_active_events(array(
292
+					'limit'    => 1,
293
+					'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'),
294
+				));
295
+				//  if none then get the next upcoming
296
+				$events = empty($events)
297
+					? EEM_Event::instance()->get_upcoming_events(array(
298
+						'limit'    => 1,
299
+						'order_by' => array('Datetime.DTT_EVT_start' => 'ASC'),
300
+					))
301
+					: $events;
302
+				$event = reset($events);
303
+		}
304 304
 
305
-        return $event instanceof EE_Event ? $event : null;
306
-    }
305
+		return $event instanceof EE_Event ? $event : null;
306
+	}
307 307
 
308 308
 
309
-    /**
310
-     * @param array $attributes
311
-     * @return EE_Datetime|null
312
-     * @throws EE_Error
313
-     * @throws InvalidDataTypeException
314
-     * @throws InvalidInterfaceException
315
-     * @throws InvalidArgumentException
316
-     */
317
-    private function getDatetime(array $attributes)
318
-    {
319
-        if (! empty($attributes['datetime_id'])) {
320
-            $datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']);
321
-            if ($datetime instanceof EE_Datetime) {
322
-                return $datetime;
323
-            }
324
-        }
325
-        return null;
326
-    }
309
+	/**
310
+	 * @param array $attributes
311
+	 * @return EE_Datetime|null
312
+	 * @throws EE_Error
313
+	 * @throws InvalidDataTypeException
314
+	 * @throws InvalidInterfaceException
315
+	 * @throws InvalidArgumentException
316
+	 */
317
+	private function getDatetime(array $attributes)
318
+	{
319
+		if (! empty($attributes['datetime_id'])) {
320
+			$datetime = EEM_Datetime::instance()->get_one_by_ID($attributes['datetime_id']);
321
+			if ($datetime instanceof EE_Datetime) {
322
+				return $datetime;
323
+			}
324
+		}
325
+		return null;
326
+	}
327 327
 
328 328
 
329
-    /**
330
-     * @param array $attributes
331
-     * @return \EE_Base_Class|EE_Ticket|null
332
-     * @throws EE_Error
333
-     * @throws InvalidDataTypeException
334
-     * @throws InvalidInterfaceException
335
-     * @throws InvalidArgumentException
336
-     */
337
-    private function getTicket(array $attributes)
338
-    {
339
-        if (! empty($attributes['ticket_id'])) {
340
-            $ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']);
341
-            if ($ticket instanceof EE_Ticket) {
342
-                return $ticket;
343
-            }
344
-        }
345
-        return null;
346
-    }
329
+	/**
330
+	 * @param array $attributes
331
+	 * @return \EE_Base_Class|EE_Ticket|null
332
+	 * @throws EE_Error
333
+	 * @throws InvalidDataTypeException
334
+	 * @throws InvalidInterfaceException
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	private function getTicket(array $attributes)
338
+	{
339
+		if (! empty($attributes['ticket_id'])) {
340
+			$ticket = EEM_Ticket::instance()->get_one_by_ID($attributes['ticket_id']);
341
+			if ($ticket instanceof EE_Ticket) {
342
+				return $ticket;
343
+			}
344
+		}
345
+		return null;
346
+	}
347 347
 
348 348
 
349
-    /**
350
-     * @param array $attributes
351
-     * @throws EE_Error
352
-     */
353
-    private function setAdditionalQueryParams(array $attributes)
354
-    {
355
-        $reg_status_array = EEM_Registration::reg_status_array();
356
-        if (isset($reg_status_array[ $attributes['status'] ])) {
357
-            $this->query_params[0]['Registration.STS_ID'] = $attributes['status'];
358
-        }
359
-        if (absint($attributes['limit'])) {
360
-            $this->query_params['limit'] = $attributes['limit'];
361
-        }
362
-        $this->query_params['group_by'] = array('ATT_ID');
363
-        $this->query_params['order_by'] = (array) apply_filters(
364
-            'FHEE__EES_Espresso_Event_Attendees__process_shortcode__order_by',
365
-            array('ATT_lname' => 'ASC', 'ATT_fname' => 'ASC')
366
-        );
367
-    }
349
+	/**
350
+	 * @param array $attributes
351
+	 * @throws EE_Error
352
+	 */
353
+	private function setAdditionalQueryParams(array $attributes)
354
+	{
355
+		$reg_status_array = EEM_Registration::reg_status_array();
356
+		if (isset($reg_status_array[ $attributes['status'] ])) {
357
+			$this->query_params[0]['Registration.STS_ID'] = $attributes['status'];
358
+		}
359
+		if (absint($attributes['limit'])) {
360
+			$this->query_params['limit'] = $attributes['limit'];
361
+		}
362
+		$this->query_params['group_by'] = array('ATT_ID');
363
+		$this->query_params['order_by'] = (array) apply_filters(
364
+			'FHEE__EES_Espresso_Event_Attendees__process_shortcode__order_by',
365
+			array('ATT_lname' => 'ASC', 'ATT_fname' => 'ASC')
366
+		);
367
+	}
368 368
 }
Please login to merge, or discard this patch.
core/CPTs/EE_CPT_Strategy.core.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -128,7 +128,7 @@  discard block
 block discarded – undo
128 128
         if (is_array($this->_CPTs)) {
129 129
             foreach ($this->_CPTs as $CPT_type => $CPT) {
130 130
                 if (isset($CPT['plural_slug'])) {
131
-                    $_CPT_endpoints [ (string) $CPT['plural_slug'] ] = $CPT_type;
131
+                    $_CPT_endpoints [(string) $CPT['plural_slug']] = $CPT_type;
132 132
                 }
133 133
             }
134 134
         }
@@ -151,7 +151,7 @@  discard block
 block discarded – undo
151 151
     public function pre_get_posts($WP_Query)
152 152
     {
153 153
         // check that post-type is set
154
-        if (! $WP_Query instanceof WP_Query) {
154
+        if ( ! $WP_Query instanceof WP_Query) {
155 155
             return;
156 156
         }
157 157
         // add our conditionals
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
             $terms = EEM_Term::instance()->get_all_CPT_post_tags();
196 196
             foreach ($terms as $term) {
197 197
                 if ($term instanceof EE_Term) {
198
-                    $this->_CPT_terms[ $term->slug() ] = $term;
198
+                    $this->_CPT_terms[$term->slug()] = $term;
199 199
                 }
200 200
             }
201 201
         }
@@ -260,7 +260,7 @@  discard block
 block discarded – undo
260 260
             // loop thru our taxonomies
261 261
             foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) {
262 262
                 // check if one of our taxonomies is set as a query var
263
-                if (isset($WP_Query->query[ $CPT_taxonomy ])) {
263
+                if (isset($WP_Query->query[$CPT_taxonomy])) {
264 264
                     // but which CPT does that correspond to??? hmmm... guess we gotta go looping
265 265
                     foreach ($this->_CPTs as $post_type => $CPT) {
266 266
                         // verify our CPT has args, is public and has taxonomies set
@@ -284,7 +284,7 @@  discard block
 block discarded – undo
284 284
                                     break;
285 285
                                 default:
286 286
                                     do_action(
287
-                                        'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_' . $post_type . '_post_type',
287
+                                        'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_'.$post_type.'_post_type',
288 288
                                         $WP_Query,
289 289
                                         $this
290 290
                                     );
@@ -309,11 +309,11 @@  discard block
 block discarded – undo
309 309
             // loop thru post_types as array
310 310
             foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) {
311 311
                 // is current query for an EE CPT ?
312
-                if (isset($this->_CPTs[ $post_type ])) {
312
+                if (isset($this->_CPTs[$post_type])) {
313 313
                     // is EE on or off ?
314 314
                     if (EE_Maintenance_Mode::instance()->level()) {
315 315
                         // reroute CPT template view to maintenance_mode.template.php
316
-                        if (! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) {
316
+                        if ( ! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) {
317 317
                             add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999);
318 318
                         }
319 319
                         if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) {
@@ -341,7 +341,7 @@  discard block
 block discarded – undo
341 341
             'EventEspresso\core\CPTs\CptQueryModifier',
342 342
             array(
343 343
                 $post_type,
344
-                $this->_CPTs[ $post_type ],
344
+                $this->_CPTs[$post_type],
345 345
                 $WP_Query,
346 346
             )
347 347
         );
Please login to merge, or discard this patch.
Indentation   +445 added lines, -445 removed lines patch added patch discarded remove patch
@@ -15,449 +15,449 @@
 block discarded – undo
15 15
  */
16 16
 class EE_CPT_Strategy extends EE_Base
17 17
 {
18
-    /**
19
-     * @var EE_CPT_Strategy $_instance
20
-     */
21
-    private static $_instance;
22
-
23
-    /**
24
-     * the current page, if it utilizes CPTs
25
-     *
26
-     * @var array $CPT
27
-     */
28
-    protected $CPT;
29
-
30
-    /**
31
-     * return value from CustomPostTypeDefinitions::getDefinitions()
32
-     *
33
-     * @var array $_CPTs
34
-     */
35
-    protected $_CPTs = array();
36
-
37
-    /**
38
-     * @var array $_CPT_taxonomies
39
-     */
40
-    protected $_CPT_taxonomies = array();
41
-
42
-    /**
43
-     * @var array $_CPT_terms
44
-     */
45
-    protected $_CPT_terms = array();
46
-
47
-    /**
48
-     * @var array $_CPT_endpoints
49
-     */
50
-    protected $_CPT_endpoints = array();
51
-
52
-    /**
53
-     * @var EEM_Base $CPT_model
54
-     */
55
-    protected $CPT_model;
56
-
57
-    /**
58
-     * @var EventEspresso\Core\CPTs\CptQueryModifier $query_modifier
59
-     */
60
-    protected $query_modifier;
61
-
62
-
63
-    /**
64
-     * @singleton method used to instantiate class object
65
-     * @param CustomPostTypeDefinitions|null $custom_post_types
66
-     * @param CustomTaxonomyDefinitions|null $taxonomies
67
-     * @return EE_CPT_Strategy
68
-     */
69
-    public static function instance(
70
-        CustomPostTypeDefinitions $custom_post_types = null,
71
-        CustomTaxonomyDefinitions $taxonomies = null
72
-    ) {
73
-        // check if class object is instantiated
74
-        if (
75
-            ! self::$_instance instanceof EE_CPT_Strategy
76
-            && $custom_post_types instanceof CustomPostTypeDefinitions
77
-            && $taxonomies instanceof CustomTaxonomyDefinitions
78
-        ) {
79
-            self::$_instance = new self($custom_post_types, $taxonomies);
80
-        }
81
-        return self::$_instance;
82
-    }
83
-
84
-
85
-    /**
86
-     * @param CustomPostTypeDefinitions $custom_post_types
87
-     * @param CustomTaxonomyDefinitions $taxonomies
88
-     */
89
-    protected function __construct(
90
-        CustomPostTypeDefinitions $custom_post_types,
91
-        CustomTaxonomyDefinitions $taxonomies
92
-    ) {
93
-        // get CPT data
94
-        $this->_CPTs = $custom_post_types->getDefinitions();
95
-        $this->_CPT_endpoints = $this->_set_CPT_endpoints();
96
-        $this->_CPT_taxonomies = $taxonomies->getCustomTaxonomyDefinitions();
97
-        add_action('pre_get_posts', array($this, 'pre_get_posts'), 5);
98
-    }
99
-
100
-
101
-    /**
102
-     * @return array
103
-     */
104
-    public function get_CPT_endpoints()
105
-    {
106
-        return $this->_CPT_endpoints;
107
-    }
108
-
109
-
110
-    /**
111
-     * @return array
112
-     */
113
-    public function get_CPT_taxonomies()
114
-    {
115
-        return $this->_CPT_taxonomies;
116
-    }
117
-
118
-
119
-    /**
120
-     * add CPT "slugs" to array of default espresso "pages"
121
-     *
122
-     * @return array
123
-     */
124
-    private function _set_CPT_endpoints()
125
-    {
126
-        $_CPT_endpoints = array();
127
-        if (is_array($this->_CPTs)) {
128
-            foreach ($this->_CPTs as $CPT_type => $CPT) {
129
-                if (isset($CPT['plural_slug'])) {
130
-                    $_CPT_endpoints [ (string) $CPT['plural_slug'] ] = $CPT_type;
131
-                }
132
-            }
133
-        }
134
-        return $_CPT_endpoints;
135
-    }
136
-
137
-
138
-    /**
139
-     * If this query (not just "main" queries (ie, for WP's infamous "loop")) is for an EE CPT, then we want to
140
-     * supercharge the get_posts query to add our EE stuff (like joining to our tables, selecting extra columns, and
141
-     * adding EE objects to the post to facilitate further querying of related data etc)
142
-     *
143
-     * @param WP_Query $WP_Query
144
-     * @return void
145
-     * @throws \EE_Error
146
-     * @throws \InvalidArgumentException
147
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
148
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
149
-     */
150
-    public function pre_get_posts($WP_Query)
151
-    {
152
-        // check that post-type is set
153
-        if (! $WP_Query instanceof WP_Query) {
154
-            return;
155
-        }
156
-        // add our conditionals
157
-        $this->_set_EE_tags_on_WP_Query($WP_Query);
158
-        // check for terms
159
-        $this->_set_post_type_for_terms($WP_Query);
160
-        // make sure paging is always set
161
-        $this->_set_paging($WP_Query);
162
-        // is a taxonomy set ?
163
-        $this->_set_CPT_taxonomies_on_WP_Query($WP_Query);
164
-        // loop thru post_types if set
165
-        $this->_process_WP_Query_post_types($WP_Query);
166
-    }
167
-
168
-
169
-    /**
170
-     * @param WP_Query $WP_Query
171
-     * @return void
172
-     */
173
-    private function _set_EE_tags_on_WP_Query(WP_Query $WP_Query)
174
-    {
175
-        $WP_Query->is_espresso_event_single = false;
176
-        $WP_Query->is_espresso_event_archive = false;
177
-        $WP_Query->is_espresso_event_taxonomy = false;
178
-        $WP_Query->is_espresso_venue_single = false;
179
-        $WP_Query->is_espresso_venue_archive = false;
180
-        $WP_Query->is_espresso_venue_taxonomy = false;
181
-    }
182
-
183
-
184
-    /**
185
-     * @return void
186
-     * @throws EE_Error
187
-     * @throws InvalidArgumentException
188
-     * @throws InvalidDataTypeException
189
-     * @throws InvalidInterfaceException
190
-     */
191
-    private function _set_CPT_terms()
192
-    {
193
-        if (empty($this->_CPT_terms)) {
194
-            $terms = EEM_Term::instance()->get_all_CPT_post_tags();
195
-            foreach ($terms as $term) {
196
-                if ($term instanceof EE_Term) {
197
-                    $this->_CPT_terms[ $term->slug() ] = $term;
198
-                }
199
-            }
200
-        }
201
-    }
202
-
203
-
204
-    /**
205
-     * @param WP_Query $WP_Query
206
-     * @return void
207
-     * @throws EE_Error
208
-     * @throws InvalidArgumentException
209
-     * @throws InvalidDataTypeException
210
-     * @throws InvalidInterfaceException
211
-     */
212
-    private function _set_post_type_for_terms(WP_Query $WP_Query)
213
-    {
214
-        // is a tag set ?
215
-        if (isset($WP_Query->query['tag'])) {
216
-            // get term for tag
217
-            $term = EEM_Term::instance()->get_post_tag_for_event_or_venue($WP_Query->query['tag']);
218
-            // verify the term
219
-            if ($term instanceof EE_Term) {
220
-                $term->post_type = array_merge(array('post', 'page'), (array) $term->post_type);
221
-                $term->post_type = apply_filters(
222
-                    'FHEE__EE_CPT_Strategy___set_post_type_for_terms__term_post_type',
223
-                    $term->post_type,
224
-                    $term
225
-                );
226
-                // if a post type is already set
227
-                if (isset($WP_Query->query_vars['post_type'])) {
228
-                    // add to existing array
229
-                    $term->post_type = array_merge((array) $WP_Query->query_vars['post_type'], $term->post_type);
230
-                }
231
-                // just set post_type to our CPT
232
-                $WP_Query->set('post_type', array_unique($term->post_type));
233
-            }
234
-        }
235
-    }
236
-
237
-
238
-    /**
239
-     * @param WP_Query $WP_Query
240
-     * @return void
241
-     */
242
-    public function _set_paging($WP_Query)
243
-    {
244
-        if ($WP_Query->is_main_query() && apply_filters('FHEE__EE_CPT_Strategy___set_paging', true)) {
245
-            $page = get_query_var('page') ? get_query_var('page') : null;
246
-            $paged = get_query_var('paged') ? get_query_var('paged') : $page;
247
-            $WP_Query->set('paged', $paged);
248
-        }
249
-    }
250
-
251
-
252
-    /**
253
-     * @param \WP_Query $WP_Query
254
-     */
255
-    protected function _set_CPT_taxonomies_on_WP_Query(WP_Query $WP_Query)
256
-    {
257
-        // is a taxonomy set ?
258
-        if ($WP_Query->is_tax) {
259
-            // loop thru our taxonomies
260
-            foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) {
261
-                // check if one of our taxonomies is set as a query var
262
-                if (isset($WP_Query->query[ $CPT_taxonomy ])) {
263
-                    // but which CPT does that correspond to??? hmmm... guess we gotta go looping
264
-                    foreach ($this->_CPTs as $post_type => $CPT) {
265
-                        // verify our CPT has args, is public and has taxonomies set
266
-                        if (
267
-                            isset($CPT['args']['public'])
268
-                            && $CPT['args']['public']
269
-                            && ! empty($CPT['args']['taxonomies'])
270
-                            && in_array($CPT_taxonomy, $CPT['args']['taxonomies'], true)
271
-                        ) {
272
-                            // if so, then add this CPT post_type to the current query's array of post_types'
273
-                            $WP_Query->query_vars['post_type'] = isset($WP_Query->query_vars['post_type'])
274
-                                ? (array) $WP_Query->query_vars['post_type']
275
-                                : array();
276
-                            $WP_Query->query_vars['post_type'][] = $post_type;
277
-                            switch ($post_type) {
278
-                                case 'espresso_events':
279
-                                    $WP_Query->is_espresso_event_taxonomy = true;
280
-                                    break;
281
-                                case 'espresso_venues':
282
-                                    $WP_Query->is_espresso_venue_taxonomy = true;
283
-                                    break;
284
-                                default:
285
-                                    do_action(
286
-                                        'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_' . $post_type . '_post_type',
287
-                                        $WP_Query,
288
-                                        $this
289
-                                    );
290
-                            }
291
-                        }
292
-                    }
293
-                }
294
-            }
295
-        }
296
-    }
297
-
298
-
299
-    /**
300
-     * @param \WP_Query $WP_Query
301
-     * @throws InvalidArgumentException
302
-     * @throws InvalidDataTypeException
303
-     * @throws InvalidInterfaceException
304
-     */
305
-    protected function _process_WP_Query_post_types(WP_Query $WP_Query)
306
-    {
307
-        if (isset($WP_Query->query_vars['post_type'])) {
308
-            // loop thru post_types as array
309
-            foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) {
310
-                // is current query for an EE CPT ?
311
-                if (isset($this->_CPTs[ $post_type ])) {
312
-                    // is EE on or off ?
313
-                    if (EE_Maintenance_Mode::instance()->level()) {
314
-                        // reroute CPT template view to maintenance_mode.template.php
315
-                        if (! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) {
316
-                            add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999);
317
-                        }
318
-                        if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) {
319
-                            add_filter('the_content', array($this, 'inject_EE_shortcode_placeholder'), 1);
320
-                        }
321
-                        return;
322
-                    }
323
-                    $this->_generate_CptQueryModifier($WP_Query, $post_type);
324
-                }
325
-            }
326
-        }
327
-    }
328
-
329
-
330
-    /**
331
-     * @param \WP_Query $WP_Query
332
-     * @param string    $post_type
333
-     * @throws InvalidArgumentException
334
-     * @throws InvalidDataTypeException
335
-     * @throws InvalidInterfaceException
336
-     */
337
-    protected function _generate_CptQueryModifier(WP_Query $WP_Query, $post_type)
338
-    {
339
-        $this->query_modifier = LoaderFactory::getLoader()->getShared(
340
-            'EventEspresso\core\CPTs\CptQueryModifier',
341
-            array(
342
-                $post_type,
343
-                $this->_CPTs[ $post_type ],
344
-                $WP_Query,
345
-            )
346
-        );
347
-        $this->_CPT_taxonomies = $this->query_modifier->taxonomies();
348
-    }
349
-
350
-
351
-    /**
352
-     * inject_EE_shortcode_placeholder
353
-     * in order to display the M-Mode notice on our CPT routes,
354
-     * we need to first inject what looks like one of our shortcodes,
355
-     * so that it can be replaced with the actual M-Mode notice
356
-     *
357
-     * @return string
358
-     */
359
-    public function inject_EE_shortcode_placeholder()
360
-    {
361
-        return '[ESPRESSO_';
362
-    }
363
-
364
-
365
-    /**
366
-     * @deprecated
367
-     * @since  4.8.41
368
-     * @return void
369
-     */
370
-    public function _possibly_set_ee_request_var()
371
-    {
372
-        $this->query_modifier->setRequestVarsIfCpt();
373
-    }
374
-
375
-
376
-    /**
377
-     * @deprecated
378
-     * @since  4.8.41
379
-     * @param  $SQL
380
-     * @return string
381
-     */
382
-    public function posts_fields($SQL)
383
-    {
384
-        if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
385
-            return $this->query_modifier->postsFields($SQL);
386
-        }
387
-        return $SQL;
388
-    }
389
-
390
-
391
-    /**
392
-     * @deprecated
393
-     * @since  4.8.41
394
-     * @param  $SQL
395
-     * @return string
396
-     */
397
-    public function posts_join($SQL)
398
-    {
399
-        if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
400
-            return $this->query_modifier->postsJoin($SQL);
401
-        }
402
-        return $SQL;
403
-    }
404
-
405
-
406
-    /**
407
-     * @deprecated
408
-     * @since  4.8.41
409
-     * @param  \WP_Post[] $posts
410
-     * @return \WP_Post[]
411
-     */
412
-    public function the_posts($posts)
413
-    {
414
-        if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
415
-            $this->query_modifier->thePosts($posts);
416
-        }
417
-        return $posts;
418
-    }
419
-
420
-
421
-    /**
422
-     * @deprecated
423
-     * @since  4.8.41
424
-     * @param $url
425
-     * @param $ID
426
-     * @return string
427
-     */
428
-    public function get_edit_post_link($url, $ID)
429
-    {
430
-        if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
431
-            return $this->query_modifier->getEditPostLink($url, $ID);
432
-        }
433
-        return '';
434
-    }
435
-
436
-
437
-    /**
438
-     * @deprecated
439
-     * @since  4.8.41
440
-     * @param null $WP_Query
441
-     */
442
-    protected function _do_template_filters($WP_Query = null)
443
-    {
444
-        if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
445
-            $this->query_modifier->addTemplateFilters();
446
-        }
447
-    }
448
-
449
-
450
-    /**
451
-     * @deprecated
452
-     * @since  4.8.41
453
-     * @param string $current_template Existing default template path derived for this page call.
454
-     * @return string the path to the full template file.
455
-     */
456
-    public function single_cpt_template($current_template)
457
-    {
458
-        if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
459
-            return $this->query_modifier->singleCptTemplate($current_template);
460
-        }
461
-        return $current_template;
462
-    }
18
+	/**
19
+	 * @var EE_CPT_Strategy $_instance
20
+	 */
21
+	private static $_instance;
22
+
23
+	/**
24
+	 * the current page, if it utilizes CPTs
25
+	 *
26
+	 * @var array $CPT
27
+	 */
28
+	protected $CPT;
29
+
30
+	/**
31
+	 * return value from CustomPostTypeDefinitions::getDefinitions()
32
+	 *
33
+	 * @var array $_CPTs
34
+	 */
35
+	protected $_CPTs = array();
36
+
37
+	/**
38
+	 * @var array $_CPT_taxonomies
39
+	 */
40
+	protected $_CPT_taxonomies = array();
41
+
42
+	/**
43
+	 * @var array $_CPT_terms
44
+	 */
45
+	protected $_CPT_terms = array();
46
+
47
+	/**
48
+	 * @var array $_CPT_endpoints
49
+	 */
50
+	protected $_CPT_endpoints = array();
51
+
52
+	/**
53
+	 * @var EEM_Base $CPT_model
54
+	 */
55
+	protected $CPT_model;
56
+
57
+	/**
58
+	 * @var EventEspresso\Core\CPTs\CptQueryModifier $query_modifier
59
+	 */
60
+	protected $query_modifier;
61
+
62
+
63
+	/**
64
+	 * @singleton method used to instantiate class object
65
+	 * @param CustomPostTypeDefinitions|null $custom_post_types
66
+	 * @param CustomTaxonomyDefinitions|null $taxonomies
67
+	 * @return EE_CPT_Strategy
68
+	 */
69
+	public static function instance(
70
+		CustomPostTypeDefinitions $custom_post_types = null,
71
+		CustomTaxonomyDefinitions $taxonomies = null
72
+	) {
73
+		// check if class object is instantiated
74
+		if (
75
+			! self::$_instance instanceof EE_CPT_Strategy
76
+			&& $custom_post_types instanceof CustomPostTypeDefinitions
77
+			&& $taxonomies instanceof CustomTaxonomyDefinitions
78
+		) {
79
+			self::$_instance = new self($custom_post_types, $taxonomies);
80
+		}
81
+		return self::$_instance;
82
+	}
83
+
84
+
85
+	/**
86
+	 * @param CustomPostTypeDefinitions $custom_post_types
87
+	 * @param CustomTaxonomyDefinitions $taxonomies
88
+	 */
89
+	protected function __construct(
90
+		CustomPostTypeDefinitions $custom_post_types,
91
+		CustomTaxonomyDefinitions $taxonomies
92
+	) {
93
+		// get CPT data
94
+		$this->_CPTs = $custom_post_types->getDefinitions();
95
+		$this->_CPT_endpoints = $this->_set_CPT_endpoints();
96
+		$this->_CPT_taxonomies = $taxonomies->getCustomTaxonomyDefinitions();
97
+		add_action('pre_get_posts', array($this, 'pre_get_posts'), 5);
98
+	}
99
+
100
+
101
+	/**
102
+	 * @return array
103
+	 */
104
+	public function get_CPT_endpoints()
105
+	{
106
+		return $this->_CPT_endpoints;
107
+	}
108
+
109
+
110
+	/**
111
+	 * @return array
112
+	 */
113
+	public function get_CPT_taxonomies()
114
+	{
115
+		return $this->_CPT_taxonomies;
116
+	}
117
+
118
+
119
+	/**
120
+	 * add CPT "slugs" to array of default espresso "pages"
121
+	 *
122
+	 * @return array
123
+	 */
124
+	private function _set_CPT_endpoints()
125
+	{
126
+		$_CPT_endpoints = array();
127
+		if (is_array($this->_CPTs)) {
128
+			foreach ($this->_CPTs as $CPT_type => $CPT) {
129
+				if (isset($CPT['plural_slug'])) {
130
+					$_CPT_endpoints [ (string) $CPT['plural_slug'] ] = $CPT_type;
131
+				}
132
+			}
133
+		}
134
+		return $_CPT_endpoints;
135
+	}
136
+
137
+
138
+	/**
139
+	 * If this query (not just "main" queries (ie, for WP's infamous "loop")) is for an EE CPT, then we want to
140
+	 * supercharge the get_posts query to add our EE stuff (like joining to our tables, selecting extra columns, and
141
+	 * adding EE objects to the post to facilitate further querying of related data etc)
142
+	 *
143
+	 * @param WP_Query $WP_Query
144
+	 * @return void
145
+	 * @throws \EE_Error
146
+	 * @throws \InvalidArgumentException
147
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
148
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
149
+	 */
150
+	public function pre_get_posts($WP_Query)
151
+	{
152
+		// check that post-type is set
153
+		if (! $WP_Query instanceof WP_Query) {
154
+			return;
155
+		}
156
+		// add our conditionals
157
+		$this->_set_EE_tags_on_WP_Query($WP_Query);
158
+		// check for terms
159
+		$this->_set_post_type_for_terms($WP_Query);
160
+		// make sure paging is always set
161
+		$this->_set_paging($WP_Query);
162
+		// is a taxonomy set ?
163
+		$this->_set_CPT_taxonomies_on_WP_Query($WP_Query);
164
+		// loop thru post_types if set
165
+		$this->_process_WP_Query_post_types($WP_Query);
166
+	}
167
+
168
+
169
+	/**
170
+	 * @param WP_Query $WP_Query
171
+	 * @return void
172
+	 */
173
+	private function _set_EE_tags_on_WP_Query(WP_Query $WP_Query)
174
+	{
175
+		$WP_Query->is_espresso_event_single = false;
176
+		$WP_Query->is_espresso_event_archive = false;
177
+		$WP_Query->is_espresso_event_taxonomy = false;
178
+		$WP_Query->is_espresso_venue_single = false;
179
+		$WP_Query->is_espresso_venue_archive = false;
180
+		$WP_Query->is_espresso_venue_taxonomy = false;
181
+	}
182
+
183
+
184
+	/**
185
+	 * @return void
186
+	 * @throws EE_Error
187
+	 * @throws InvalidArgumentException
188
+	 * @throws InvalidDataTypeException
189
+	 * @throws InvalidInterfaceException
190
+	 */
191
+	private function _set_CPT_terms()
192
+	{
193
+		if (empty($this->_CPT_terms)) {
194
+			$terms = EEM_Term::instance()->get_all_CPT_post_tags();
195
+			foreach ($terms as $term) {
196
+				if ($term instanceof EE_Term) {
197
+					$this->_CPT_terms[ $term->slug() ] = $term;
198
+				}
199
+			}
200
+		}
201
+	}
202
+
203
+
204
+	/**
205
+	 * @param WP_Query $WP_Query
206
+	 * @return void
207
+	 * @throws EE_Error
208
+	 * @throws InvalidArgumentException
209
+	 * @throws InvalidDataTypeException
210
+	 * @throws InvalidInterfaceException
211
+	 */
212
+	private function _set_post_type_for_terms(WP_Query $WP_Query)
213
+	{
214
+		// is a tag set ?
215
+		if (isset($WP_Query->query['tag'])) {
216
+			// get term for tag
217
+			$term = EEM_Term::instance()->get_post_tag_for_event_or_venue($WP_Query->query['tag']);
218
+			// verify the term
219
+			if ($term instanceof EE_Term) {
220
+				$term->post_type = array_merge(array('post', 'page'), (array) $term->post_type);
221
+				$term->post_type = apply_filters(
222
+					'FHEE__EE_CPT_Strategy___set_post_type_for_terms__term_post_type',
223
+					$term->post_type,
224
+					$term
225
+				);
226
+				// if a post type is already set
227
+				if (isset($WP_Query->query_vars['post_type'])) {
228
+					// add to existing array
229
+					$term->post_type = array_merge((array) $WP_Query->query_vars['post_type'], $term->post_type);
230
+				}
231
+				// just set post_type to our CPT
232
+				$WP_Query->set('post_type', array_unique($term->post_type));
233
+			}
234
+		}
235
+	}
236
+
237
+
238
+	/**
239
+	 * @param WP_Query $WP_Query
240
+	 * @return void
241
+	 */
242
+	public function _set_paging($WP_Query)
243
+	{
244
+		if ($WP_Query->is_main_query() && apply_filters('FHEE__EE_CPT_Strategy___set_paging', true)) {
245
+			$page = get_query_var('page') ? get_query_var('page') : null;
246
+			$paged = get_query_var('paged') ? get_query_var('paged') : $page;
247
+			$WP_Query->set('paged', $paged);
248
+		}
249
+	}
250
+
251
+
252
+	/**
253
+	 * @param \WP_Query $WP_Query
254
+	 */
255
+	protected function _set_CPT_taxonomies_on_WP_Query(WP_Query $WP_Query)
256
+	{
257
+		// is a taxonomy set ?
258
+		if ($WP_Query->is_tax) {
259
+			// loop thru our taxonomies
260
+			foreach ($this->_CPT_taxonomies as $CPT_taxonomy => $CPT_taxonomy_details) {
261
+				// check if one of our taxonomies is set as a query var
262
+				if (isset($WP_Query->query[ $CPT_taxonomy ])) {
263
+					// but which CPT does that correspond to??? hmmm... guess we gotta go looping
264
+					foreach ($this->_CPTs as $post_type => $CPT) {
265
+						// verify our CPT has args, is public and has taxonomies set
266
+						if (
267
+							isset($CPT['args']['public'])
268
+							&& $CPT['args']['public']
269
+							&& ! empty($CPT['args']['taxonomies'])
270
+							&& in_array($CPT_taxonomy, $CPT['args']['taxonomies'], true)
271
+						) {
272
+							// if so, then add this CPT post_type to the current query's array of post_types'
273
+							$WP_Query->query_vars['post_type'] = isset($WP_Query->query_vars['post_type'])
274
+								? (array) $WP_Query->query_vars['post_type']
275
+								: array();
276
+							$WP_Query->query_vars['post_type'][] = $post_type;
277
+							switch ($post_type) {
278
+								case 'espresso_events':
279
+									$WP_Query->is_espresso_event_taxonomy = true;
280
+									break;
281
+								case 'espresso_venues':
282
+									$WP_Query->is_espresso_venue_taxonomy = true;
283
+									break;
284
+								default:
285
+									do_action(
286
+										'AHEE__EE_CPT_Strategy___set_CPT_taxonomies_on_WP_Query__for_' . $post_type . '_post_type',
287
+										$WP_Query,
288
+										$this
289
+									);
290
+							}
291
+						}
292
+					}
293
+				}
294
+			}
295
+		}
296
+	}
297
+
298
+
299
+	/**
300
+	 * @param \WP_Query $WP_Query
301
+	 * @throws InvalidArgumentException
302
+	 * @throws InvalidDataTypeException
303
+	 * @throws InvalidInterfaceException
304
+	 */
305
+	protected function _process_WP_Query_post_types(WP_Query $WP_Query)
306
+	{
307
+		if (isset($WP_Query->query_vars['post_type'])) {
308
+			// loop thru post_types as array
309
+			foreach ((array) $WP_Query->query_vars['post_type'] as $post_type) {
310
+				// is current query for an EE CPT ?
311
+				if (isset($this->_CPTs[ $post_type ])) {
312
+					// is EE on or off ?
313
+					if (EE_Maintenance_Mode::instance()->level()) {
314
+						// reroute CPT template view to maintenance_mode.template.php
315
+						if (! has_filter('template_include', array('EE_Maintenance_Mode', 'template_include'))) {
316
+							add_filter('template_include', array('EE_Maintenance_Mode', 'template_include'), 99999);
317
+						}
318
+						if (has_filter('the_content', array(EE_Maintenance_Mode::instance(), 'the_content'))) {
319
+							add_filter('the_content', array($this, 'inject_EE_shortcode_placeholder'), 1);
320
+						}
321
+						return;
322
+					}
323
+					$this->_generate_CptQueryModifier($WP_Query, $post_type);
324
+				}
325
+			}
326
+		}
327
+	}
328
+
329
+
330
+	/**
331
+	 * @param \WP_Query $WP_Query
332
+	 * @param string    $post_type
333
+	 * @throws InvalidArgumentException
334
+	 * @throws InvalidDataTypeException
335
+	 * @throws InvalidInterfaceException
336
+	 */
337
+	protected function _generate_CptQueryModifier(WP_Query $WP_Query, $post_type)
338
+	{
339
+		$this->query_modifier = LoaderFactory::getLoader()->getShared(
340
+			'EventEspresso\core\CPTs\CptQueryModifier',
341
+			array(
342
+				$post_type,
343
+				$this->_CPTs[ $post_type ],
344
+				$WP_Query,
345
+			)
346
+		);
347
+		$this->_CPT_taxonomies = $this->query_modifier->taxonomies();
348
+	}
349
+
350
+
351
+	/**
352
+	 * inject_EE_shortcode_placeholder
353
+	 * in order to display the M-Mode notice on our CPT routes,
354
+	 * we need to first inject what looks like one of our shortcodes,
355
+	 * so that it can be replaced with the actual M-Mode notice
356
+	 *
357
+	 * @return string
358
+	 */
359
+	public function inject_EE_shortcode_placeholder()
360
+	{
361
+		return '[ESPRESSO_';
362
+	}
363
+
364
+
365
+	/**
366
+	 * @deprecated
367
+	 * @since  4.8.41
368
+	 * @return void
369
+	 */
370
+	public function _possibly_set_ee_request_var()
371
+	{
372
+		$this->query_modifier->setRequestVarsIfCpt();
373
+	}
374
+
375
+
376
+	/**
377
+	 * @deprecated
378
+	 * @since  4.8.41
379
+	 * @param  $SQL
380
+	 * @return string
381
+	 */
382
+	public function posts_fields($SQL)
383
+	{
384
+		if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
385
+			return $this->query_modifier->postsFields($SQL);
386
+		}
387
+		return $SQL;
388
+	}
389
+
390
+
391
+	/**
392
+	 * @deprecated
393
+	 * @since  4.8.41
394
+	 * @param  $SQL
395
+	 * @return string
396
+	 */
397
+	public function posts_join($SQL)
398
+	{
399
+		if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
400
+			return $this->query_modifier->postsJoin($SQL);
401
+		}
402
+		return $SQL;
403
+	}
404
+
405
+
406
+	/**
407
+	 * @deprecated
408
+	 * @since  4.8.41
409
+	 * @param  \WP_Post[] $posts
410
+	 * @return \WP_Post[]
411
+	 */
412
+	public function the_posts($posts)
413
+	{
414
+		if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
415
+			$this->query_modifier->thePosts($posts);
416
+		}
417
+		return $posts;
418
+	}
419
+
420
+
421
+	/**
422
+	 * @deprecated
423
+	 * @since  4.8.41
424
+	 * @param $url
425
+	 * @param $ID
426
+	 * @return string
427
+	 */
428
+	public function get_edit_post_link($url, $ID)
429
+	{
430
+		if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
431
+			return $this->query_modifier->getEditPostLink($url, $ID);
432
+		}
433
+		return '';
434
+	}
435
+
436
+
437
+	/**
438
+	 * @deprecated
439
+	 * @since  4.8.41
440
+	 * @param null $WP_Query
441
+	 */
442
+	protected function _do_template_filters($WP_Query = null)
443
+	{
444
+		if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
445
+			$this->query_modifier->addTemplateFilters();
446
+		}
447
+	}
448
+
449
+
450
+	/**
451
+	 * @deprecated
452
+	 * @since  4.8.41
453
+	 * @param string $current_template Existing default template path derived for this page call.
454
+	 * @return string the path to the full template file.
455
+	 */
456
+	public function single_cpt_template($current_template)
457
+	{
458
+		if ($this->query_modifier instanceof EventEspresso\Core\CPTs\CptQueryModifier) {
459
+			return $this->query_modifier->singleCptTemplate($current_template);
460
+		}
461
+		return $current_template;
462
+	}
463 463
 }
Please login to merge, or discard this patch.
core/CPTs/EE_CPT_Event_Strategy.core.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -122,13 +122,13 @@  discard block
 block discarded – undo
122 122
             )
123 123
         ) {
124 124
             // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
125
-            $SQL .= ', ' . EEM_Datetime::instance()->table() . '.* ';
125
+            $SQL .= ', '.EEM_Datetime::instance()->table().'.* ';
126 126
             if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) {
127 127
                 // because we only want to retrieve the next upcoming datetime for each event:
128 128
                 // add something like:
129 129
                 // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date "
130 130
                 // to WP Query SELECT statement
131
-                $SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ';
131
+                $SQL .= ', MIN( '.EEM_Datetime::instance()->table().'.DTT_EVT_start ) as event_start_date ';
132 132
             }
133 133
         }
134 134
         return $SQL;
@@ -158,9 +158,9 @@  discard block
 block discarded – undo
158 158
             // adds something like:
159 159
             // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) "
160 160
             // to WP Query JOIN statement
161
-            $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table()
162
-                    . '.ID = ' . EEM_Datetime::instance()->table() . '.'
163
-                    . EEM_Event::instance()->primary_key_name() . ' ) ';
161
+            $SQL .= ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.EEM_Event::instance()->table()
162
+                    . '.ID = '.EEM_Datetime::instance()->table().'.'
163
+                    . EEM_Event::instance()->primary_key_name().' ) ';
164 164
         }
165 165
         return $SQL;
166 166
     }
@@ -190,8 +190,8 @@  discard block
 block discarded – undo
190 190
                 || ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events)
191 191
                 || ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events
192 192
             ) {
193
-                $SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '"
194
-                        . current_time('mysql', true) . "' ";
193
+                $SQL .= ' AND '.EEM_Datetime::instance()->table().".DTT_EVT_end > '"
194
+                        . current_time('mysql', true)."' ";
195 195
             }
196 196
         }
197 197
         return $SQL;
@@ -239,7 +239,7 @@  discard block
 block discarded – undo
239 239
             // but we want to only show each event only once
240 240
             // (whereas if we didn't group them by the post's ID, then we would end up with many repeats)
241 241
             global $wpdb;
242
-            $SQL = $wpdb->posts . '.ID ';
242
+            $SQL = $wpdb->posts.'.ID ';
243 243
         }
244 244
         return $SQL;
245 245
     }
Please login to merge, or discard this patch.
Indentation   +232 added lines, -232 removed lines patch added patch discarded remove patch
@@ -12,258 +12,258 @@
 block discarded – undo
12 12
  */
13 13
 class EE_CPT_Event_Strategy
14 14
 {
15
-    /**
16
-     * the current page, if it utilizes CPTs
17
-     *
18
-     * @var object $CPT
19
-     */
20
-    protected $CPT;
15
+	/**
16
+	 * the current page, if it utilizes CPTs
17
+	 *
18
+	 * @var object $CPT
19
+	 */
20
+	protected $CPT;
21 21
 
22 22
 
23
-    /**
24
-     * @param WP_Query $wp_query
25
-     * @param array    $CPT
26
-     */
27
-    public function __construct($wp_query, $CPT = array())
28
-    {
29
-        if ($wp_query instanceof WP_Query) {
30
-            $WP_Query = $wp_query;
31
-            $this->CPT = $CPT;
32
-        } else {
33
-            $WP_Query = isset($wp_query['WP_Query']) ? $wp_query['WP_Query'] : null;
34
-            $this->CPT = isset($wp_query['CPT']) ? $wp_query['CPT'] : null;
35
-        }
36
-        // !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
37
-        // here's the list of available filters in the WP_Query object
38
-        // 'posts_where'
39
-        // 'posts_where_paged'
40
-        // 'posts_groupby'
41
-        // 'posts_join_paged'
42
-        // 'posts_orderby'
43
-        // 'posts_distinct'
44
-        // 'post_limits'
45
-        // 'posts_fields'
46
-        // 'posts_join'
47
-        $this->_add_filters();
48
-        if ($WP_Query instanceof WP_Query) {
49
-            $WP_Query->is_espresso_event_single = is_singular()
50
-                                                  && isset($WP_Query->query->post_type)
51
-                                                  && $WP_Query->query->post_type === 'espresso_events';
52
-            $WP_Query->is_espresso_event_archive = is_post_type_archive('espresso_events');
53
-            $WP_Query->is_espresso_event_taxonomy = is_tax('espresso_event_categories');
54
-        }
55
-    }
23
+	/**
24
+	 * @param WP_Query $wp_query
25
+	 * @param array    $CPT
26
+	 */
27
+	public function __construct($wp_query, $CPT = array())
28
+	{
29
+		if ($wp_query instanceof WP_Query) {
30
+			$WP_Query = $wp_query;
31
+			$this->CPT = $CPT;
32
+		} else {
33
+			$WP_Query = isset($wp_query['WP_Query']) ? $wp_query['WP_Query'] : null;
34
+			$this->CPT = isset($wp_query['CPT']) ? $wp_query['CPT'] : null;
35
+		}
36
+		// !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
37
+		// here's the list of available filters in the WP_Query object
38
+		// 'posts_where'
39
+		// 'posts_where_paged'
40
+		// 'posts_groupby'
41
+		// 'posts_join_paged'
42
+		// 'posts_orderby'
43
+		// 'posts_distinct'
44
+		// 'post_limits'
45
+		// 'posts_fields'
46
+		// 'posts_join'
47
+		$this->_add_filters();
48
+		if ($WP_Query instanceof WP_Query) {
49
+			$WP_Query->is_espresso_event_single = is_singular()
50
+												  && isset($WP_Query->query->post_type)
51
+												  && $WP_Query->query->post_type === 'espresso_events';
52
+			$WP_Query->is_espresso_event_archive = is_post_type_archive('espresso_events');
53
+			$WP_Query->is_espresso_event_taxonomy = is_tax('espresso_event_categories');
54
+		}
55
+	}
56 56
 
57 57
 
58
-    /**
59
-     * When an instance of this class is created, we add our filters
60
-     * (which will get removed in case the next call to get_posts ISN'T
61
-     * for event CPTs)
62
-     */
63
-    protected function _add_filters()
64
-    {
65
-        add_filter('posts_fields', array($this, 'posts_fields'), 1, 2);
66
-        add_filter('posts_join', array($this, 'posts_join'), 1, 2);
67
-        add_filter('posts_where', array($this, 'posts_where'), 10, 2);
68
-        // add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 );
69
-        add_filter('posts_orderby', array($this, 'posts_orderby'), 1, 2);
70
-        add_filter('posts_groupby', array($this, 'posts_groupby'), 1, 2);
71
-        add_action('posts_selection', array($this, 'remove_filters'));
72
-    }
58
+	/**
59
+	 * When an instance of this class is created, we add our filters
60
+	 * (which will get removed in case the next call to get_posts ISN'T
61
+	 * for event CPTs)
62
+	 */
63
+	protected function _add_filters()
64
+	{
65
+		add_filter('posts_fields', array($this, 'posts_fields'), 1, 2);
66
+		add_filter('posts_join', array($this, 'posts_join'), 1, 2);
67
+		add_filter('posts_where', array($this, 'posts_where'), 10, 2);
68
+		// add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 );
69
+		add_filter('posts_orderby', array($this, 'posts_orderby'), 1, 2);
70
+		add_filter('posts_groupby', array($this, 'posts_groupby'), 1, 2);
71
+		add_action('posts_selection', array($this, 'remove_filters'));
72
+	}
73 73
 
74 74
 
75
-    /**
76
-     * public access to _remove_filters()
77
-     *
78
-     * @since 4.9.63.p
79
-     */
80
-    public function remove_filters()
81
-    {
82
-        $this->_remove_filters();
83
-    }
75
+	/**
76
+	 * public access to _remove_filters()
77
+	 *
78
+	 * @since 4.9.63.p
79
+	 */
80
+	public function remove_filters()
81
+	{
82
+		$this->_remove_filters();
83
+	}
84 84
 
85 85
 
86
-    /**
87
-     * Should eb called when the last filter or hook is fired for this CPT strategy.
88
-     * This is to avoid applying this CPT strategy for other posts or CPTs (eg,
89
-     * we don't want to join to the datetime table when querying for venues, do we!?)
90
-     */
91
-    protected function _remove_filters()
92
-    {
93
-        remove_filter('posts_fields', array($this, 'posts_fields'), 1);
94
-        remove_filter('posts_join', array($this, 'posts_join'), 1);
95
-        remove_filter('posts_where', array($this, 'posts_where'), 10);
96
-        // remove_filter( 'the_posts', array( $this, 'the_posts' ), 1 );
97
-        remove_filter('posts_orderby', array($this, 'posts_orderby'), 1);
98
-        remove_filter('posts_groupby', array($this, 'posts_groupby'), 1);
99
-        remove_action('posts_selection', array($this, 'remove_filters'));
100
-    }
86
+	/**
87
+	 * Should eb called when the last filter or hook is fired for this CPT strategy.
88
+	 * This is to avoid applying this CPT strategy for other posts or CPTs (eg,
89
+	 * we don't want to join to the datetime table when querying for venues, do we!?)
90
+	 */
91
+	protected function _remove_filters()
92
+	{
93
+		remove_filter('posts_fields', array($this, 'posts_fields'), 1);
94
+		remove_filter('posts_join', array($this, 'posts_join'), 1);
95
+		remove_filter('posts_where', array($this, 'posts_where'), 10);
96
+		// remove_filter( 'the_posts', array( $this, 'the_posts' ), 1 );
97
+		remove_filter('posts_orderby', array($this, 'posts_orderby'), 1);
98
+		remove_filter('posts_groupby', array($this, 'posts_groupby'), 1);
99
+		remove_action('posts_selection', array($this, 'remove_filters'));
100
+	}
101 101
 
102 102
 
103
-    /**
104
-     * @param string   $SQL
105
-     * @param WP_Query $wp_query
106
-     * @return    string
107
-     * @throws EE_Error
108
-     * @throws InvalidArgumentException
109
-     * @throws InvalidDataTypeException
110
-     * @throws InvalidInterfaceException
111
-     */
112
-    public function posts_fields($SQL, WP_Query $wp_query)
113
-    {
114
-        if (
115
-            $wp_query instanceof WP_Query
116
-            &&
117
-            (
118
-                $wp_query->is_espresso_event_single
119
-                || $wp_query->is_espresso_event_archive
120
-                || $wp_query->is_espresso_event_taxonomy
121
-            )
122
-        ) {
123
-            // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
124
-            $SQL .= ', ' . EEM_Datetime::instance()->table() . '.* ';
125
-            if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) {
126
-                // because we only want to retrieve the next upcoming datetime for each event:
127
-                // add something like:
128
-                // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date "
129
-                // to WP Query SELECT statement
130
-                $SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ';
131
-            }
132
-        }
133
-        return $SQL;
134
-    }
103
+	/**
104
+	 * @param string   $SQL
105
+	 * @param WP_Query $wp_query
106
+	 * @return    string
107
+	 * @throws EE_Error
108
+	 * @throws InvalidArgumentException
109
+	 * @throws InvalidDataTypeException
110
+	 * @throws InvalidInterfaceException
111
+	 */
112
+	public function posts_fields($SQL, WP_Query $wp_query)
113
+	{
114
+		if (
115
+			$wp_query instanceof WP_Query
116
+			&&
117
+			(
118
+				$wp_query->is_espresso_event_single
119
+				|| $wp_query->is_espresso_event_archive
120
+				|| $wp_query->is_espresso_event_taxonomy
121
+			)
122
+		) {
123
+			// adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
124
+			$SQL .= ', ' . EEM_Datetime::instance()->table() . '.* ';
125
+			if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) {
126
+				// because we only want to retrieve the next upcoming datetime for each event:
127
+				// add something like:
128
+				// ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date "
129
+				// to WP Query SELECT statement
130
+				$SQL .= ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date ';
131
+			}
132
+		}
133
+		return $SQL;
134
+	}
135 135
 
136 136
 
137
-    /**
138
-     * @param string   $SQL
139
-     * @param WP_Query $wp_query
140
-     * @return string
141
-     * @throws EE_Error
142
-     * @throws InvalidArgumentException
143
-     * @throws InvalidDataTypeException
144
-     * @throws InvalidInterfaceException
145
-     */
146
-    public function posts_join($SQL, WP_Query $wp_query)
147
-    {
148
-        if (
149
-            $wp_query instanceof WP_Query
150
-            &&
151
-            (
152
-                $wp_query->is_espresso_event_single
153
-                || $wp_query->is_espresso_event_archive
154
-                || $wp_query->is_espresso_event_taxonomy
155
-            )
156
-        ) {
157
-            // adds something like:
158
-            // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) "
159
-            // to WP Query JOIN statement
160
-            $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table()
161
-                    . '.ID = ' . EEM_Datetime::instance()->table() . '.'
162
-                    . EEM_Event::instance()->primary_key_name() . ' ) ';
163
-        }
164
-        return $SQL;
165
-    }
137
+	/**
138
+	 * @param string   $SQL
139
+	 * @param WP_Query $wp_query
140
+	 * @return string
141
+	 * @throws EE_Error
142
+	 * @throws InvalidArgumentException
143
+	 * @throws InvalidDataTypeException
144
+	 * @throws InvalidInterfaceException
145
+	 */
146
+	public function posts_join($SQL, WP_Query $wp_query)
147
+	{
148
+		if (
149
+			$wp_query instanceof WP_Query
150
+			&&
151
+			(
152
+				$wp_query->is_espresso_event_single
153
+				|| $wp_query->is_espresso_event_archive
154
+				|| $wp_query->is_espresso_event_taxonomy
155
+			)
156
+		) {
157
+			// adds something like:
158
+			// " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) "
159
+			// to WP Query JOIN statement
160
+			$SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . EEM_Event::instance()->table()
161
+					. '.ID = ' . EEM_Datetime::instance()->table() . '.'
162
+					. EEM_Event::instance()->primary_key_name() . ' ) ';
163
+		}
164
+		return $SQL;
165
+	}
166 166
 
167 167
 
168
-    /**
169
-     * @param string   $SQL
170
-     * @param WP_Query $wp_query
171
-     * @return string
172
-     * @throws EE_Error
173
-     * @throws InvalidArgumentException
174
-     * @throws InvalidDataTypeException
175
-     * @throws InvalidInterfaceException
176
-     */
177
-    public function posts_where($SQL, WP_Query $wp_query)
178
-    {
179
-        if (
180
-            $wp_query instanceof WP_Query
181
-            &&
182
-            (
183
-                $wp_query->is_espresso_event_archive
184
-                || $wp_query->is_espresso_event_taxonomy
185
-            )
186
-        ) {
187
-            if (
188
-                ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive)
189
-                || ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events)
190
-                || ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events
191
-            ) {
192
-                $SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '"
193
-                        . current_time('mysql', true) . "' ";
194
-            }
195
-        }
196
-        return $SQL;
197
-    }
168
+	/**
169
+	 * @param string   $SQL
170
+	 * @param WP_Query $wp_query
171
+	 * @return string
172
+	 * @throws EE_Error
173
+	 * @throws InvalidArgumentException
174
+	 * @throws InvalidDataTypeException
175
+	 * @throws InvalidInterfaceException
176
+	 */
177
+	public function posts_where($SQL, WP_Query $wp_query)
178
+	{
179
+		if (
180
+			$wp_query instanceof WP_Query
181
+			&&
182
+			(
183
+				$wp_query->is_espresso_event_archive
184
+				|| $wp_query->is_espresso_event_taxonomy
185
+			)
186
+		) {
187
+			if (
188
+				! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive)
189
+				|| ! isset(EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events)
190
+				|| ! EE_Registry::instance()->CFG->template_settings->EED_Events_Archive->display_expired_events
191
+			) {
192
+				$SQL .= ' AND ' . EEM_Datetime::instance()->table() . ".DTT_EVT_end > '"
193
+						. current_time('mysql', true) . "' ";
194
+			}
195
+		}
196
+		return $SQL;
197
+	}
198 198
 
199 199
 
200
-    /**
201
-     * @param string   $SQL
202
-     * @param WP_Query $wp_query
203
-     * @return string
204
-     */
205
-    public function posts_orderby($SQL, WP_Query $wp_query)
206
-    {
207
-        if (
208
-            $wp_query instanceof WP_Query
209
-            &&
210
-            (
211
-                $wp_query->is_espresso_event_archive
212
-                || $wp_query->is_espresso_event_taxonomy
213
-            )
214
-        ) {
215
-            $SQL = ' event_start_date ASC ';
216
-        }
217
-        return $SQL;
218
-    }
200
+	/**
201
+	 * @param string   $SQL
202
+	 * @param WP_Query $wp_query
203
+	 * @return string
204
+	 */
205
+	public function posts_orderby($SQL, WP_Query $wp_query)
206
+	{
207
+		if (
208
+			$wp_query instanceof WP_Query
209
+			&&
210
+			(
211
+				$wp_query->is_espresso_event_archive
212
+				|| $wp_query->is_espresso_event_taxonomy
213
+			)
214
+		) {
215
+			$SQL = ' event_start_date ASC ';
216
+		}
217
+		return $SQL;
218
+	}
219 219
 
220 220
 
221
-    /**
222
-     * @param string   $SQL
223
-     * @param WP_Query $wp_query
224
-     * @return string
225
-     */
226
-    public function posts_groupby($SQL, WP_Query $wp_query)
227
-    {
228
-        if (
229
-            $wp_query instanceof WP_Query
230
-            &&
231
-            (
232
-                $wp_query->is_espresso_event_archive
233
-                || $wp_query->is_espresso_event_taxonomy
234
-            )
235
-        ) {
236
-            // TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default)
237
-            // we're joining to the datetimes table, where there can be MANY datetimes for a single event,
238
-            // but we want to only show each event only once
239
-            // (whereas if we didn't group them by the post's ID, then we would end up with many repeats)
240
-            global $wpdb;
241
-            $SQL = $wpdb->posts . '.ID ';
242
-        }
243
-        return $SQL;
244
-    }
221
+	/**
222
+	 * @param string   $SQL
223
+	 * @param WP_Query $wp_query
224
+	 * @return string
225
+	 */
226
+	public function posts_groupby($SQL, WP_Query $wp_query)
227
+	{
228
+		if (
229
+			$wp_query instanceof WP_Query
230
+			&&
231
+			(
232
+				$wp_query->is_espresso_event_archive
233
+				|| $wp_query->is_espresso_event_taxonomy
234
+			)
235
+		) {
236
+			// TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default)
237
+			// we're joining to the datetimes table, where there can be MANY datetimes for a single event,
238
+			// but we want to only show each event only once
239
+			// (whereas if we didn't group them by the post's ID, then we would end up with many repeats)
240
+			global $wpdb;
241
+			$SQL = $wpdb->posts . '.ID ';
242
+		}
243
+		return $SQL;
244
+	}
245 245
 
246 246
 
247
-    /**
248
-     * @param array    $posts
249
-     * @param WP_Query $wp_query
250
-     * @return array
251
-     */
252
-    public function the_posts($posts, WP_Query $wp_query)
253
-    {
254
-        return $posts;
255
-    }
247
+	/**
248
+	 * @param array    $posts
249
+	 * @param WP_Query $wp_query
250
+	 * @return array
251
+	 */
252
+	public function the_posts($posts, WP_Query $wp_query)
253
+	{
254
+		return $posts;
255
+	}
256 256
 
257 257
 
258
-    /**
259
-     * @param null $meta_value
260
-     * @param      $post_id
261
-     * @param      $meta_key
262
-     * @param      $single
263
-     * @return    string
264
-     */
265
-    public function get_EE_post_type_metadata($meta_value = null, $post_id, $meta_key, $single)
266
-    {
267
-        return $meta_value;
268
-    }
258
+	/**
259
+	 * @param null $meta_value
260
+	 * @param      $post_id
261
+	 * @param      $meta_key
262
+	 * @param      $single
263
+	 * @return    string
264
+	 */
265
+	public function get_EE_post_type_metadata($meta_value = null, $post_id, $meta_key, $single)
266
+	{
267
+		return $meta_value;
268
+	}
269 269
 }
Please login to merge, or discard this patch.