@@ -13,203 +13,203 @@ |
||
13 | 13 | { |
14 | 14 | |
15 | 15 | |
16 | - /** |
|
17 | - * This method basically works the same as the PHP core function array_diff except it allows you to compare arrays |
|
18 | - * of EE_Base_Class objects NOTE: This will ONLY work on an array of EE_Base_Class objects |
|
19 | - * |
|
20 | - * @uses array_udiff core php function for setting up our own array comparison |
|
21 | - * @uses self::_compare_objects as the custom method for array_udiff |
|
22 | - * @param array $array1 an array of objects |
|
23 | - * @param array $array2 an array of objects |
|
24 | - * @return array an array of objects found in array 1 that aren't found in array 2. |
|
25 | - */ |
|
26 | - public static function object_array_diff($array1, $array2) |
|
27 | - { |
|
28 | - return array_udiff($array1, $array2, array('self', '_compare_objects')); |
|
29 | - } |
|
30 | - |
|
31 | - /** |
|
32 | - * Given that $arr is an array, determines if it's associative or numerically AND sequentially indexed |
|
33 | - * |
|
34 | - * @param array $array |
|
35 | - * @return boolean |
|
36 | - */ |
|
37 | - public static function is_associative_array(array $array) |
|
38 | - { |
|
39 | - return array_keys($array) !== range(0, count($array) - 1); |
|
40 | - } |
|
41 | - |
|
42 | - /** |
|
43 | - * Gets an item from the array and leave the array intact. Use in place of end() |
|
44 | - * when you don't want to change the array |
|
45 | - * |
|
46 | - * @param array $arr |
|
47 | - * @return mixed what ever is in the array |
|
48 | - */ |
|
49 | - public static function get_one_item_from_array($arr) |
|
50 | - { |
|
51 | - $item = end($arr); |
|
52 | - reset($arr); |
|
53 | - return $item; |
|
54 | - } |
|
55 | - |
|
56 | - /** |
|
57 | - * Detects if this is a multi-dimensional array (meaning that the top-level |
|
58 | - * values are themselves array. Eg array(array(...),...) |
|
59 | - * |
|
60 | - * @param mixed $arr |
|
61 | - * @return boolean |
|
62 | - */ |
|
63 | - public static function is_multi_dimensional_array($arr) |
|
64 | - { |
|
65 | - if (is_array($arr)) { |
|
66 | - $first_item = reset($arr); |
|
67 | - if (is_array($first_item)) { |
|
68 | - return true;// yep, there's at least 2 levels to this array |
|
69 | - } else { |
|
70 | - return false;// nope, only 1 level |
|
71 | - } |
|
72 | - } else { |
|
73 | - return false;// its not an array at all! |
|
74 | - } |
|
75 | - } |
|
76 | - |
|
77 | - /** |
|
78 | - * Shorthand for isset( $arr[ $index ] ) ? $arr[ $index ] : $default |
|
79 | - * |
|
80 | - * @param array $arr |
|
81 | - * @param mixed $index |
|
82 | - * @param mixed $default |
|
83 | - * @return mixed |
|
84 | - */ |
|
85 | - public static function is_set($arr, $index, $default) |
|
86 | - { |
|
87 | - return isset($arr[ $index ]) ? $arr[ $index ] : $default; |
|
88 | - } |
|
89 | - |
|
90 | - /** |
|
91 | - * Exactly like `maybe_unserialize`, but also accounts for a WP bug: http://core.trac.wordpress.org/ticket/26118 |
|
92 | - * |
|
93 | - * @param mixed $value usually a string, but could be an array or object |
|
94 | - * @return mixed the UN-serialized data |
|
95 | - */ |
|
96 | - public static function maybe_unserialize($value) |
|
97 | - { |
|
98 | - $data = maybe_unserialize($value); |
|
99 | - // it's possible that this still has serialized data if its the session. WP has a bug, http://core.trac.wordpress.org/ticket/26118 that doesnt' unserialize this automatically. |
|
100 | - $token = 'C'; |
|
101 | - $data = is_string($data) ? trim($data) : $data; |
|
102 | - if (is_string($data) && strlen($data) > 1 && $data[0] == $token && preg_match("/^{$token}:[0-9]+:/s", $data)) { |
|
103 | - return unserialize($data); |
|
104 | - } else { |
|
105 | - return $data; |
|
106 | - } |
|
107 | - } |
|
108 | - |
|
109 | - |
|
110 | - /** |
|
111 | - * insert_into_array |
|
112 | - * |
|
113 | - * @param array $target_array the array to insert new data into |
|
114 | - * @param array $array_to_insert the new data to be inserted |
|
115 | - * @param int | string $offset a known key within $target_array where new data will be inserted |
|
116 | - * @param bool $add_before whether to add new data before or after the offset key |
|
117 | - * @param bool $preserve_keys whether or not to reset numerically indexed arrays |
|
118 | - * @return array |
|
119 | - */ |
|
120 | - public static function insert_into_array( |
|
121 | - $target_array = array(), |
|
122 | - $array_to_insert = array(), |
|
123 | - $offset = null, |
|
124 | - $add_before = true, |
|
125 | - $preserve_keys = true |
|
126 | - ) { |
|
127 | - // ensure incoming arrays are actually arrays |
|
128 | - $target_array = (array) $target_array; |
|
129 | - $array_to_insert = (array) $array_to_insert; |
|
130 | - // if no offset key was supplied |
|
131 | - if (empty($offset)) { |
|
132 | - // use start or end of $target_array based on whether we are adding before or not |
|
133 | - $offset = $add_before ? 0 : count($target_array); |
|
134 | - } |
|
135 | - // if offset key is a string, then find the corresponding numeric location for that element |
|
136 | - $offset = is_int($offset) ? $offset : array_search($offset, array_keys($target_array)); |
|
137 | - // add one to the offset if adding after |
|
138 | - $offset = $add_before ? $offset : $offset + 1; |
|
139 | - // but ensure offset does not exceed the length of the array |
|
140 | - $offset = $offset > count($target_array) ? count($target_array) : $offset; |
|
141 | - // reindex array ??? |
|
142 | - if ($preserve_keys) { |
|
143 | - // take a slice of the target array from the beginning till the offset, |
|
144 | - // then add the new data |
|
145 | - // then add another slice that starts at the offset and goes till the end |
|
146 | - return array_slice($target_array, 0, $offset, true) + $array_to_insert + array_slice( |
|
147 | - $target_array, |
|
148 | - $offset, |
|
149 | - null, |
|
150 | - true |
|
151 | - ); |
|
152 | - } else { |
|
153 | - // since we don't want to preserve keys, we can use array_splice |
|
154 | - array_splice($target_array, $offset, 0, $array_to_insert); |
|
155 | - return $target_array; |
|
156 | - } |
|
157 | - } |
|
158 | - |
|
159 | - |
|
160 | - /** |
|
161 | - * array_merge() is slow and should never be used while looping over data |
|
162 | - * if you don't need to preserve keys from all arrays, then using a foreach loop is much faster |
|
163 | - * so really this acts more like array_replace( $array1, $array2 ) |
|
164 | - * or a union with the arrays flipped ( $array2 + $array1 ) |
|
165 | - * this saves a few lines of code and improves readability |
|
166 | - * |
|
167 | - * @param array $array1 |
|
168 | - * @param array $array2 |
|
169 | - * @return array |
|
170 | - */ |
|
171 | - public static function merge_arrays_and_overwrite_keys(array $array1, array $array2) |
|
172 | - { |
|
173 | - foreach ($array2 as $key => $value) { |
|
174 | - $array1[ $key ] = $value; |
|
175 | - } |
|
176 | - return $array1; |
|
177 | - } |
|
178 | - |
|
179 | - |
|
180 | - /** |
|
181 | - * given a flat array like $array = array('A', 'B', 'C') |
|
182 | - * will convert into a multidimensional array like $array[A][B][C] |
|
183 | - * if $final_value is provided and is anything other than null, |
|
184 | - * then that will be set as the value for the innermost array key |
|
185 | - * like so: $array[A][B][C] = $final_value |
|
186 | - * |
|
187 | - * @param array $flat_array |
|
188 | - * @param mixed $final_value |
|
189 | - * @return array |
|
190 | - */ |
|
191 | - public static function convert_array_values_to_keys(array $flat_array, $final_value = null) |
|
192 | - { |
|
193 | - $multidimensional = array(); |
|
194 | - $reference = &$multidimensional; |
|
195 | - foreach ($flat_array as $key) { |
|
196 | - $reference[ $key ] = array(); |
|
197 | - $reference = &$reference[ $key ]; |
|
198 | - } |
|
199 | - if ($final_value !== null) { |
|
200 | - $reference = $final_value; |
|
201 | - } |
|
202 | - return $multidimensional; |
|
203 | - } |
|
204 | - |
|
205 | - |
|
206 | - /** |
|
207 | - * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential |
|
208 | - * @param array $array |
|
209 | - * @return bool |
|
210 | - */ |
|
211 | - public static function is_array_numerically_and_sequentially_indexed(array $array) |
|
212 | - { |
|
213 | - return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true; |
|
214 | - } |
|
16 | + /** |
|
17 | + * This method basically works the same as the PHP core function array_diff except it allows you to compare arrays |
|
18 | + * of EE_Base_Class objects NOTE: This will ONLY work on an array of EE_Base_Class objects |
|
19 | + * |
|
20 | + * @uses array_udiff core php function for setting up our own array comparison |
|
21 | + * @uses self::_compare_objects as the custom method for array_udiff |
|
22 | + * @param array $array1 an array of objects |
|
23 | + * @param array $array2 an array of objects |
|
24 | + * @return array an array of objects found in array 1 that aren't found in array 2. |
|
25 | + */ |
|
26 | + public static function object_array_diff($array1, $array2) |
|
27 | + { |
|
28 | + return array_udiff($array1, $array2, array('self', '_compare_objects')); |
|
29 | + } |
|
30 | + |
|
31 | + /** |
|
32 | + * Given that $arr is an array, determines if it's associative or numerically AND sequentially indexed |
|
33 | + * |
|
34 | + * @param array $array |
|
35 | + * @return boolean |
|
36 | + */ |
|
37 | + public static function is_associative_array(array $array) |
|
38 | + { |
|
39 | + return array_keys($array) !== range(0, count($array) - 1); |
|
40 | + } |
|
41 | + |
|
42 | + /** |
|
43 | + * Gets an item from the array and leave the array intact. Use in place of end() |
|
44 | + * when you don't want to change the array |
|
45 | + * |
|
46 | + * @param array $arr |
|
47 | + * @return mixed what ever is in the array |
|
48 | + */ |
|
49 | + public static function get_one_item_from_array($arr) |
|
50 | + { |
|
51 | + $item = end($arr); |
|
52 | + reset($arr); |
|
53 | + return $item; |
|
54 | + } |
|
55 | + |
|
56 | + /** |
|
57 | + * Detects if this is a multi-dimensional array (meaning that the top-level |
|
58 | + * values are themselves array. Eg array(array(...),...) |
|
59 | + * |
|
60 | + * @param mixed $arr |
|
61 | + * @return boolean |
|
62 | + */ |
|
63 | + public static function is_multi_dimensional_array($arr) |
|
64 | + { |
|
65 | + if (is_array($arr)) { |
|
66 | + $first_item = reset($arr); |
|
67 | + if (is_array($first_item)) { |
|
68 | + return true;// yep, there's at least 2 levels to this array |
|
69 | + } else { |
|
70 | + return false;// nope, only 1 level |
|
71 | + } |
|
72 | + } else { |
|
73 | + return false;// its not an array at all! |
|
74 | + } |
|
75 | + } |
|
76 | + |
|
77 | + /** |
|
78 | + * Shorthand for isset( $arr[ $index ] ) ? $arr[ $index ] : $default |
|
79 | + * |
|
80 | + * @param array $arr |
|
81 | + * @param mixed $index |
|
82 | + * @param mixed $default |
|
83 | + * @return mixed |
|
84 | + */ |
|
85 | + public static function is_set($arr, $index, $default) |
|
86 | + { |
|
87 | + return isset($arr[ $index ]) ? $arr[ $index ] : $default; |
|
88 | + } |
|
89 | + |
|
90 | + /** |
|
91 | + * Exactly like `maybe_unserialize`, but also accounts for a WP bug: http://core.trac.wordpress.org/ticket/26118 |
|
92 | + * |
|
93 | + * @param mixed $value usually a string, but could be an array or object |
|
94 | + * @return mixed the UN-serialized data |
|
95 | + */ |
|
96 | + public static function maybe_unserialize($value) |
|
97 | + { |
|
98 | + $data = maybe_unserialize($value); |
|
99 | + // it's possible that this still has serialized data if its the session. WP has a bug, http://core.trac.wordpress.org/ticket/26118 that doesnt' unserialize this automatically. |
|
100 | + $token = 'C'; |
|
101 | + $data = is_string($data) ? trim($data) : $data; |
|
102 | + if (is_string($data) && strlen($data) > 1 && $data[0] == $token && preg_match("/^{$token}:[0-9]+:/s", $data)) { |
|
103 | + return unserialize($data); |
|
104 | + } else { |
|
105 | + return $data; |
|
106 | + } |
|
107 | + } |
|
108 | + |
|
109 | + |
|
110 | + /** |
|
111 | + * insert_into_array |
|
112 | + * |
|
113 | + * @param array $target_array the array to insert new data into |
|
114 | + * @param array $array_to_insert the new data to be inserted |
|
115 | + * @param int | string $offset a known key within $target_array where new data will be inserted |
|
116 | + * @param bool $add_before whether to add new data before or after the offset key |
|
117 | + * @param bool $preserve_keys whether or not to reset numerically indexed arrays |
|
118 | + * @return array |
|
119 | + */ |
|
120 | + public static function insert_into_array( |
|
121 | + $target_array = array(), |
|
122 | + $array_to_insert = array(), |
|
123 | + $offset = null, |
|
124 | + $add_before = true, |
|
125 | + $preserve_keys = true |
|
126 | + ) { |
|
127 | + // ensure incoming arrays are actually arrays |
|
128 | + $target_array = (array) $target_array; |
|
129 | + $array_to_insert = (array) $array_to_insert; |
|
130 | + // if no offset key was supplied |
|
131 | + if (empty($offset)) { |
|
132 | + // use start or end of $target_array based on whether we are adding before or not |
|
133 | + $offset = $add_before ? 0 : count($target_array); |
|
134 | + } |
|
135 | + // if offset key is a string, then find the corresponding numeric location for that element |
|
136 | + $offset = is_int($offset) ? $offset : array_search($offset, array_keys($target_array)); |
|
137 | + // add one to the offset if adding after |
|
138 | + $offset = $add_before ? $offset : $offset + 1; |
|
139 | + // but ensure offset does not exceed the length of the array |
|
140 | + $offset = $offset > count($target_array) ? count($target_array) : $offset; |
|
141 | + // reindex array ??? |
|
142 | + if ($preserve_keys) { |
|
143 | + // take a slice of the target array from the beginning till the offset, |
|
144 | + // then add the new data |
|
145 | + // then add another slice that starts at the offset and goes till the end |
|
146 | + return array_slice($target_array, 0, $offset, true) + $array_to_insert + array_slice( |
|
147 | + $target_array, |
|
148 | + $offset, |
|
149 | + null, |
|
150 | + true |
|
151 | + ); |
|
152 | + } else { |
|
153 | + // since we don't want to preserve keys, we can use array_splice |
|
154 | + array_splice($target_array, $offset, 0, $array_to_insert); |
|
155 | + return $target_array; |
|
156 | + } |
|
157 | + } |
|
158 | + |
|
159 | + |
|
160 | + /** |
|
161 | + * array_merge() is slow and should never be used while looping over data |
|
162 | + * if you don't need to preserve keys from all arrays, then using a foreach loop is much faster |
|
163 | + * so really this acts more like array_replace( $array1, $array2 ) |
|
164 | + * or a union with the arrays flipped ( $array2 + $array1 ) |
|
165 | + * this saves a few lines of code and improves readability |
|
166 | + * |
|
167 | + * @param array $array1 |
|
168 | + * @param array $array2 |
|
169 | + * @return array |
|
170 | + */ |
|
171 | + public static function merge_arrays_and_overwrite_keys(array $array1, array $array2) |
|
172 | + { |
|
173 | + foreach ($array2 as $key => $value) { |
|
174 | + $array1[ $key ] = $value; |
|
175 | + } |
|
176 | + return $array1; |
|
177 | + } |
|
178 | + |
|
179 | + |
|
180 | + /** |
|
181 | + * given a flat array like $array = array('A', 'B', 'C') |
|
182 | + * will convert into a multidimensional array like $array[A][B][C] |
|
183 | + * if $final_value is provided and is anything other than null, |
|
184 | + * then that will be set as the value for the innermost array key |
|
185 | + * like so: $array[A][B][C] = $final_value |
|
186 | + * |
|
187 | + * @param array $flat_array |
|
188 | + * @param mixed $final_value |
|
189 | + * @return array |
|
190 | + */ |
|
191 | + public static function convert_array_values_to_keys(array $flat_array, $final_value = null) |
|
192 | + { |
|
193 | + $multidimensional = array(); |
|
194 | + $reference = &$multidimensional; |
|
195 | + foreach ($flat_array as $key) { |
|
196 | + $reference[ $key ] = array(); |
|
197 | + $reference = &$reference[ $key ]; |
|
198 | + } |
|
199 | + if ($final_value !== null) { |
|
200 | + $reference = $final_value; |
|
201 | + } |
|
202 | + return $multidimensional; |
|
203 | + } |
|
204 | + |
|
205 | + |
|
206 | + /** |
|
207 | + * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential |
|
208 | + * @param array $array |
|
209 | + * @return bool |
|
210 | + */ |
|
211 | + public static function is_array_numerically_and_sequentially_indexed(array $array) |
|
212 | + { |
|
213 | + return ! empty($array) ? array_keys($array) === range(0, count($array) - 1) : true; |
|
214 | + } |
|
215 | 215 | } |
@@ -65,12 +65,12 @@ discard block |
||
65 | 65 | if (is_array($arr)) { |
66 | 66 | $first_item = reset($arr); |
67 | 67 | if (is_array($first_item)) { |
68 | - return true;// yep, there's at least 2 levels to this array |
|
68 | + return true; // yep, there's at least 2 levels to this array |
|
69 | 69 | } else { |
70 | - return false;// nope, only 1 level |
|
70 | + return false; // nope, only 1 level |
|
71 | 71 | } |
72 | 72 | } else { |
73 | - return false;// its not an array at all! |
|
73 | + return false; // its not an array at all! |
|
74 | 74 | } |
75 | 75 | } |
76 | 76 | |
@@ -84,7 +84,7 @@ discard block |
||
84 | 84 | */ |
85 | 85 | public static function is_set($arr, $index, $default) |
86 | 86 | { |
87 | - return isset($arr[ $index ]) ? $arr[ $index ] : $default; |
|
87 | + return isset($arr[$index]) ? $arr[$index] : $default; |
|
88 | 88 | } |
89 | 89 | |
90 | 90 | /** |
@@ -171,7 +171,7 @@ discard block |
||
171 | 171 | public static function merge_arrays_and_overwrite_keys(array $array1, array $array2) |
172 | 172 | { |
173 | 173 | foreach ($array2 as $key => $value) { |
174 | - $array1[ $key ] = $value; |
|
174 | + $array1[$key] = $value; |
|
175 | 175 | } |
176 | 176 | return $array1; |
177 | 177 | } |
@@ -193,8 +193,8 @@ discard block |
||
193 | 193 | $multidimensional = array(); |
194 | 194 | $reference = &$multidimensional; |
195 | 195 | foreach ($flat_array as $key) { |
196 | - $reference[ $key ] = array(); |
|
197 | - $reference = &$reference[ $key ]; |
|
196 | + $reference[$key] = array(); |
|
197 | + $reference = &$reference[$key]; |
|
198 | 198 | } |
199 | 199 | if ($final_value !== null) { |
200 | 200 | $reference = $final_value; |
@@ -15,673 +15,673 @@ |
||
15 | 15 | class EEH_Event_Query |
16 | 16 | { |
17 | 17 | |
18 | - /** |
|
19 | - * Start Date |
|
20 | - * |
|
21 | - * @var $_event_query_month |
|
22 | - */ |
|
23 | - protected static $_event_query_month; |
|
24 | - |
|
25 | - /** |
|
26 | - * Category |
|
27 | - * |
|
28 | - * @var $_event_query_category |
|
29 | - */ |
|
30 | - protected static $_event_query_category; |
|
31 | - |
|
32 | - /** |
|
33 | - * whether to display expired events in the event list |
|
34 | - * |
|
35 | - * @var bool $_show_expired |
|
36 | - */ |
|
37 | - protected static $_event_query_show_expired = false; |
|
38 | - |
|
39 | - /** |
|
40 | - * list of params for controlling how the query results are ordered |
|
41 | - * |
|
42 | - * @var array $_event_query_orderby |
|
43 | - */ |
|
44 | - protected static $_event_query_orderby = array(); |
|
45 | - |
|
46 | - /** |
|
47 | - * direction list is sorted |
|
48 | - * |
|
49 | - * @var string $_event_query_sort |
|
50 | - */ |
|
51 | - protected static $_event_query_sort; |
|
52 | - |
|
53 | - /** |
|
54 | - * list of params used to build the query's various clauses |
|
55 | - * |
|
56 | - * @var $_query_params |
|
57 | - */ |
|
58 | - protected static $_query_params = array(); |
|
59 | - |
|
60 | - |
|
61 | - |
|
62 | - /** |
|
63 | - * @return void |
|
64 | - */ |
|
65 | - public static function add_query_filters() |
|
66 | - { |
|
67 | - // add query filters |
|
68 | - add_action('pre_get_posts', array('EEH_Event_Query', 'filter_query_parts'), 10, 1); |
|
69 | - } |
|
70 | - |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * @param WP_Query $WP_Query |
|
75 | - * @return bool |
|
76 | - */ |
|
77 | - public static function apply_query_filters(WP_Query $WP_Query) |
|
78 | - { |
|
79 | - return ( |
|
80 | - isset($WP_Query->query['post_type']) |
|
81 | - && $WP_Query->query['post_type'] === 'espresso_events' |
|
82 | - ) |
|
83 | - || apply_filters('FHEE__EEH_Event_Query__apply_query_filters', false); |
|
84 | - } |
|
85 | - |
|
86 | - |
|
87 | - /** |
|
88 | - * @param WP_Query $WP_Query |
|
89 | - */ |
|
90 | - public static function filter_query_parts(WP_Query $WP_Query) |
|
91 | - { |
|
92 | - // ONLY add our filters if this isn't the main wp_query, |
|
93 | - // because if this is the main wp_query we already have |
|
94 | - // our cpt strategies take care of adding things in. |
|
95 | - if ($WP_Query instanceof WP_Query && ! $WP_Query->is_main_query()) { |
|
96 | - // build event list query |
|
97 | - add_filter('posts_fields', array('EEH_Event_Query', 'posts_fields'), 10, 2); |
|
98 | - add_filter('posts_join', array('EEH_Event_Query', 'posts_join'), 10, 2); |
|
99 | - add_filter('posts_where', array('EEH_Event_Query', 'posts_where'), 10, 2); |
|
100 | - add_filter('posts_orderby', array('EEH_Event_Query', 'posts_orderby'), 10, 2); |
|
101 | - add_filter('posts_clauses_request', array('EEH_Event_Query', 'posts_clauses'), 10, 2); |
|
102 | - } |
|
103 | - } |
|
104 | - |
|
105 | - |
|
106 | - |
|
107 | - /** |
|
108 | - * @param string $month |
|
109 | - * @param string $category |
|
110 | - * @param bool $show_expired |
|
111 | - * @param string $orderby |
|
112 | - * @param string $sort |
|
113 | - * @throws InvalidArgumentException |
|
114 | - * @throws InvalidDataTypeException |
|
115 | - * @throws InvalidInterfaceException |
|
116 | - */ |
|
117 | - public static function set_query_params( |
|
118 | - $month = '', |
|
119 | - $category = '', |
|
120 | - $show_expired = false, |
|
121 | - $orderby = 'start_date', |
|
122 | - $sort = 'ASC' |
|
123 | - ) { |
|
124 | - self::$_query_params = array(); |
|
125 | - EEH_Event_Query::$_event_query_month = EEH_Event_Query::_display_month($month); |
|
126 | - EEH_Event_Query::$_event_query_category = EEH_Event_Query::_event_category_slug($category); |
|
127 | - EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired($show_expired); |
|
128 | - EEH_Event_Query::$_event_query_orderby = EEH_Event_Query::_orderby($orderby); |
|
129 | - EEH_Event_Query::$_event_query_sort = EEH_Event_Query::_sort($sort); |
|
130 | - } |
|
131 | - |
|
132 | - |
|
133 | - |
|
134 | - /** |
|
135 | - * what month should the event list display events for? |
|
136 | - * |
|
137 | - * @param string $month |
|
138 | - * @return string |
|
139 | - * @throws InvalidArgumentException |
|
140 | - * @throws InvalidDataTypeException |
|
141 | - * @throws InvalidInterfaceException |
|
142 | - */ |
|
143 | - private static function _display_month($month = '') |
|
144 | - { |
|
145 | - return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_month', $month)); |
|
146 | - } |
|
147 | - |
|
148 | - |
|
149 | - |
|
150 | - /** |
|
151 | - * @param string $category |
|
152 | - * @return string |
|
153 | - * @throws InvalidArgumentException |
|
154 | - * @throws InvalidDataTypeException |
|
155 | - * @throws InvalidInterfaceException |
|
156 | - */ |
|
157 | - private static function _event_category_slug($category = '') |
|
158 | - { |
|
159 | - return sanitize_title_with_dashes(EE_Registry::instance()->REQ->get('event_query_category', $category)); |
|
160 | - } |
|
161 | - |
|
162 | - |
|
163 | - |
|
164 | - /** |
|
165 | - * @param bool $show_expired |
|
166 | - * @return bool |
|
167 | - * @throws InvalidArgumentException |
|
168 | - * @throws InvalidDataTypeException |
|
169 | - * @throws InvalidInterfaceException |
|
170 | - */ |
|
171 | - private static function _show_expired($show_expired = false) |
|
172 | - { |
|
173 | - // override default expired option if set via filter |
|
174 | - return filter_var( |
|
175 | - EE_Registry::instance()->REQ->get('event_query_show_expired', $show_expired), |
|
176 | - FILTER_VALIDATE_BOOLEAN |
|
177 | - ); |
|
178 | - } |
|
179 | - |
|
180 | - |
|
181 | - |
|
182 | - /** |
|
183 | - * @param string $orderby |
|
184 | - * @return array |
|
185 | - * @throws InvalidArgumentException |
|
186 | - * @throws InvalidDataTypeException |
|
187 | - * @throws InvalidInterfaceException |
|
188 | - */ |
|
189 | - private static function _orderby($orderby = 'start_date') |
|
190 | - { |
|
191 | - $event_query_orderby = EE_Registry::instance()->REQ->get('event_query_orderby', $orderby); |
|
192 | - $event_query_orderby = is_array($event_query_orderby) |
|
193 | - ? $event_query_orderby |
|
194 | - : explode(',', $event_query_orderby); |
|
195 | - $event_query_orderby = array_map('trim', $event_query_orderby); |
|
196 | - $event_query_orderby = array_map('sanitize_text_field', $event_query_orderby); |
|
197 | - return $event_query_orderby; |
|
198 | - } |
|
199 | - |
|
200 | - |
|
201 | - |
|
202 | - /** |
|
203 | - * @param string $sort |
|
204 | - * @return string |
|
205 | - * @throws InvalidArgumentException |
|
206 | - * @throws InvalidDataTypeException |
|
207 | - * @throws InvalidInterfaceException |
|
208 | - */ |
|
209 | - private static function _sort($sort = 'ASC') |
|
210 | - { |
|
211 | - $sort = EE_Registry::instance()->REQ->get('event_query_sort', $sort); |
|
212 | - return in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true) |
|
213 | - ? strtoupper($sort) |
|
214 | - : 'ASC'; |
|
215 | - } |
|
216 | - |
|
217 | - |
|
218 | - |
|
219 | - /** |
|
220 | - * Filters the clauses for the WP_Query object |
|
221 | - * |
|
222 | - * @param array $clauses array of clauses |
|
223 | - * @param WP_Query $wp_query |
|
224 | - * @return array array of clauses |
|
225 | - */ |
|
226 | - public static function posts_clauses($clauses, WP_Query $wp_query) |
|
227 | - { |
|
228 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
229 | - global $wpdb; |
|
230 | - $clauses['groupby'] = $wpdb->posts . '.ID '; |
|
231 | - } |
|
232 | - return $clauses; |
|
233 | - } |
|
234 | - |
|
235 | - |
|
236 | - |
|
237 | - /** |
|
238 | - * @param string $SQL |
|
239 | - * @param WP_Query $wp_query |
|
240 | - * @return string |
|
241 | - * @throws EE_Error |
|
242 | - * @throws InvalidArgumentException |
|
243 | - * @throws InvalidDataTypeException |
|
244 | - * @throws InvalidInterfaceException |
|
245 | - */ |
|
246 | - public static function posts_fields($SQL, WP_Query $wp_query) |
|
247 | - { |
|
248 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
249 | - // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
|
250 | - $SQL .= EEH_Event_Query::posts_fields_sql_for_orderby(EEH_Event_Query::$_event_query_orderby); |
|
251 | - } |
|
252 | - return $SQL; |
|
253 | - } |
|
254 | - |
|
255 | - |
|
256 | - |
|
257 | - /** |
|
258 | - * @param array $orderby_params |
|
259 | - * @return string |
|
260 | - * @throws EE_Error |
|
261 | - * @throws InvalidArgumentException |
|
262 | - * @throws InvalidDataTypeException |
|
263 | - * @throws InvalidInterfaceException |
|
264 | - */ |
|
265 | - public static function posts_fields_sql_for_orderby(array $orderby_params = array()) |
|
266 | - { |
|
267 | - $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
268 | - foreach ($orderby_params as $orderby) { |
|
269 | - switch ($orderby) { |
|
270 | - case 'ticket_start': |
|
271 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date'; |
|
272 | - break; |
|
273 | - case 'ticket_end': |
|
274 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date'; |
|
275 | - break; |
|
276 | - case 'venue_title': |
|
277 | - $SQL .= ', Venue.post_title AS venue_title'; |
|
278 | - break; |
|
279 | - case 'city': |
|
280 | - $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city'; |
|
281 | - break; |
|
282 | - case 'state': |
|
283 | - $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name'; |
|
284 | - break; |
|
285 | - } |
|
286 | - } |
|
287 | - return $SQL; |
|
288 | - } |
|
289 | - |
|
290 | - |
|
291 | - |
|
292 | - /** |
|
293 | - * @param string $SQL |
|
294 | - * @param WP_Query $wp_query |
|
295 | - * @return string |
|
296 | - * @throws EE_Error |
|
297 | - * @throws InvalidArgumentException |
|
298 | - * @throws InvalidDataTypeException |
|
299 | - * @throws InvalidInterfaceException |
|
300 | - */ |
|
301 | - public static function posts_join($SQL = '', WP_Query $wp_query) |
|
302 | - { |
|
303 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
304 | - // Category |
|
305 | - $SQL = EEH_Event_Query::posts_join_sql_for_show_expired($SQL, EEH_Event_Query::$_event_query_show_expired); |
|
306 | - $SQL = EEH_Event_Query::posts_join_sql_for_terms($SQL, EEH_Event_Query::$_event_query_category); |
|
307 | - $SQL = EEH_Event_Query::posts_join_for_orderby($SQL, EEH_Event_Query::$_event_query_orderby); |
|
308 | - } |
|
309 | - return $SQL; |
|
310 | - } |
|
311 | - |
|
312 | - |
|
313 | - |
|
314 | - /** |
|
315 | - * @param string $SQL |
|
316 | - * @param boolean $show_expired if TRUE, then displayed past events |
|
317 | - * @return string |
|
318 | - * @throws EE_Error |
|
319 | - * @throws InvalidArgumentException |
|
320 | - * @throws InvalidDataTypeException |
|
321 | - * @throws InvalidInterfaceException |
|
322 | - */ |
|
323 | - public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false) |
|
324 | - { |
|
325 | - if (! $show_expired) { |
|
326 | - $join = EEM_Event::instance()->table() . '.ID = '; |
|
327 | - $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
328 | - // don't add if this is already in the SQL |
|
329 | - if (strpos($SQL, $join) === false) { |
|
330 | - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) '; |
|
331 | - } |
|
332 | - } |
|
333 | - return $SQL; |
|
334 | - } |
|
335 | - |
|
336 | - |
|
337 | - |
|
338 | - /** |
|
339 | - * @param string $SQL |
|
340 | - * @param string $join_terms pass TRUE or term string, doesn't really matter since this value doesn't really get |
|
341 | - * used for anything yet |
|
342 | - * @return string |
|
343 | - */ |
|
344 | - public static function posts_join_sql_for_terms($SQL = '', $join_terms = '') |
|
345 | - { |
|
346 | - if (! empty($join_terms)) { |
|
347 | - global $wpdb; |
|
348 | - $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)"; |
|
349 | - $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)"; |
|
350 | - $SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) "; |
|
351 | - } |
|
352 | - return $SQL; |
|
353 | - } |
|
354 | - |
|
355 | - |
|
356 | - |
|
357 | - /** |
|
358 | - * usage: $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params ); |
|
359 | - * |
|
360 | - * @param string $SQL |
|
361 | - * @param array $orderby_params |
|
362 | - * @return string |
|
363 | - * @throws EE_Error |
|
364 | - * @throws InvalidArgumentException |
|
365 | - * @throws InvalidDataTypeException |
|
366 | - * @throws InvalidInterfaceException |
|
367 | - */ |
|
368 | - public static function posts_join_for_orderby($SQL = '', array $orderby_params = array()) |
|
369 | - { |
|
370 | - foreach ($orderby_params as $orderby) { |
|
371 | - switch ($orderby) { |
|
372 | - case 'ticket_start': |
|
373 | - case 'ticket_end': |
|
374 | - $SQL .= EEH_Event_Query::_posts_join_for_datetime( |
|
375 | - $SQL, |
|
376 | - EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name() |
|
377 | - ); |
|
378 | - $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table(); |
|
379 | - $SQL .= ' ON ('; |
|
380 | - $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
381 | - $SQL .= ' = '; |
|
382 | - $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
383 | - $SQL .= ' )'; |
|
384 | - break; |
|
385 | - case 'venue_title': |
|
386 | - case 'city': |
|
387 | - $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
388 | - break; |
|
389 | - case 'state': |
|
390 | - $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
391 | - $SQL .= EEH_Event_Query::_posts_join_for_venue_state($SQL); |
|
392 | - break; |
|
393 | - case 'start_date': |
|
394 | - default: |
|
395 | - $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID'); |
|
396 | - break; |
|
397 | - } |
|
398 | - } |
|
399 | - return $SQL; |
|
400 | - } |
|
401 | - |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * @param string $SQL |
|
406 | - * @param string $join |
|
407 | - * @return string |
|
408 | - * @throws EE_Error |
|
409 | - * @throws InvalidArgumentException |
|
410 | - * @throws InvalidDataTypeException |
|
411 | - * @throws InvalidInterfaceException |
|
412 | - */ |
|
413 | - protected static function _posts_join_for_datetime($SQL = '', $join = '') |
|
414 | - { |
|
415 | - if (! empty($join)) { |
|
416 | - $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
417 | - if (strpos($SQL, $join) === false) { |
|
418 | - return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )'; |
|
419 | - } |
|
420 | - } |
|
421 | - return ''; |
|
422 | - } |
|
423 | - |
|
424 | - |
|
425 | - |
|
426 | - /** |
|
427 | - * @param string $SQL |
|
428 | - * @return string |
|
429 | - * @throws EE_Error |
|
430 | - * @throws InvalidArgumentException |
|
431 | - * @throws InvalidDataTypeException |
|
432 | - * @throws InvalidInterfaceException |
|
433 | - */ |
|
434 | - protected static function _posts_join_for_event_venue($SQL = '') |
|
435 | - { |
|
436 | - // Event Venue table name |
|
437 | - $event_venue_table = EEM_Event_Venue::instance()->table(); |
|
438 | - // generate conditions for: Event <=> Event Venue JOIN clause |
|
439 | - $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = '; |
|
440 | - $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name(); |
|
441 | - // don't add joins if they have already been added |
|
442 | - if (strpos($SQL, $event_to_event_venue_join) === false) { |
|
443 | - // Venue table name |
|
444 | - $venue_table = EEM_Venue::instance()->table(); |
|
445 | - // Venue table pk |
|
446 | - $venue_table_pk = EEM_Venue::instance()->primary_key_name(); |
|
447 | - // Venue Meta table name |
|
448 | - $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
449 | - // generate JOIN clause for: Event <=> Event Venue |
|
450 | - $venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )"; |
|
451 | - // generate JOIN clause for: Event Venue <=> Venue |
|
452 | - $venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )"; |
|
453 | - // generate JOIN clause for: Venue <=> Venue Meta |
|
454 | - $venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )"; |
|
455 | - unset($event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table); |
|
456 | - return $venue_SQL; |
|
457 | - } |
|
458 | - unset($event_venue_table, $event_to_event_venue_join); |
|
459 | - return ''; |
|
460 | - } |
|
461 | - |
|
462 | - |
|
463 | - |
|
464 | - /** |
|
465 | - * @param string $SQL |
|
466 | - * @return string |
|
467 | - * @throws EE_Error |
|
468 | - * @throws InvalidArgumentException |
|
469 | - * @throws InvalidDataTypeException |
|
470 | - * @throws InvalidInterfaceException |
|
471 | - */ |
|
472 | - protected static function _posts_join_for_venue_state($SQL = '') |
|
473 | - { |
|
474 | - // Venue Meta table name |
|
475 | - $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
476 | - // State table name |
|
477 | - $state_table = EEM_State::instance()->table(); |
|
478 | - // State table pk |
|
479 | - $state_table_pk = EEM_State::instance()->primary_key_name(); |
|
480 | - // verify vars |
|
481 | - if ($venue_meta_table && $state_table && $state_table_pk) { |
|
482 | - // like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID |
|
483 | - $join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk"; |
|
484 | - // don't add join if it has already been added |
|
485 | - if (strpos($SQL, $join) === false) { |
|
486 | - unset($state_table_pk, $venue_meta_table, $venue_table_pk); |
|
487 | - return " LEFT JOIN $state_table ON ( $join )"; |
|
488 | - } |
|
489 | - } |
|
490 | - unset($join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk); |
|
491 | - return ''; |
|
492 | - } |
|
493 | - |
|
494 | - |
|
495 | - |
|
496 | - /** |
|
497 | - * @param string $SQL |
|
498 | - * @param WP_Query $wp_query |
|
499 | - * @return string |
|
500 | - * @throws EE_Error |
|
501 | - * @throws InvalidArgumentException |
|
502 | - * @throws InvalidDataTypeException |
|
503 | - * @throws InvalidInterfaceException |
|
504 | - */ |
|
505 | - public static function posts_where($SQL = '', WP_Query $wp_query) |
|
506 | - { |
|
507 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
508 | - // Show Expired ? |
|
509 | - $SQL .= EEH_Event_Query::posts_where_sql_for_show_expired(EEH_Event_Query::$_event_query_show_expired); |
|
510 | - // Category |
|
511 | - $SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug(EEH_Event_Query::$_event_query_category); |
|
512 | - // Start Date |
|
513 | - $SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month(EEH_Event_Query::$_event_query_month); |
|
514 | - } |
|
515 | - return $SQL; |
|
516 | - } |
|
517 | - |
|
518 | - |
|
519 | - |
|
520 | - /** |
|
521 | - * @param boolean $show_expired if TRUE, then displayed past events |
|
522 | - * @return string |
|
523 | - * @throws EE_Error |
|
524 | - * @throws InvalidArgumentException |
|
525 | - * @throws InvalidDataTypeException |
|
526 | - * @throws InvalidInterfaceException |
|
527 | - */ |
|
528 | - public static function posts_where_sql_for_show_expired($show_expired = false) |
|
529 | - { |
|
530 | - return ! $show_expired |
|
531 | - ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' ' |
|
532 | - : ''; |
|
533 | - } |
|
534 | - |
|
535 | - |
|
536 | - |
|
537 | - /** |
|
538 | - * @param boolean $event_category_slug |
|
539 | - * @return string |
|
540 | - */ |
|
541 | - public static function posts_where_sql_for_event_category_slug($event_category_slug = null) |
|
542 | - { |
|
543 | - global $wpdb; |
|
544 | - return ! empty($event_category_slug) |
|
545 | - ? $wpdb->prepare(" AND {$wpdb->terms}.slug = %s ", $event_category_slug) |
|
546 | - : ''; |
|
547 | - } |
|
548 | - |
|
549 | - |
|
550 | - |
|
551 | - /** |
|
552 | - * @param boolean $month |
|
553 | - * @return string |
|
554 | - * @throws EE_Error |
|
555 | - * @throws InvalidArgumentException |
|
556 | - * @throws InvalidDataTypeException |
|
557 | - * @throws InvalidInterfaceException |
|
558 | - */ |
|
559 | - public static function posts_where_sql_for_event_list_month($month = null) |
|
560 | - { |
|
561 | - $SQL = ''; |
|
562 | - if (! empty($month)) { |
|
563 | - $datetime_table = EEM_Datetime::instance()->table(); |
|
564 | - // event start date is LESS than the end of the month ( so nothing that doesn't start until next month ) |
|
565 | - $SQL = " AND {$datetime_table}.DTT_EVT_start <= '"; |
|
566 | - $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "'"; |
|
567 | - // event end date is GREATER than the start of the month ( so nothing that ended before this month ) |
|
568 | - $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '"; |
|
569 | - $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "' "; |
|
570 | - } |
|
571 | - return $SQL; |
|
572 | - } |
|
573 | - |
|
574 | - |
|
575 | - |
|
576 | - /** |
|
577 | - * @param string $SQL |
|
578 | - * @param WP_Query $wp_query |
|
579 | - * @return string |
|
580 | - * @throws EE_Error |
|
581 | - * @throws InvalidArgumentException |
|
582 | - * @throws InvalidDataTypeException |
|
583 | - * @throws InvalidInterfaceException |
|
584 | - */ |
|
585 | - public static function posts_orderby($SQL = '', WP_Query $wp_query) |
|
586 | - { |
|
587 | - if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
588 | - $SQL = EEH_Event_Query::posts_orderby_sql( |
|
589 | - EEH_Event_Query::$_event_query_orderby, |
|
590 | - EEH_Event_Query::$_event_query_sort |
|
591 | - ); |
|
592 | - } |
|
593 | - return $SQL; |
|
594 | - } |
|
595 | - |
|
596 | - |
|
597 | - |
|
598 | - /** |
|
599 | - * posts_orderby_sql |
|
600 | - * possible parameters: |
|
601 | - * ID |
|
602 | - * start_date |
|
603 | - * end_date |
|
604 | - * event_name |
|
605 | - * category_slug |
|
606 | - * ticket_start |
|
607 | - * ticket_end |
|
608 | - * venue_title |
|
609 | - * city |
|
610 | - * state |
|
611 | - * **IMPORTANT** |
|
612 | - * make sure to also send the $orderby_params array to the posts_join_for_orderby() method |
|
613 | - * or else some of the table references below will result in MySQL errors |
|
614 | - * |
|
615 | - * @param array $orderby_params |
|
616 | - * @param string $sort |
|
617 | - * @return string |
|
618 | - * @throws EE_Error |
|
619 | - * @throws InvalidArgumentException |
|
620 | - * @throws InvalidDataTypeException |
|
621 | - * @throws InvalidInterfaceException |
|
622 | - */ |
|
623 | - public static function posts_orderby_sql(array $orderby_params = array(), $sort = 'ASC') |
|
624 | - { |
|
625 | - global $wpdb; |
|
626 | - $SQL = ''; |
|
627 | - $counter = 0; |
|
628 | - $sort = in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true) |
|
629 | - ? strtoupper($sort) |
|
630 | - : 'ASC'; |
|
631 | - // make sure 'orderby' is set in query params |
|
632 | - if (! isset(self::$_query_params['orderby'])) { |
|
633 | - self::$_query_params['orderby'] = array(); |
|
634 | - } |
|
635 | - // loop thru $orderby_params (type cast as array) |
|
636 | - foreach ($orderby_params as $orderby) { |
|
637 | - // check if we have already added this param |
|
638 | - if (isset(self::$_query_params['orderby'][ $orderby ])) { |
|
639 | - // if so then remove from the $orderby_params so that the count() method below is accurate |
|
640 | - unset($orderby_params[ $orderby ]); |
|
641 | - // then bump ahead to the next param |
|
642 | - continue; |
|
643 | - } |
|
644 | - // this will ad a comma depending on whether this is the first or last param |
|
645 | - $glue = $counter === 0 || $counter === count($orderby_params) ? ' ' : ', '; |
|
646 | - // ok what's we dealing with? |
|
647 | - switch ($orderby) { |
|
648 | - case 'id': |
|
649 | - case 'ID': |
|
650 | - $SQL .= $glue . $wpdb->posts . '.ID ' . $sort; |
|
651 | - break; |
|
652 | - case 'end_date': |
|
653 | - $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort; |
|
654 | - break; |
|
655 | - case 'event_name': |
|
656 | - $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort; |
|
657 | - break; |
|
658 | - case 'category_slug': |
|
659 | - $SQL .= $glue . $wpdb->terms . '.slug ' . $sort; |
|
660 | - break; |
|
661 | - case 'ticket_start': |
|
662 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort; |
|
663 | - break; |
|
664 | - case 'ticket_end': |
|
665 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort; |
|
666 | - break; |
|
667 | - case 'venue_title': |
|
668 | - $SQL .= $glue . 'venue_title ' . $sort; |
|
669 | - break; |
|
670 | - case 'city': |
|
671 | - $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort; |
|
672 | - break; |
|
673 | - case 'state': |
|
674 | - $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort; |
|
675 | - break; |
|
676 | - case 'start_date': |
|
677 | - default: |
|
678 | - $SQL .= $glue . ' event_start_date ' . $sort; |
|
679 | - break; |
|
680 | - } |
|
681 | - // add to array of orderby params that have been added |
|
682 | - self::$_query_params['orderby'][ $orderby ] = true; |
|
683 | - $counter++; |
|
684 | - } |
|
685 | - return $SQL; |
|
686 | - } |
|
18 | + /** |
|
19 | + * Start Date |
|
20 | + * |
|
21 | + * @var $_event_query_month |
|
22 | + */ |
|
23 | + protected static $_event_query_month; |
|
24 | + |
|
25 | + /** |
|
26 | + * Category |
|
27 | + * |
|
28 | + * @var $_event_query_category |
|
29 | + */ |
|
30 | + protected static $_event_query_category; |
|
31 | + |
|
32 | + /** |
|
33 | + * whether to display expired events in the event list |
|
34 | + * |
|
35 | + * @var bool $_show_expired |
|
36 | + */ |
|
37 | + protected static $_event_query_show_expired = false; |
|
38 | + |
|
39 | + /** |
|
40 | + * list of params for controlling how the query results are ordered |
|
41 | + * |
|
42 | + * @var array $_event_query_orderby |
|
43 | + */ |
|
44 | + protected static $_event_query_orderby = array(); |
|
45 | + |
|
46 | + /** |
|
47 | + * direction list is sorted |
|
48 | + * |
|
49 | + * @var string $_event_query_sort |
|
50 | + */ |
|
51 | + protected static $_event_query_sort; |
|
52 | + |
|
53 | + /** |
|
54 | + * list of params used to build the query's various clauses |
|
55 | + * |
|
56 | + * @var $_query_params |
|
57 | + */ |
|
58 | + protected static $_query_params = array(); |
|
59 | + |
|
60 | + |
|
61 | + |
|
62 | + /** |
|
63 | + * @return void |
|
64 | + */ |
|
65 | + public static function add_query_filters() |
|
66 | + { |
|
67 | + // add query filters |
|
68 | + add_action('pre_get_posts', array('EEH_Event_Query', 'filter_query_parts'), 10, 1); |
|
69 | + } |
|
70 | + |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * @param WP_Query $WP_Query |
|
75 | + * @return bool |
|
76 | + */ |
|
77 | + public static function apply_query_filters(WP_Query $WP_Query) |
|
78 | + { |
|
79 | + return ( |
|
80 | + isset($WP_Query->query['post_type']) |
|
81 | + && $WP_Query->query['post_type'] === 'espresso_events' |
|
82 | + ) |
|
83 | + || apply_filters('FHEE__EEH_Event_Query__apply_query_filters', false); |
|
84 | + } |
|
85 | + |
|
86 | + |
|
87 | + /** |
|
88 | + * @param WP_Query $WP_Query |
|
89 | + */ |
|
90 | + public static function filter_query_parts(WP_Query $WP_Query) |
|
91 | + { |
|
92 | + // ONLY add our filters if this isn't the main wp_query, |
|
93 | + // because if this is the main wp_query we already have |
|
94 | + // our cpt strategies take care of adding things in. |
|
95 | + if ($WP_Query instanceof WP_Query && ! $WP_Query->is_main_query()) { |
|
96 | + // build event list query |
|
97 | + add_filter('posts_fields', array('EEH_Event_Query', 'posts_fields'), 10, 2); |
|
98 | + add_filter('posts_join', array('EEH_Event_Query', 'posts_join'), 10, 2); |
|
99 | + add_filter('posts_where', array('EEH_Event_Query', 'posts_where'), 10, 2); |
|
100 | + add_filter('posts_orderby', array('EEH_Event_Query', 'posts_orderby'), 10, 2); |
|
101 | + add_filter('posts_clauses_request', array('EEH_Event_Query', 'posts_clauses'), 10, 2); |
|
102 | + } |
|
103 | + } |
|
104 | + |
|
105 | + |
|
106 | + |
|
107 | + /** |
|
108 | + * @param string $month |
|
109 | + * @param string $category |
|
110 | + * @param bool $show_expired |
|
111 | + * @param string $orderby |
|
112 | + * @param string $sort |
|
113 | + * @throws InvalidArgumentException |
|
114 | + * @throws InvalidDataTypeException |
|
115 | + * @throws InvalidInterfaceException |
|
116 | + */ |
|
117 | + public static function set_query_params( |
|
118 | + $month = '', |
|
119 | + $category = '', |
|
120 | + $show_expired = false, |
|
121 | + $orderby = 'start_date', |
|
122 | + $sort = 'ASC' |
|
123 | + ) { |
|
124 | + self::$_query_params = array(); |
|
125 | + EEH_Event_Query::$_event_query_month = EEH_Event_Query::_display_month($month); |
|
126 | + EEH_Event_Query::$_event_query_category = EEH_Event_Query::_event_category_slug($category); |
|
127 | + EEH_Event_Query::$_event_query_show_expired = EEH_Event_Query::_show_expired($show_expired); |
|
128 | + EEH_Event_Query::$_event_query_orderby = EEH_Event_Query::_orderby($orderby); |
|
129 | + EEH_Event_Query::$_event_query_sort = EEH_Event_Query::_sort($sort); |
|
130 | + } |
|
131 | + |
|
132 | + |
|
133 | + |
|
134 | + /** |
|
135 | + * what month should the event list display events for? |
|
136 | + * |
|
137 | + * @param string $month |
|
138 | + * @return string |
|
139 | + * @throws InvalidArgumentException |
|
140 | + * @throws InvalidDataTypeException |
|
141 | + * @throws InvalidInterfaceException |
|
142 | + */ |
|
143 | + private static function _display_month($month = '') |
|
144 | + { |
|
145 | + return sanitize_text_field(EE_Registry::instance()->REQ->get('event_query_month', $month)); |
|
146 | + } |
|
147 | + |
|
148 | + |
|
149 | + |
|
150 | + /** |
|
151 | + * @param string $category |
|
152 | + * @return string |
|
153 | + * @throws InvalidArgumentException |
|
154 | + * @throws InvalidDataTypeException |
|
155 | + * @throws InvalidInterfaceException |
|
156 | + */ |
|
157 | + private static function _event_category_slug($category = '') |
|
158 | + { |
|
159 | + return sanitize_title_with_dashes(EE_Registry::instance()->REQ->get('event_query_category', $category)); |
|
160 | + } |
|
161 | + |
|
162 | + |
|
163 | + |
|
164 | + /** |
|
165 | + * @param bool $show_expired |
|
166 | + * @return bool |
|
167 | + * @throws InvalidArgumentException |
|
168 | + * @throws InvalidDataTypeException |
|
169 | + * @throws InvalidInterfaceException |
|
170 | + */ |
|
171 | + private static function _show_expired($show_expired = false) |
|
172 | + { |
|
173 | + // override default expired option if set via filter |
|
174 | + return filter_var( |
|
175 | + EE_Registry::instance()->REQ->get('event_query_show_expired', $show_expired), |
|
176 | + FILTER_VALIDATE_BOOLEAN |
|
177 | + ); |
|
178 | + } |
|
179 | + |
|
180 | + |
|
181 | + |
|
182 | + /** |
|
183 | + * @param string $orderby |
|
184 | + * @return array |
|
185 | + * @throws InvalidArgumentException |
|
186 | + * @throws InvalidDataTypeException |
|
187 | + * @throws InvalidInterfaceException |
|
188 | + */ |
|
189 | + private static function _orderby($orderby = 'start_date') |
|
190 | + { |
|
191 | + $event_query_orderby = EE_Registry::instance()->REQ->get('event_query_orderby', $orderby); |
|
192 | + $event_query_orderby = is_array($event_query_orderby) |
|
193 | + ? $event_query_orderby |
|
194 | + : explode(',', $event_query_orderby); |
|
195 | + $event_query_orderby = array_map('trim', $event_query_orderby); |
|
196 | + $event_query_orderby = array_map('sanitize_text_field', $event_query_orderby); |
|
197 | + return $event_query_orderby; |
|
198 | + } |
|
199 | + |
|
200 | + |
|
201 | + |
|
202 | + /** |
|
203 | + * @param string $sort |
|
204 | + * @return string |
|
205 | + * @throws InvalidArgumentException |
|
206 | + * @throws InvalidDataTypeException |
|
207 | + * @throws InvalidInterfaceException |
|
208 | + */ |
|
209 | + private static function _sort($sort = 'ASC') |
|
210 | + { |
|
211 | + $sort = EE_Registry::instance()->REQ->get('event_query_sort', $sort); |
|
212 | + return in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true) |
|
213 | + ? strtoupper($sort) |
|
214 | + : 'ASC'; |
|
215 | + } |
|
216 | + |
|
217 | + |
|
218 | + |
|
219 | + /** |
|
220 | + * Filters the clauses for the WP_Query object |
|
221 | + * |
|
222 | + * @param array $clauses array of clauses |
|
223 | + * @param WP_Query $wp_query |
|
224 | + * @return array array of clauses |
|
225 | + */ |
|
226 | + public static function posts_clauses($clauses, WP_Query $wp_query) |
|
227 | + { |
|
228 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
229 | + global $wpdb; |
|
230 | + $clauses['groupby'] = $wpdb->posts . '.ID '; |
|
231 | + } |
|
232 | + return $clauses; |
|
233 | + } |
|
234 | + |
|
235 | + |
|
236 | + |
|
237 | + /** |
|
238 | + * @param string $SQL |
|
239 | + * @param WP_Query $wp_query |
|
240 | + * @return string |
|
241 | + * @throws EE_Error |
|
242 | + * @throws InvalidArgumentException |
|
243 | + * @throws InvalidDataTypeException |
|
244 | + * @throws InvalidInterfaceException |
|
245 | + */ |
|
246 | + public static function posts_fields($SQL, WP_Query $wp_query) |
|
247 | + { |
|
248 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
249 | + // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement |
|
250 | + $SQL .= EEH_Event_Query::posts_fields_sql_for_orderby(EEH_Event_Query::$_event_query_orderby); |
|
251 | + } |
|
252 | + return $SQL; |
|
253 | + } |
|
254 | + |
|
255 | + |
|
256 | + |
|
257 | + /** |
|
258 | + * @param array $orderby_params |
|
259 | + * @return string |
|
260 | + * @throws EE_Error |
|
261 | + * @throws InvalidArgumentException |
|
262 | + * @throws InvalidDataTypeException |
|
263 | + * @throws InvalidInterfaceException |
|
264 | + */ |
|
265 | + public static function posts_fields_sql_for_orderby(array $orderby_params = array()) |
|
266 | + { |
|
267 | + $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
268 | + foreach ($orderby_params as $orderby) { |
|
269 | + switch ($orderby) { |
|
270 | + case 'ticket_start': |
|
271 | + $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date'; |
|
272 | + break; |
|
273 | + case 'ticket_end': |
|
274 | + $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date'; |
|
275 | + break; |
|
276 | + case 'venue_title': |
|
277 | + $SQL .= ', Venue.post_title AS venue_title'; |
|
278 | + break; |
|
279 | + case 'city': |
|
280 | + $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city'; |
|
281 | + break; |
|
282 | + case 'state': |
|
283 | + $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name'; |
|
284 | + break; |
|
285 | + } |
|
286 | + } |
|
287 | + return $SQL; |
|
288 | + } |
|
289 | + |
|
290 | + |
|
291 | + |
|
292 | + /** |
|
293 | + * @param string $SQL |
|
294 | + * @param WP_Query $wp_query |
|
295 | + * @return string |
|
296 | + * @throws EE_Error |
|
297 | + * @throws InvalidArgumentException |
|
298 | + * @throws InvalidDataTypeException |
|
299 | + * @throws InvalidInterfaceException |
|
300 | + */ |
|
301 | + public static function posts_join($SQL = '', WP_Query $wp_query) |
|
302 | + { |
|
303 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
304 | + // Category |
|
305 | + $SQL = EEH_Event_Query::posts_join_sql_for_show_expired($SQL, EEH_Event_Query::$_event_query_show_expired); |
|
306 | + $SQL = EEH_Event_Query::posts_join_sql_for_terms($SQL, EEH_Event_Query::$_event_query_category); |
|
307 | + $SQL = EEH_Event_Query::posts_join_for_orderby($SQL, EEH_Event_Query::$_event_query_orderby); |
|
308 | + } |
|
309 | + return $SQL; |
|
310 | + } |
|
311 | + |
|
312 | + |
|
313 | + |
|
314 | + /** |
|
315 | + * @param string $SQL |
|
316 | + * @param boolean $show_expired if TRUE, then displayed past events |
|
317 | + * @return string |
|
318 | + * @throws EE_Error |
|
319 | + * @throws InvalidArgumentException |
|
320 | + * @throws InvalidDataTypeException |
|
321 | + * @throws InvalidInterfaceException |
|
322 | + */ |
|
323 | + public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false) |
|
324 | + { |
|
325 | + if (! $show_expired) { |
|
326 | + $join = EEM_Event::instance()->table() . '.ID = '; |
|
327 | + $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
328 | + // don't add if this is already in the SQL |
|
329 | + if (strpos($SQL, $join) === false) { |
|
330 | + $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) '; |
|
331 | + } |
|
332 | + } |
|
333 | + return $SQL; |
|
334 | + } |
|
335 | + |
|
336 | + |
|
337 | + |
|
338 | + /** |
|
339 | + * @param string $SQL |
|
340 | + * @param string $join_terms pass TRUE or term string, doesn't really matter since this value doesn't really get |
|
341 | + * used for anything yet |
|
342 | + * @return string |
|
343 | + */ |
|
344 | + public static function posts_join_sql_for_terms($SQL = '', $join_terms = '') |
|
345 | + { |
|
346 | + if (! empty($join_terms)) { |
|
347 | + global $wpdb; |
|
348 | + $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)"; |
|
349 | + $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)"; |
|
350 | + $SQL .= " LEFT JOIN $wpdb->terms ON ($wpdb->terms.term_id = $wpdb->term_taxonomy.term_id) "; |
|
351 | + } |
|
352 | + return $SQL; |
|
353 | + } |
|
354 | + |
|
355 | + |
|
356 | + |
|
357 | + /** |
|
358 | + * usage: $SQL .= EEH_Event_Query::posts_join_for_orderby( $orderby_params ); |
|
359 | + * |
|
360 | + * @param string $SQL |
|
361 | + * @param array $orderby_params |
|
362 | + * @return string |
|
363 | + * @throws EE_Error |
|
364 | + * @throws InvalidArgumentException |
|
365 | + * @throws InvalidDataTypeException |
|
366 | + * @throws InvalidInterfaceException |
|
367 | + */ |
|
368 | + public static function posts_join_for_orderby($SQL = '', array $orderby_params = array()) |
|
369 | + { |
|
370 | + foreach ($orderby_params as $orderby) { |
|
371 | + switch ($orderby) { |
|
372 | + case 'ticket_start': |
|
373 | + case 'ticket_end': |
|
374 | + $SQL .= EEH_Event_Query::_posts_join_for_datetime( |
|
375 | + $SQL, |
|
376 | + EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name() |
|
377 | + ); |
|
378 | + $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table(); |
|
379 | + $SQL .= ' ON ('; |
|
380 | + $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
381 | + $SQL .= ' = '; |
|
382 | + $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
383 | + $SQL .= ' )'; |
|
384 | + break; |
|
385 | + case 'venue_title': |
|
386 | + case 'city': |
|
387 | + $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
388 | + break; |
|
389 | + case 'state': |
|
390 | + $SQL .= EEH_Event_Query::_posts_join_for_event_venue($SQL); |
|
391 | + $SQL .= EEH_Event_Query::_posts_join_for_venue_state($SQL); |
|
392 | + break; |
|
393 | + case 'start_date': |
|
394 | + default: |
|
395 | + $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID'); |
|
396 | + break; |
|
397 | + } |
|
398 | + } |
|
399 | + return $SQL; |
|
400 | + } |
|
401 | + |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * @param string $SQL |
|
406 | + * @param string $join |
|
407 | + * @return string |
|
408 | + * @throws EE_Error |
|
409 | + * @throws InvalidArgumentException |
|
410 | + * @throws InvalidDataTypeException |
|
411 | + * @throws InvalidInterfaceException |
|
412 | + */ |
|
413 | + protected static function _posts_join_for_datetime($SQL = '', $join = '') |
|
414 | + { |
|
415 | + if (! empty($join)) { |
|
416 | + $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
417 | + if (strpos($SQL, $join) === false) { |
|
418 | + return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )'; |
|
419 | + } |
|
420 | + } |
|
421 | + return ''; |
|
422 | + } |
|
423 | + |
|
424 | + |
|
425 | + |
|
426 | + /** |
|
427 | + * @param string $SQL |
|
428 | + * @return string |
|
429 | + * @throws EE_Error |
|
430 | + * @throws InvalidArgumentException |
|
431 | + * @throws InvalidDataTypeException |
|
432 | + * @throws InvalidInterfaceException |
|
433 | + */ |
|
434 | + protected static function _posts_join_for_event_venue($SQL = '') |
|
435 | + { |
|
436 | + // Event Venue table name |
|
437 | + $event_venue_table = EEM_Event_Venue::instance()->table(); |
|
438 | + // generate conditions for: Event <=> Event Venue JOIN clause |
|
439 | + $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = '; |
|
440 | + $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name(); |
|
441 | + // don't add joins if they have already been added |
|
442 | + if (strpos($SQL, $event_to_event_venue_join) === false) { |
|
443 | + // Venue table name |
|
444 | + $venue_table = EEM_Venue::instance()->table(); |
|
445 | + // Venue table pk |
|
446 | + $venue_table_pk = EEM_Venue::instance()->primary_key_name(); |
|
447 | + // Venue Meta table name |
|
448 | + $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
449 | + // generate JOIN clause for: Event <=> Event Venue |
|
450 | + $venue_SQL = " LEFT JOIN $event_venue_table ON ( $event_to_event_venue_join )"; |
|
451 | + // generate JOIN clause for: Event Venue <=> Venue |
|
452 | + $venue_SQL .= " LEFT JOIN $venue_table as Venue ON ( $event_venue_table.$venue_table_pk = Venue.ID )"; |
|
453 | + // generate JOIN clause for: Venue <=> Venue Meta |
|
454 | + $venue_SQL .= " LEFT JOIN $venue_meta_table ON ( Venue.ID = $venue_meta_table.$venue_table_pk )"; |
|
455 | + unset($event_venue_table, $event_to_event_venue_join, $venue_table, $venue_table_pk, $venue_meta_table); |
|
456 | + return $venue_SQL; |
|
457 | + } |
|
458 | + unset($event_venue_table, $event_to_event_venue_join); |
|
459 | + return ''; |
|
460 | + } |
|
461 | + |
|
462 | + |
|
463 | + |
|
464 | + /** |
|
465 | + * @param string $SQL |
|
466 | + * @return string |
|
467 | + * @throws EE_Error |
|
468 | + * @throws InvalidArgumentException |
|
469 | + * @throws InvalidDataTypeException |
|
470 | + * @throws InvalidInterfaceException |
|
471 | + */ |
|
472 | + protected static function _posts_join_for_venue_state($SQL = '') |
|
473 | + { |
|
474 | + // Venue Meta table name |
|
475 | + $venue_meta_table = EEM_Venue::instance()->second_table(); |
|
476 | + // State table name |
|
477 | + $state_table = EEM_State::instance()->table(); |
|
478 | + // State table pk |
|
479 | + $state_table_pk = EEM_State::instance()->primary_key_name(); |
|
480 | + // verify vars |
|
481 | + if ($venue_meta_table && $state_table && $state_table_pk) { |
|
482 | + // like: wp_esp_venue_meta.STA_ID = wp_esp_state.STA_ID |
|
483 | + $join = "$venue_meta_table.$state_table_pk = $state_table.$state_table_pk"; |
|
484 | + // don't add join if it has already been added |
|
485 | + if (strpos($SQL, $join) === false) { |
|
486 | + unset($state_table_pk, $venue_meta_table, $venue_table_pk); |
|
487 | + return " LEFT JOIN $state_table ON ( $join )"; |
|
488 | + } |
|
489 | + } |
|
490 | + unset($join, $state_table, $state_table_pk, $venue_meta_table, $venue_table_pk); |
|
491 | + return ''; |
|
492 | + } |
|
493 | + |
|
494 | + |
|
495 | + |
|
496 | + /** |
|
497 | + * @param string $SQL |
|
498 | + * @param WP_Query $wp_query |
|
499 | + * @return string |
|
500 | + * @throws EE_Error |
|
501 | + * @throws InvalidArgumentException |
|
502 | + * @throws InvalidDataTypeException |
|
503 | + * @throws InvalidInterfaceException |
|
504 | + */ |
|
505 | + public static function posts_where($SQL = '', WP_Query $wp_query) |
|
506 | + { |
|
507 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
508 | + // Show Expired ? |
|
509 | + $SQL .= EEH_Event_Query::posts_where_sql_for_show_expired(EEH_Event_Query::$_event_query_show_expired); |
|
510 | + // Category |
|
511 | + $SQL .= EEH_Event_Query::posts_where_sql_for_event_category_slug(EEH_Event_Query::$_event_query_category); |
|
512 | + // Start Date |
|
513 | + $SQL .= EEH_Event_Query::posts_where_sql_for_event_list_month(EEH_Event_Query::$_event_query_month); |
|
514 | + } |
|
515 | + return $SQL; |
|
516 | + } |
|
517 | + |
|
518 | + |
|
519 | + |
|
520 | + /** |
|
521 | + * @param boolean $show_expired if TRUE, then displayed past events |
|
522 | + * @return string |
|
523 | + * @throws EE_Error |
|
524 | + * @throws InvalidArgumentException |
|
525 | + * @throws InvalidDataTypeException |
|
526 | + * @throws InvalidInterfaceException |
|
527 | + */ |
|
528 | + public static function posts_where_sql_for_show_expired($show_expired = false) |
|
529 | + { |
|
530 | + return ! $show_expired |
|
531 | + ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' ' |
|
532 | + : ''; |
|
533 | + } |
|
534 | + |
|
535 | + |
|
536 | + |
|
537 | + /** |
|
538 | + * @param boolean $event_category_slug |
|
539 | + * @return string |
|
540 | + */ |
|
541 | + public static function posts_where_sql_for_event_category_slug($event_category_slug = null) |
|
542 | + { |
|
543 | + global $wpdb; |
|
544 | + return ! empty($event_category_slug) |
|
545 | + ? $wpdb->prepare(" AND {$wpdb->terms}.slug = %s ", $event_category_slug) |
|
546 | + : ''; |
|
547 | + } |
|
548 | + |
|
549 | + |
|
550 | + |
|
551 | + /** |
|
552 | + * @param boolean $month |
|
553 | + * @return string |
|
554 | + * @throws EE_Error |
|
555 | + * @throws InvalidArgumentException |
|
556 | + * @throws InvalidDataTypeException |
|
557 | + * @throws InvalidInterfaceException |
|
558 | + */ |
|
559 | + public static function posts_where_sql_for_event_list_month($month = null) |
|
560 | + { |
|
561 | + $SQL = ''; |
|
562 | + if (! empty($month)) { |
|
563 | + $datetime_table = EEM_Datetime::instance()->table(); |
|
564 | + // event start date is LESS than the end of the month ( so nothing that doesn't start until next month ) |
|
565 | + $SQL = " AND {$datetime_table}.DTT_EVT_start <= '"; |
|
566 | + $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "'"; |
|
567 | + // event end date is GREATER than the start of the month ( so nothing that ended before this month ) |
|
568 | + $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '"; |
|
569 | + $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "' "; |
|
570 | + } |
|
571 | + return $SQL; |
|
572 | + } |
|
573 | + |
|
574 | + |
|
575 | + |
|
576 | + /** |
|
577 | + * @param string $SQL |
|
578 | + * @param WP_Query $wp_query |
|
579 | + * @return string |
|
580 | + * @throws EE_Error |
|
581 | + * @throws InvalidArgumentException |
|
582 | + * @throws InvalidDataTypeException |
|
583 | + * @throws InvalidInterfaceException |
|
584 | + */ |
|
585 | + public static function posts_orderby($SQL = '', WP_Query $wp_query) |
|
586 | + { |
|
587 | + if (EEH_Event_Query::apply_query_filters($wp_query)) { |
|
588 | + $SQL = EEH_Event_Query::posts_orderby_sql( |
|
589 | + EEH_Event_Query::$_event_query_orderby, |
|
590 | + EEH_Event_Query::$_event_query_sort |
|
591 | + ); |
|
592 | + } |
|
593 | + return $SQL; |
|
594 | + } |
|
595 | + |
|
596 | + |
|
597 | + |
|
598 | + /** |
|
599 | + * posts_orderby_sql |
|
600 | + * possible parameters: |
|
601 | + * ID |
|
602 | + * start_date |
|
603 | + * end_date |
|
604 | + * event_name |
|
605 | + * category_slug |
|
606 | + * ticket_start |
|
607 | + * ticket_end |
|
608 | + * venue_title |
|
609 | + * city |
|
610 | + * state |
|
611 | + * **IMPORTANT** |
|
612 | + * make sure to also send the $orderby_params array to the posts_join_for_orderby() method |
|
613 | + * or else some of the table references below will result in MySQL errors |
|
614 | + * |
|
615 | + * @param array $orderby_params |
|
616 | + * @param string $sort |
|
617 | + * @return string |
|
618 | + * @throws EE_Error |
|
619 | + * @throws InvalidArgumentException |
|
620 | + * @throws InvalidDataTypeException |
|
621 | + * @throws InvalidInterfaceException |
|
622 | + */ |
|
623 | + public static function posts_orderby_sql(array $orderby_params = array(), $sort = 'ASC') |
|
624 | + { |
|
625 | + global $wpdb; |
|
626 | + $SQL = ''; |
|
627 | + $counter = 0; |
|
628 | + $sort = in_array($sort, array('ASC', 'asc', 'DESC', 'desc'), true) |
|
629 | + ? strtoupper($sort) |
|
630 | + : 'ASC'; |
|
631 | + // make sure 'orderby' is set in query params |
|
632 | + if (! isset(self::$_query_params['orderby'])) { |
|
633 | + self::$_query_params['orderby'] = array(); |
|
634 | + } |
|
635 | + // loop thru $orderby_params (type cast as array) |
|
636 | + foreach ($orderby_params as $orderby) { |
|
637 | + // check if we have already added this param |
|
638 | + if (isset(self::$_query_params['orderby'][ $orderby ])) { |
|
639 | + // if so then remove from the $orderby_params so that the count() method below is accurate |
|
640 | + unset($orderby_params[ $orderby ]); |
|
641 | + // then bump ahead to the next param |
|
642 | + continue; |
|
643 | + } |
|
644 | + // this will ad a comma depending on whether this is the first or last param |
|
645 | + $glue = $counter === 0 || $counter === count($orderby_params) ? ' ' : ', '; |
|
646 | + // ok what's we dealing with? |
|
647 | + switch ($orderby) { |
|
648 | + case 'id': |
|
649 | + case 'ID': |
|
650 | + $SQL .= $glue . $wpdb->posts . '.ID ' . $sort; |
|
651 | + break; |
|
652 | + case 'end_date': |
|
653 | + $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort; |
|
654 | + break; |
|
655 | + case 'event_name': |
|
656 | + $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort; |
|
657 | + break; |
|
658 | + case 'category_slug': |
|
659 | + $SQL .= $glue . $wpdb->terms . '.slug ' . $sort; |
|
660 | + break; |
|
661 | + case 'ticket_start': |
|
662 | + $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort; |
|
663 | + break; |
|
664 | + case 'ticket_end': |
|
665 | + $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort; |
|
666 | + break; |
|
667 | + case 'venue_title': |
|
668 | + $SQL .= $glue . 'venue_title ' . $sort; |
|
669 | + break; |
|
670 | + case 'city': |
|
671 | + $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort; |
|
672 | + break; |
|
673 | + case 'state': |
|
674 | + $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort; |
|
675 | + break; |
|
676 | + case 'start_date': |
|
677 | + default: |
|
678 | + $SQL .= $glue . ' event_start_date ' . $sort; |
|
679 | + break; |
|
680 | + } |
|
681 | + // add to array of orderby params that have been added |
|
682 | + self::$_query_params['orderby'][ $orderby ] = true; |
|
683 | + $counter++; |
|
684 | + } |
|
685 | + return $SQL; |
|
686 | + } |
|
687 | 687 | } |
@@ -227,7 +227,7 @@ discard block |
||
227 | 227 | { |
228 | 228 | if (EEH_Event_Query::apply_query_filters($wp_query)) { |
229 | 229 | global $wpdb; |
230 | - $clauses['groupby'] = $wpdb->posts . '.ID '; |
|
230 | + $clauses['groupby'] = $wpdb->posts.'.ID '; |
|
231 | 231 | } |
232 | 232 | return $clauses; |
233 | 233 | } |
@@ -264,23 +264,23 @@ discard block |
||
264 | 264 | */ |
265 | 265 | public static function posts_fields_sql_for_orderby(array $orderby_params = array()) |
266 | 266 | { |
267 | - $SQL = ', MIN( ' . EEM_Datetime::instance()->table() . '.DTT_EVT_start ) as event_start_date '; |
|
267 | + $SQL = ', MIN( '.EEM_Datetime::instance()->table().'.DTT_EVT_start ) as event_start_date '; |
|
268 | 268 | foreach ($orderby_params as $orderby) { |
269 | 269 | switch ($orderby) { |
270 | 270 | case 'ticket_start': |
271 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_start_date'; |
|
271 | + $SQL .= ', '.EEM_Ticket::instance()->table().'.TKT_start_date'; |
|
272 | 272 | break; |
273 | 273 | case 'ticket_end': |
274 | - $SQL .= ', ' . EEM_Ticket::instance()->table() . '.TKT_end_date'; |
|
274 | + $SQL .= ', '.EEM_Ticket::instance()->table().'.TKT_end_date'; |
|
275 | 275 | break; |
276 | 276 | case 'venue_title': |
277 | 277 | $SQL .= ', Venue.post_title AS venue_title'; |
278 | 278 | break; |
279 | 279 | case 'city': |
280 | - $SQL .= ', ' . EEM_Venue::instance()->second_table() . '.VNU_city'; |
|
280 | + $SQL .= ', '.EEM_Venue::instance()->second_table().'.VNU_city'; |
|
281 | 281 | break; |
282 | 282 | case 'state': |
283 | - $SQL .= ', ' . EEM_State::instance()->table() . '.STA_name'; |
|
283 | + $SQL .= ', '.EEM_State::instance()->table().'.STA_name'; |
|
284 | 284 | break; |
285 | 285 | } |
286 | 286 | } |
@@ -322,12 +322,12 @@ discard block |
||
322 | 322 | */ |
323 | 323 | public static function posts_join_sql_for_show_expired($SQL = '', $show_expired = false) |
324 | 324 | { |
325 | - if (! $show_expired) { |
|
326 | - $join = EEM_Event::instance()->table() . '.ID = '; |
|
327 | - $join .= EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
325 | + if ( ! $show_expired) { |
|
326 | + $join = EEM_Event::instance()->table().'.ID = '; |
|
327 | + $join .= EEM_Datetime::instance()->table().'.'.EEM_Event::instance()->primary_key_name(); |
|
328 | 328 | // don't add if this is already in the SQL |
329 | 329 | if (strpos($SQL, $join) === false) { |
330 | - $SQL .= ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' ) '; |
|
330 | + $SQL .= ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.$join.' ) '; |
|
331 | 331 | } |
332 | 332 | } |
333 | 333 | return $SQL; |
@@ -343,7 +343,7 @@ discard block |
||
343 | 343 | */ |
344 | 344 | public static function posts_join_sql_for_terms($SQL = '', $join_terms = '') |
345 | 345 | { |
346 | - if (! empty($join_terms)) { |
|
346 | + if ( ! empty($join_terms)) { |
|
347 | 347 | global $wpdb; |
348 | 348 | $SQL .= " LEFT JOIN $wpdb->term_relationships ON ($wpdb->posts.ID = $wpdb->term_relationships.object_id)"; |
349 | 349 | $SQL .= " LEFT JOIN $wpdb->term_taxonomy ON ($wpdb->term_relationships.term_taxonomy_id = $wpdb->term_taxonomy.term_taxonomy_id)"; |
@@ -373,13 +373,13 @@ discard block |
||
373 | 373 | case 'ticket_end': |
374 | 374 | $SQL .= EEH_Event_Query::_posts_join_for_datetime( |
375 | 375 | $SQL, |
376 | - EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Datetime::instance()->primary_key_name() |
|
376 | + EEM_Datetime_Ticket::instance()->table().'.'.EEM_Datetime::instance()->primary_key_name() |
|
377 | 377 | ); |
378 | - $SQL .= ' LEFT JOIN ' . EEM_Ticket::instance()->table(); |
|
378 | + $SQL .= ' LEFT JOIN '.EEM_Ticket::instance()->table(); |
|
379 | 379 | $SQL .= ' ON ('; |
380 | - $SQL .= EEM_Datetime_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
380 | + $SQL .= EEM_Datetime_Ticket::instance()->table().'.'.EEM_Ticket::instance()->primary_key_name(); |
|
381 | 381 | $SQL .= ' = '; |
382 | - $SQL .= EEM_Ticket::instance()->table() . '.' . EEM_Ticket::instance()->primary_key_name(); |
|
382 | + $SQL .= EEM_Ticket::instance()->table().'.'.EEM_Ticket::instance()->primary_key_name(); |
|
383 | 383 | $SQL .= ' )'; |
384 | 384 | break; |
385 | 385 | case 'venue_title': |
@@ -392,7 +392,7 @@ discard block |
||
392 | 392 | break; |
393 | 393 | case 'start_date': |
394 | 394 | default: |
395 | - $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table() . '.ID'); |
|
395 | + $SQL .= EEH_Event_Query::_posts_join_for_datetime($SQL, EEM_Event::instance()->table().'.ID'); |
|
396 | 396 | break; |
397 | 397 | } |
398 | 398 | } |
@@ -412,10 +412,10 @@ discard block |
||
412 | 412 | */ |
413 | 413 | protected static function _posts_join_for_datetime($SQL = '', $join = '') |
414 | 414 | { |
415 | - if (! empty($join)) { |
|
416 | - $join .= ' = ' . EEM_Datetime::instance()->table() . '.' . EEM_Event::instance()->primary_key_name(); |
|
415 | + if ( ! empty($join)) { |
|
416 | + $join .= ' = '.EEM_Datetime::instance()->table().'.'.EEM_Event::instance()->primary_key_name(); |
|
417 | 417 | if (strpos($SQL, $join) === false) { |
418 | - return ' INNER JOIN ' . EEM_Datetime::instance()->table() . ' ON ( ' . $join . ' )'; |
|
418 | + return ' INNER JOIN '.EEM_Datetime::instance()->table().' ON ( '.$join.' )'; |
|
419 | 419 | } |
420 | 420 | } |
421 | 421 | return ''; |
@@ -436,8 +436,8 @@ discard block |
||
436 | 436 | // Event Venue table name |
437 | 437 | $event_venue_table = EEM_Event_Venue::instance()->table(); |
438 | 438 | // generate conditions for: Event <=> Event Venue JOIN clause |
439 | - $event_to_event_venue_join = EEM_Event::instance()->table() . '.ID = '; |
|
440 | - $event_to_event_venue_join .= $event_venue_table . '.' . EEM_Event::instance()->primary_key_name(); |
|
439 | + $event_to_event_venue_join = EEM_Event::instance()->table().'.ID = '; |
|
440 | + $event_to_event_venue_join .= $event_venue_table.'.'.EEM_Event::instance()->primary_key_name(); |
|
441 | 441 | // don't add joins if they have already been added |
442 | 442 | if (strpos($SQL, $event_to_event_venue_join) === false) { |
443 | 443 | // Venue table name |
@@ -528,7 +528,7 @@ discard block |
||
528 | 528 | public static function posts_where_sql_for_show_expired($show_expired = false) |
529 | 529 | { |
530 | 530 | return ! $show_expired |
531 | - ? ' AND ' . EEM_Datetime::instance()->table() . '.DTT_EVT_end > \'' . current_time('mysql', true) . '\' ' |
|
531 | + ? ' AND '.EEM_Datetime::instance()->table().'.DTT_EVT_end > \''.current_time('mysql', true).'\' ' |
|
532 | 532 | : ''; |
533 | 533 | } |
534 | 534 | |
@@ -559,14 +559,14 @@ discard block |
||
559 | 559 | public static function posts_where_sql_for_event_list_month($month = null) |
560 | 560 | { |
561 | 561 | $SQL = ''; |
562 | - if (! empty($month)) { |
|
562 | + if ( ! empty($month)) { |
|
563 | 563 | $datetime_table = EEM_Datetime::instance()->table(); |
564 | 564 | // event start date is LESS than the end of the month ( so nothing that doesn't start until next month ) |
565 | 565 | $SQL = " AND {$datetime_table}.DTT_EVT_start <= '"; |
566 | - $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "'"; |
|
566 | + $SQL .= date('Y-m-t 23:59:59', \EEH_DTT_Helper::first_of_month_timestamp($month))."'"; |
|
567 | 567 | // event end date is GREATER than the start of the month ( so nothing that ended before this month ) |
568 | 568 | $SQL .= " AND {$datetime_table}.DTT_EVT_end >= '"; |
569 | - $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month)) . "' "; |
|
569 | + $SQL .= date('Y-m-01 0:0:00', \EEH_DTT_Helper::first_of_month_timestamp($month))."' "; |
|
570 | 570 | } |
571 | 571 | return $SQL; |
572 | 572 | } |
@@ -629,15 +629,15 @@ discard block |
||
629 | 629 | ? strtoupper($sort) |
630 | 630 | : 'ASC'; |
631 | 631 | // make sure 'orderby' is set in query params |
632 | - if (! isset(self::$_query_params['orderby'])) { |
|
632 | + if ( ! isset(self::$_query_params['orderby'])) { |
|
633 | 633 | self::$_query_params['orderby'] = array(); |
634 | 634 | } |
635 | 635 | // loop thru $orderby_params (type cast as array) |
636 | 636 | foreach ($orderby_params as $orderby) { |
637 | 637 | // check if we have already added this param |
638 | - if (isset(self::$_query_params['orderby'][ $orderby ])) { |
|
638 | + if (isset(self::$_query_params['orderby'][$orderby])) { |
|
639 | 639 | // if so then remove from the $orderby_params so that the count() method below is accurate |
640 | - unset($orderby_params[ $orderby ]); |
|
640 | + unset($orderby_params[$orderby]); |
|
641 | 641 | // then bump ahead to the next param |
642 | 642 | continue; |
643 | 643 | } |
@@ -647,39 +647,39 @@ discard block |
||
647 | 647 | switch ($orderby) { |
648 | 648 | case 'id': |
649 | 649 | case 'ID': |
650 | - $SQL .= $glue . $wpdb->posts . '.ID ' . $sort; |
|
650 | + $SQL .= $glue.$wpdb->posts.'.ID '.$sort; |
|
651 | 651 | break; |
652 | 652 | case 'end_date': |
653 | - $SQL .= $glue . EEM_Datetime::instance()->table() . '.DTT_EVT_end ' . $sort; |
|
653 | + $SQL .= $glue.EEM_Datetime::instance()->table().'.DTT_EVT_end '.$sort; |
|
654 | 654 | break; |
655 | 655 | case 'event_name': |
656 | - $SQL .= $glue . $wpdb->posts . '.post_title ' . $sort; |
|
656 | + $SQL .= $glue.$wpdb->posts.'.post_title '.$sort; |
|
657 | 657 | break; |
658 | 658 | case 'category_slug': |
659 | - $SQL .= $glue . $wpdb->terms . '.slug ' . $sort; |
|
659 | + $SQL .= $glue.$wpdb->terms.'.slug '.$sort; |
|
660 | 660 | break; |
661 | 661 | case 'ticket_start': |
662 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_start_date ' . $sort; |
|
662 | + $SQL .= $glue.EEM_Ticket::instance()->table().'.TKT_start_date '.$sort; |
|
663 | 663 | break; |
664 | 664 | case 'ticket_end': |
665 | - $SQL .= $glue . EEM_Ticket::instance()->table() . '.TKT_end_date ' . $sort; |
|
665 | + $SQL .= $glue.EEM_Ticket::instance()->table().'.TKT_end_date '.$sort; |
|
666 | 666 | break; |
667 | 667 | case 'venue_title': |
668 | - $SQL .= $glue . 'venue_title ' . $sort; |
|
668 | + $SQL .= $glue.'venue_title '.$sort; |
|
669 | 669 | break; |
670 | 670 | case 'city': |
671 | - $SQL .= $glue . EEM_Venue::instance()->second_table() . '.VNU_city ' . $sort; |
|
671 | + $SQL .= $glue.EEM_Venue::instance()->second_table().'.VNU_city '.$sort; |
|
672 | 672 | break; |
673 | 673 | case 'state': |
674 | - $SQL .= $glue . EEM_State::instance()->table() . '.STA_name ' . $sort; |
|
674 | + $SQL .= $glue.EEM_State::instance()->table().'.STA_name '.$sort; |
|
675 | 675 | break; |
676 | 676 | case 'start_date': |
677 | 677 | default: |
678 | - $SQL .= $glue . ' event_start_date ' . $sort; |
|
678 | + $SQL .= $glue.' event_start_date '.$sort; |
|
679 | 679 | break; |
680 | 680 | } |
681 | 681 | // add to array of orderby params that have been added |
682 | - self::$_query_params['orderby'][ $orderby ] = true; |
|
682 | + self::$_query_params['orderby'][$orderby] = true; |
|
683 | 683 | $counter++; |
684 | 684 | } |
685 | 685 | return $SQL; |
@@ -11,131 +11,131 @@ |
||
11 | 11 | class EEH_Class_Tools |
12 | 12 | { |
13 | 13 | |
14 | - public static $i = 0; |
|
15 | - public static $file_line = null; |
|
14 | + public static $i = 0; |
|
15 | + public static $file_line = null; |
|
16 | 16 | |
17 | - /** |
|
18 | - * get_called_class - for PHP versions < 5.3 |
|
19 | - * |
|
20 | - * @access public |
|
21 | - * @author origins: http://stackoverflow.com/a/1542045 |
|
22 | - * return string |
|
23 | - */ |
|
24 | - public static function get_called_class() |
|
25 | - { |
|
26 | - $backtrace = debug_backtrace(); |
|
27 | - if (isset($backtrace[2]) && is_array($backtrace[2]) && isset($backtrace[2]['class']) && ! isset($backtrace[2]['file'])) { |
|
28 | - return $backtrace[2]['class']; |
|
29 | - } elseif (isset($backtrace[3]) && is_array($backtrace[3]) && isset($backtrace[3]['class']) && ! isset($backtrace[3]['file'])) { |
|
30 | - return $backtrace[3]['class']; |
|
31 | - } elseif (isset($backtrace[2]) && is_array($backtrace[2]) && isset($backtrace[2]['file']) && isset($backtrace[2]['line'])) { |
|
32 | - if (self::$file_line == $backtrace[2]['file'] . $backtrace[2]['line']) { |
|
33 | - self::$i++; |
|
34 | - } else { |
|
35 | - self::$i = 0; |
|
36 | - self::$file_line = $backtrace[2]['file'] . $backtrace[2]['line']; |
|
37 | - } |
|
38 | - // was class method called via call_user_func ? |
|
39 | - if ($backtrace[2]['function'] == 'call_user_func' && isset($backtrace[2]['args']) && is_array($backtrace[2]['args'])) { |
|
40 | - if (isset($backtrace[2]['args'][0]) && isset($backtrace[2]['args'][0][0])) { |
|
41 | - $called_class = $backtrace[2]['args'][0][0]; |
|
42 | - // is it an EE function ? |
|
43 | - if (strpos($called_class, 'EE') === 0) { |
|
44 | - $prefix_chars = strpos($called_class, '_') + 1; |
|
45 | - $prefix = substr($called_class, 0, $prefix_chars); |
|
46 | - $classname = substr($called_class, $prefix_chars, strlen($called_class)); |
|
47 | - $classname = $prefix . str_replace(' ', '_', ucwords(strtolower(str_replace('_', ' ', $classname)))); |
|
48 | - return $classname; |
|
49 | - } |
|
50 | - } |
|
51 | - } else { |
|
52 | - $lines = file($backtrace[2]['file']); |
|
53 | - preg_match_all('/([a-zA-Z0-9\_]+)::' . $backtrace[2]['function'] . '/', $lines[ $backtrace[2]['line']-1 ], $matches); |
|
54 | - if (isset($matches[1]) && isset($matches[1][ self::$i ])) { |
|
55 | - return $matches[1][ self::$i ]; |
|
56 | - } |
|
57 | - } |
|
58 | - } |
|
59 | - return false; |
|
60 | - } |
|
17 | + /** |
|
18 | + * get_called_class - for PHP versions < 5.3 |
|
19 | + * |
|
20 | + * @access public |
|
21 | + * @author origins: http://stackoverflow.com/a/1542045 |
|
22 | + * return string |
|
23 | + */ |
|
24 | + public static function get_called_class() |
|
25 | + { |
|
26 | + $backtrace = debug_backtrace(); |
|
27 | + if (isset($backtrace[2]) && is_array($backtrace[2]) && isset($backtrace[2]['class']) && ! isset($backtrace[2]['file'])) { |
|
28 | + return $backtrace[2]['class']; |
|
29 | + } elseif (isset($backtrace[3]) && is_array($backtrace[3]) && isset($backtrace[3]['class']) && ! isset($backtrace[3]['file'])) { |
|
30 | + return $backtrace[3]['class']; |
|
31 | + } elseif (isset($backtrace[2]) && is_array($backtrace[2]) && isset($backtrace[2]['file']) && isset($backtrace[2]['line'])) { |
|
32 | + if (self::$file_line == $backtrace[2]['file'] . $backtrace[2]['line']) { |
|
33 | + self::$i++; |
|
34 | + } else { |
|
35 | + self::$i = 0; |
|
36 | + self::$file_line = $backtrace[2]['file'] . $backtrace[2]['line']; |
|
37 | + } |
|
38 | + // was class method called via call_user_func ? |
|
39 | + if ($backtrace[2]['function'] == 'call_user_func' && isset($backtrace[2]['args']) && is_array($backtrace[2]['args'])) { |
|
40 | + if (isset($backtrace[2]['args'][0]) && isset($backtrace[2]['args'][0][0])) { |
|
41 | + $called_class = $backtrace[2]['args'][0][0]; |
|
42 | + // is it an EE function ? |
|
43 | + if (strpos($called_class, 'EE') === 0) { |
|
44 | + $prefix_chars = strpos($called_class, '_') + 1; |
|
45 | + $prefix = substr($called_class, 0, $prefix_chars); |
|
46 | + $classname = substr($called_class, $prefix_chars, strlen($called_class)); |
|
47 | + $classname = $prefix . str_replace(' ', '_', ucwords(strtolower(str_replace('_', ' ', $classname)))); |
|
48 | + return $classname; |
|
49 | + } |
|
50 | + } |
|
51 | + } else { |
|
52 | + $lines = file($backtrace[2]['file']); |
|
53 | + preg_match_all('/([a-zA-Z0-9\_]+)::' . $backtrace[2]['function'] . '/', $lines[ $backtrace[2]['line']-1 ], $matches); |
|
54 | + if (isset($matches[1]) && isset($matches[1][ self::$i ])) { |
|
55 | + return $matches[1][ self::$i ]; |
|
56 | + } |
|
57 | + } |
|
58 | + } |
|
59 | + return false; |
|
60 | + } |
|
61 | 61 | |
62 | 62 | |
63 | 63 | |
64 | 64 | |
65 | - /** |
|
66 | - * get_class_names_for_all_callbacks_on_hook |
|
67 | - * returns an array of names for all classes that have methods registered as callbacks for the given action or filter hook |
|
68 | - * @access public |
|
69 | - * @param string $hook |
|
70 | - * @return array |
|
71 | - */ |
|
72 | - public static function get_class_names_for_all_callbacks_on_hook($hook = null) |
|
73 | - { |
|
74 | - global $wp_filter; |
|
75 | - $class_names = array(); |
|
76 | - // are any callbacks registered for this hook ? |
|
77 | - if (isset($wp_filter[ $hook ])) { |
|
78 | - // loop thru all of the callbacks attached to the deprecated hookpoint |
|
79 | - foreach ($wp_filter[ $hook ] as $priority) { |
|
80 | - foreach ($priority as $callback) { |
|
81 | - // is the callback a non-static class method ? |
|
82 | - if (isset($callback['function']) && is_array($callback['function'])) { |
|
83 | - if (isset($callback['function'][0]) && is_object($callback['function'][0])) { |
|
84 | - $class_names[] = get_class($callback['function'][0]); |
|
85 | - } |
|
86 | - // test for static method |
|
87 | - } elseif (strpos($callback['function'], '::') !== false) { |
|
88 | - $class = explode('::', $callback['function']); |
|
89 | - $class_names[] = $class[0]; |
|
90 | - } else { |
|
91 | - // just a function |
|
92 | - } |
|
93 | - } |
|
94 | - } |
|
95 | - } |
|
96 | - return $class_names; |
|
97 | - } |
|
65 | + /** |
|
66 | + * get_class_names_for_all_callbacks_on_hook |
|
67 | + * returns an array of names for all classes that have methods registered as callbacks for the given action or filter hook |
|
68 | + * @access public |
|
69 | + * @param string $hook |
|
70 | + * @return array |
|
71 | + */ |
|
72 | + public static function get_class_names_for_all_callbacks_on_hook($hook = null) |
|
73 | + { |
|
74 | + global $wp_filter; |
|
75 | + $class_names = array(); |
|
76 | + // are any callbacks registered for this hook ? |
|
77 | + if (isset($wp_filter[ $hook ])) { |
|
78 | + // loop thru all of the callbacks attached to the deprecated hookpoint |
|
79 | + foreach ($wp_filter[ $hook ] as $priority) { |
|
80 | + foreach ($priority as $callback) { |
|
81 | + // is the callback a non-static class method ? |
|
82 | + if (isset($callback['function']) && is_array($callback['function'])) { |
|
83 | + if (isset($callback['function'][0]) && is_object($callback['function'][0])) { |
|
84 | + $class_names[] = get_class($callback['function'][0]); |
|
85 | + } |
|
86 | + // test for static method |
|
87 | + } elseif (strpos($callback['function'], '::') !== false) { |
|
88 | + $class = explode('::', $callback['function']); |
|
89 | + $class_names[] = $class[0]; |
|
90 | + } else { |
|
91 | + // just a function |
|
92 | + } |
|
93 | + } |
|
94 | + } |
|
95 | + } |
|
96 | + return $class_names; |
|
97 | + } |
|
98 | 98 | |
99 | 99 | |
100 | 100 | |
101 | 101 | |
102 | - /** |
|
103 | - * property_exists() with fallback for PHP versions < 5.3 |
|
104 | - * @access public |
|
105 | - * @param mixed object | string $class |
|
106 | - * @param string $property |
|
107 | - * @return boolean |
|
108 | - */ |
|
109 | - public static function has_property($class = null, $property = null) |
|
110 | - { |
|
111 | - // if $class or $property don't exist, then get out, cuz that would be like... fatal dude |
|
112 | - if (empty($class) || empty($property)) { |
|
113 | - return false; |
|
114 | - } |
|
115 | - // if your hosting company doesn't cut the mustard |
|
116 | - if (version_compare(PHP_VERSION, '5.3.0') < 0) { |
|
117 | - // just in case $class is an actual instantiated object |
|
118 | - if (is_object($class)) { |
|
119 | - return isset($class->{$property}) ? true : false; |
|
120 | - } else { |
|
121 | - // use reflection for < PHP 5.3 to get details using just the class name |
|
122 | - $reflector = new ReflectionClass($class); |
|
123 | - return $reflector->hasProperty($property); |
|
124 | - } |
|
125 | - } else { |
|
126 | - // or try regular property exists method which works as expected in PHP 5.3+ |
|
127 | - return property_exists($class, $property); |
|
128 | - } |
|
129 | - } |
|
102 | + /** |
|
103 | + * property_exists() with fallback for PHP versions < 5.3 |
|
104 | + * @access public |
|
105 | + * @param mixed object | string $class |
|
106 | + * @param string $property |
|
107 | + * @return boolean |
|
108 | + */ |
|
109 | + public static function has_property($class = null, $property = null) |
|
110 | + { |
|
111 | + // if $class or $property don't exist, then get out, cuz that would be like... fatal dude |
|
112 | + if (empty($class) || empty($property)) { |
|
113 | + return false; |
|
114 | + } |
|
115 | + // if your hosting company doesn't cut the mustard |
|
116 | + if (version_compare(PHP_VERSION, '5.3.0') < 0) { |
|
117 | + // just in case $class is an actual instantiated object |
|
118 | + if (is_object($class)) { |
|
119 | + return isset($class->{$property}) ? true : false; |
|
120 | + } else { |
|
121 | + // use reflection for < PHP 5.3 to get details using just the class name |
|
122 | + $reflector = new ReflectionClass($class); |
|
123 | + return $reflector->hasProperty($property); |
|
124 | + } |
|
125 | + } else { |
|
126 | + // or try regular property exists method which works as expected in PHP 5.3+ |
|
127 | + return property_exists($class, $property); |
|
128 | + } |
|
129 | + } |
|
130 | 130 | } |
131 | 131 | |
132 | 132 | // if PHP version < 5.3 |
133 | 133 | if (! function_exists('get_called_class')) { |
134 | - /** |
|
135 | - * @return string |
|
136 | - */ |
|
137 | - function get_called_class() |
|
138 | - { |
|
139 | - return EEH_Class_Tools::get_called_class(); |
|
140 | - } |
|
134 | + /** |
|
135 | + * @return string |
|
136 | + */ |
|
137 | + function get_called_class() |
|
138 | + { |
|
139 | + return EEH_Class_Tools::get_called_class(); |
|
140 | + } |
|
141 | 141 | } |
@@ -29,11 +29,11 @@ discard block |
||
29 | 29 | } elseif (isset($backtrace[3]) && is_array($backtrace[3]) && isset($backtrace[3]['class']) && ! isset($backtrace[3]['file'])) { |
30 | 30 | return $backtrace[3]['class']; |
31 | 31 | } elseif (isset($backtrace[2]) && is_array($backtrace[2]) && isset($backtrace[2]['file']) && isset($backtrace[2]['line'])) { |
32 | - if (self::$file_line == $backtrace[2]['file'] . $backtrace[2]['line']) { |
|
32 | + if (self::$file_line == $backtrace[2]['file'].$backtrace[2]['line']) { |
|
33 | 33 | self::$i++; |
34 | 34 | } else { |
35 | 35 | self::$i = 0; |
36 | - self::$file_line = $backtrace[2]['file'] . $backtrace[2]['line']; |
|
36 | + self::$file_line = $backtrace[2]['file'].$backtrace[2]['line']; |
|
37 | 37 | } |
38 | 38 | // was class method called via call_user_func ? |
39 | 39 | if ($backtrace[2]['function'] == 'call_user_func' && isset($backtrace[2]['args']) && is_array($backtrace[2]['args'])) { |
@@ -44,15 +44,15 @@ discard block |
||
44 | 44 | $prefix_chars = strpos($called_class, '_') + 1; |
45 | 45 | $prefix = substr($called_class, 0, $prefix_chars); |
46 | 46 | $classname = substr($called_class, $prefix_chars, strlen($called_class)); |
47 | - $classname = $prefix . str_replace(' ', '_', ucwords(strtolower(str_replace('_', ' ', $classname)))); |
|
47 | + $classname = $prefix.str_replace(' ', '_', ucwords(strtolower(str_replace('_', ' ', $classname)))); |
|
48 | 48 | return $classname; |
49 | 49 | } |
50 | 50 | } |
51 | 51 | } else { |
52 | 52 | $lines = file($backtrace[2]['file']); |
53 | - preg_match_all('/([a-zA-Z0-9\_]+)::' . $backtrace[2]['function'] . '/', $lines[ $backtrace[2]['line']-1 ], $matches); |
|
54 | - if (isset($matches[1]) && isset($matches[1][ self::$i ])) { |
|
55 | - return $matches[1][ self::$i ]; |
|
53 | + preg_match_all('/([a-zA-Z0-9\_]+)::'.$backtrace[2]['function'].'/', $lines[$backtrace[2]['line'] - 1], $matches); |
|
54 | + if (isset($matches[1]) && isset($matches[1][self::$i])) { |
|
55 | + return $matches[1][self::$i]; |
|
56 | 56 | } |
57 | 57 | } |
58 | 58 | } |
@@ -74,9 +74,9 @@ discard block |
||
74 | 74 | global $wp_filter; |
75 | 75 | $class_names = array(); |
76 | 76 | // are any callbacks registered for this hook ? |
77 | - if (isset($wp_filter[ $hook ])) { |
|
77 | + if (isset($wp_filter[$hook])) { |
|
78 | 78 | // loop thru all of the callbacks attached to the deprecated hookpoint |
79 | - foreach ($wp_filter[ $hook ] as $priority) { |
|
79 | + foreach ($wp_filter[$hook] as $priority) { |
|
80 | 80 | foreach ($priority as $callback) { |
81 | 81 | // is the callback a non-static class method ? |
82 | 82 | if (isset($callback['function']) && is_array($callback['function'])) { |
@@ -130,7 +130,7 @@ discard block |
||
130 | 130 | } |
131 | 131 | |
132 | 132 | // if PHP version < 5.3 |
133 | -if (! function_exists('get_called_class')) { |
|
133 | +if ( ! function_exists('get_called_class')) { |
|
134 | 134 | /** |
135 | 135 | * @return string |
136 | 136 | */ |
@@ -13,70 +13,70 @@ |
||
13 | 13 | { |
14 | 14 | |
15 | 15 | |
16 | - /** |
|
17 | - * $CPT - the current page, if it utilizes CPTs |
|
18 | - * |
|
19 | - * @var object |
|
20 | - * @access protected |
|
21 | - */ |
|
22 | - protected $CPT = null; |
|
16 | + /** |
|
17 | + * $CPT - the current page, if it utilizes CPTs |
|
18 | + * |
|
19 | + * @var object |
|
20 | + * @access protected |
|
21 | + */ |
|
22 | + protected $CPT = null; |
|
23 | 23 | |
24 | 24 | |
25 | - /** |
|
26 | - * class constructor |
|
27 | - * |
|
28 | - * @access private |
|
29 | - * @param array $arguments |
|
30 | - * @return \EE_CPT_Default_Strategy |
|
31 | - */ |
|
32 | - public function __construct($arguments = array()) |
|
33 | - { |
|
34 | - $this->CPT = isset($arguments['CPT']) ? $arguments['CPT'] : null; |
|
35 | - } |
|
25 | + /** |
|
26 | + * class constructor |
|
27 | + * |
|
28 | + * @access private |
|
29 | + * @param array $arguments |
|
30 | + * @return \EE_CPT_Default_Strategy |
|
31 | + */ |
|
32 | + public function __construct($arguments = array()) |
|
33 | + { |
|
34 | + $this->CPT = isset($arguments['CPT']) ? $arguments['CPT'] : null; |
|
35 | + } |
|
36 | 36 | |
37 | 37 | |
38 | - /** |
|
39 | - * pre_get_posts |
|
40 | - * |
|
41 | - * @access public |
|
42 | - * @param \WP_Query $WP_Query |
|
43 | - * @return \WP_Query |
|
44 | - */ |
|
45 | - public function pre_get_posts(WP_Query $WP_Query) |
|
46 | - { |
|
47 | - if (! $WP_Query->is_main_query() && ! $WP_Query->is_archive()) { |
|
48 | - return $WP_Query; |
|
49 | - } |
|
50 | - return $WP_Query; |
|
51 | - } |
|
38 | + /** |
|
39 | + * pre_get_posts |
|
40 | + * |
|
41 | + * @access public |
|
42 | + * @param \WP_Query $WP_Query |
|
43 | + * @return \WP_Query |
|
44 | + */ |
|
45 | + public function pre_get_posts(WP_Query $WP_Query) |
|
46 | + { |
|
47 | + if (! $WP_Query->is_main_query() && ! $WP_Query->is_archive()) { |
|
48 | + return $WP_Query; |
|
49 | + } |
|
50 | + return $WP_Query; |
|
51 | + } |
|
52 | 52 | |
53 | 53 | |
54 | - /** |
|
55 | - * wp |
|
56 | - * |
|
57 | - * @access public |
|
58 | - * @param \WP_Post[] $posts |
|
59 | - * @param \WP_Query $WP_Query |
|
60 | - * @return \WP_Post[] |
|
61 | - */ |
|
62 | - public function the_posts($posts, WP_Query $WP_Query) |
|
63 | - { |
|
64 | - return $posts; |
|
65 | - } |
|
54 | + /** |
|
55 | + * wp |
|
56 | + * |
|
57 | + * @access public |
|
58 | + * @param \WP_Post[] $posts |
|
59 | + * @param \WP_Query $WP_Query |
|
60 | + * @return \WP_Post[] |
|
61 | + */ |
|
62 | + public function the_posts($posts, WP_Query $WP_Query) |
|
63 | + { |
|
64 | + return $posts; |
|
65 | + } |
|
66 | 66 | |
67 | 67 | |
68 | - /** |
|
69 | - * get_EE_post_type_metadata |
|
70 | - * |
|
71 | - * @access public |
|
72 | - * @param mixed $meta_value |
|
73 | - * @param int $post_id |
|
74 | - * @param string $meta_key |
|
75 | - * @param string $single |
|
76 | - * @return mixed |
|
77 | - */ |
|
78 | - public function get_EE_post_type_metadata($meta_value = null, $post_id, $meta_key, $single) |
|
79 | - { |
|
80 | - return $meta_value; |
|
81 | - } |
|
68 | + /** |
|
69 | + * get_EE_post_type_metadata |
|
70 | + * |
|
71 | + * @access public |
|
72 | + * @param mixed $meta_value |
|
73 | + * @param int $post_id |
|
74 | + * @param string $meta_key |
|
75 | + * @param string $single |
|
76 | + * @return mixed |
|
77 | + */ |
|
78 | + public function get_EE_post_type_metadata($meta_value = null, $post_id, $meta_key, $single) |
|
79 | + { |
|
80 | + return $meta_value; |
|
81 | + } |
|
82 | 82 | } |
@@ -44,7 +44,7 @@ |
||
44 | 44 | */ |
45 | 45 | public function pre_get_posts(WP_Query $WP_Query) |
46 | 46 | { |
47 | - if (! $WP_Query->is_main_query() && ! $WP_Query->is_archive()) { |
|
47 | + if ( ! $WP_Query->is_main_query() && ! $WP_Query->is_archive()) { |
|
48 | 48 | return $WP_Query; |
49 | 49 | } |
50 | 50 | return $WP_Query; |
@@ -24,39 +24,39 @@ |
||
24 | 24 | class EE_CPT_Attendee_Strategy |
25 | 25 | { |
26 | 26 | |
27 | - /** |
|
28 | - * $CPT - the current page, if it utilizes CPTs |
|
29 | - * |
|
30 | - * @var array |
|
31 | - * @access protected |
|
32 | - */ |
|
33 | - protected $CPT = null; |
|
27 | + /** |
|
28 | + * $CPT - the current page, if it utilizes CPTs |
|
29 | + * |
|
30 | + * @var array |
|
31 | + * @access protected |
|
32 | + */ |
|
33 | + protected $CPT = null; |
|
34 | 34 | |
35 | 35 | |
36 | - /** |
|
37 | - * class constructor |
|
38 | - * |
|
39 | - * @access public |
|
40 | - * @param array $arguments |
|
41 | - * @return \EE_CPT_Attendee_Strategy |
|
42 | - */ |
|
43 | - public function __construct($arguments = array()) |
|
44 | - { |
|
45 | - $this->CPT = isset($arguments['CPT']) ? $arguments['CPT'] : null; |
|
46 | - $WP_Query = isset($arguments['WP_Query']) ? $arguments['WP_Query'] : null; |
|
47 | - } |
|
36 | + /** |
|
37 | + * class constructor |
|
38 | + * |
|
39 | + * @access public |
|
40 | + * @param array $arguments |
|
41 | + * @return \EE_CPT_Attendee_Strategy |
|
42 | + */ |
|
43 | + public function __construct($arguments = array()) |
|
44 | + { |
|
45 | + $this->CPT = isset($arguments['CPT']) ? $arguments['CPT'] : null; |
|
46 | + $WP_Query = isset($arguments['WP_Query']) ? $arguments['WP_Query'] : null; |
|
47 | + } |
|
48 | 48 | |
49 | 49 | |
50 | - /** |
|
51 | - * the_posts |
|
52 | - * |
|
53 | - * @access public |
|
54 | - * @param $posts |
|
55 | - * @param WP_Query $wp_query |
|
56 | - * @return void |
|
57 | - */ |
|
58 | - public function the_posts($posts, WP_Query $wp_query) |
|
59 | - { |
|
60 | - return $posts; |
|
61 | - } |
|
50 | + /** |
|
51 | + * the_posts |
|
52 | + * |
|
53 | + * @access public |
|
54 | + * @param $posts |
|
55 | + * @param WP_Query $wp_query |
|
56 | + * @return void |
|
57 | + */ |
|
58 | + public function the_posts($posts, WP_Query $wp_query) |
|
59 | + { |
|
60 | + return $posts; |
|
61 | + } |
|
62 | 62 | } |
@@ -12,54 +12,54 @@ |
||
12 | 12 | class EE_CPT_Venue_Strategy |
13 | 13 | { |
14 | 14 | |
15 | - /** |
|
16 | - * $CPT - the current page, if it utilizes CPTs |
|
17 | - * |
|
18 | - * @var array |
|
19 | - * @access protected |
|
20 | - */ |
|
21 | - protected $CPT = null; |
|
15 | + /** |
|
16 | + * $CPT - the current page, if it utilizes CPTs |
|
17 | + * |
|
18 | + * @var array |
|
19 | + * @access protected |
|
20 | + */ |
|
21 | + protected $CPT = null; |
|
22 | 22 | |
23 | 23 | |
24 | - /** |
|
25 | - * class constructor |
|
26 | - * |
|
27 | - * @access public |
|
28 | - * @param array $arguments |
|
29 | - * @return \EE_CPT_Venue_Strategy |
|
30 | - */ |
|
31 | - public function __construct($arguments = array()) |
|
32 | - { |
|
33 | - $this->CPT = isset($arguments['CPT']) ? $arguments['CPT'] : null; |
|
34 | - $WP_Query = isset($arguments['WP_Query']) ? $arguments['WP_Query'] : null; |
|
35 | - if ($WP_Query instanceof WP_Query && ! $WP_Query->is_tag) { |
|
36 | - $WP_Query->is_espresso_venue_single = is_singular() |
|
37 | - && isset($WP_Query->query->post_type) |
|
38 | - && $WP_Query->query->post_type == 'espresso_venues'; |
|
39 | - $WP_Query->is_espresso_venue_archive = is_post_type_archive('espresso_venues') ? true : false; |
|
40 | - $WP_Query->is_espresso_venue_taxonomy = is_tax('espresso_venue_categories') ? true : false; |
|
41 | - } |
|
42 | - add_filter('the_posts', array($this, 'the_posts'), 1, 2); |
|
43 | - } |
|
24 | + /** |
|
25 | + * class constructor |
|
26 | + * |
|
27 | + * @access public |
|
28 | + * @param array $arguments |
|
29 | + * @return \EE_CPT_Venue_Strategy |
|
30 | + */ |
|
31 | + public function __construct($arguments = array()) |
|
32 | + { |
|
33 | + $this->CPT = isset($arguments['CPT']) ? $arguments['CPT'] : null; |
|
34 | + $WP_Query = isset($arguments['WP_Query']) ? $arguments['WP_Query'] : null; |
|
35 | + if ($WP_Query instanceof WP_Query && ! $WP_Query->is_tag) { |
|
36 | + $WP_Query->is_espresso_venue_single = is_singular() |
|
37 | + && isset($WP_Query->query->post_type) |
|
38 | + && $WP_Query->query->post_type == 'espresso_venues'; |
|
39 | + $WP_Query->is_espresso_venue_archive = is_post_type_archive('espresso_venues') ? true : false; |
|
40 | + $WP_Query->is_espresso_venue_taxonomy = is_tax('espresso_venue_categories') ? true : false; |
|
41 | + } |
|
42 | + add_filter('the_posts', array($this, 'the_posts'), 1, 2); |
|
43 | + } |
|
44 | 44 | |
45 | 45 | |
46 | - /** |
|
47 | - * the_posts |
|
48 | - * |
|
49 | - * @access public |
|
50 | - * @param $posts |
|
51 | - * @param WP_Query $wp_query |
|
52 | - * @return void |
|
53 | - */ |
|
54 | - public function the_posts($posts, WP_Query $wp_query) |
|
55 | - { |
|
56 | - // automagically load the EEH_Venue_View helper so that it's functions are available |
|
57 | - if (isset(EE_Registry::instance()->CFG->map_settings->use_google_maps) |
|
58 | - && EE_Registry::instance()->CFG->map_settings->use_google_maps |
|
59 | - ) { |
|
60 | - EEH_Maps::espresso_google_map_js(); |
|
61 | - } |
|
62 | - remove_filter('the_posts', array($this, 'the_posts'), 1, 2); |
|
63 | - return $posts; |
|
64 | - } |
|
46 | + /** |
|
47 | + * the_posts |
|
48 | + * |
|
49 | + * @access public |
|
50 | + * @param $posts |
|
51 | + * @param WP_Query $wp_query |
|
52 | + * @return void |
|
53 | + */ |
|
54 | + public function the_posts($posts, WP_Query $wp_query) |
|
55 | + { |
|
56 | + // automagically load the EEH_Venue_View helper so that it's functions are available |
|
57 | + if (isset(EE_Registry::instance()->CFG->map_settings->use_google_maps) |
|
58 | + && EE_Registry::instance()->CFG->map_settings->use_google_maps |
|
59 | + ) { |
|
60 | + EEH_Maps::espresso_google_map_js(); |
|
61 | + } |
|
62 | + remove_filter('the_posts', array($this, 'the_posts'), 1, 2); |
|
63 | + return $posts; |
|
64 | + } |
|
65 | 65 | } |
@@ -33,7 +33,7 @@ discard block |
||
33 | 33 | public static function instance() |
34 | 34 | { |
35 | 35 | // check if class object is instantiated |
36 | - if (! self::$_instance instanceof EE_Payment_Processor) { |
|
36 | + if ( ! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | 37 | self::$_instance = new self(); |
38 | 38 | } |
39 | 39 | return self::$_instance; |
@@ -170,7 +170,7 @@ discard block |
||
170 | 170 | /** @type \EE_Transaction $transaction */ |
171 | 171 | $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
172 | 172 | $primary_reg = $transaction->primary_registration(); |
173 | - if (! $primary_reg instanceof EE_Registration) { |
|
173 | + if ( ! $primary_reg instanceof EE_Registration) { |
|
174 | 174 | throw new EE_Error( |
175 | 175 | sprintf( |
176 | 176 | __( |
@@ -265,7 +265,7 @@ discard block |
||
265 | 265 | EEM_Change_Log::instance()->log( |
266 | 266 | EEM_Change_Log::type_gateway, |
267 | 267 | array( |
268 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
268 | + 'message' => 'IPN Exception: '.$e->getMessage(), |
|
269 | 269 | 'current_url' => EEH_URL::current_url(), |
270 | 270 | 'payment' => $e->getPaymentProperties(), |
271 | 271 | 'IPN_data' => $e->getIpnData(), |
@@ -309,7 +309,7 @@ discard block |
||
309 | 309 | EEM_Change_Log::instance()->log( |
310 | 310 | EEM_Change_Log::type_gateway, |
311 | 311 | array( |
312 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
312 | + 'message' => 'IPN Exception: '.$e->getMessage(), |
|
313 | 313 | 'current_url' => EEH_URL::current_url(), |
314 | 314 | 'payment' => $e->getPaymentProperties(), |
315 | 315 | 'IPN_data' => $e->getIpnData(), |
@@ -380,7 +380,7 @@ discard block |
||
380 | 380 | { |
381 | 381 | $return_data = array(); |
382 | 382 | foreach ($request_data as $key => $value) { |
383 | - $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
383 | + $return_data[$this->_remove_unusable_characters($key)] = $this->_remove_unusable_characters( |
|
384 | 384 | $value |
385 | 385 | ); |
386 | 386 | } |
@@ -18,842 +18,842 @@ |
||
18 | 18 | class EE_Payment_Processor extends EE_Processor_Base implements ResettableInterface |
19 | 19 | { |
20 | 20 | |
21 | - /** |
|
22 | - * @var EE_Payment_Processor $_instance |
|
23 | - * @access private |
|
24 | - */ |
|
25 | - private static $_instance; |
|
26 | - |
|
27 | - |
|
28 | - /** |
|
29 | - * @singleton method used to instantiate class object |
|
30 | - * @access public |
|
31 | - * @return EE_Payment_Processor instance |
|
32 | - */ |
|
33 | - public static function instance() |
|
34 | - { |
|
35 | - // check if class object is instantiated |
|
36 | - if (! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | - self::$_instance = new self(); |
|
38 | - } |
|
39 | - return self::$_instance; |
|
40 | - } |
|
41 | - |
|
42 | - |
|
43 | - /** |
|
44 | - * @return EE_Payment_Processor |
|
45 | - */ |
|
46 | - public static function reset() |
|
47 | - { |
|
48 | - self::$_instance = null; |
|
49 | - return self::instance(); |
|
50 | - } |
|
51 | - |
|
52 | - |
|
53 | - /** |
|
54 | - *private constructor to prevent direct creation |
|
55 | - * |
|
56 | - * @Constructor |
|
57 | - * @access private |
|
58 | - */ |
|
59 | - private function __construct() |
|
60 | - { |
|
61 | - do_action('AHEE__EE_Payment_Processor__construct'); |
|
62 | - add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
63 | - } |
|
64 | - |
|
65 | - |
|
66 | - /** |
|
67 | - * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
68 | - * appropriately. Saves the payment that is generated |
|
69 | - * |
|
70 | - * @param EE_Payment_Method $payment_method |
|
71 | - * @param EE_Transaction $transaction |
|
72 | - * @param float $amount if only part of the transaction is to be paid for, how much. |
|
73 | - * Leave null if payment is for the full amount owing |
|
74 | - * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
75 | - * Receive_form_submission() should have |
|
76 | - * already been called on the billing form |
|
77 | - * (ie, its inputs should have their normalized values set). |
|
78 | - * @param string $return_url string used mostly by offsite gateways to specify |
|
79 | - * where to go AFTER the offsite gateway |
|
80 | - * @param string $method like 'CART', indicates who the client who called this was |
|
81 | - * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
82 | - * @param boolean $update_txn whether or not to call |
|
83 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
84 | - * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
85 | - * @return EE_Payment |
|
86 | - * @throws EE_Error |
|
87 | - * @throws InvalidArgumentException |
|
88 | - * @throws ReflectionException |
|
89 | - * @throws RuntimeException |
|
90 | - * @throws InvalidDataTypeException |
|
91 | - * @throws InvalidInterfaceException |
|
92 | - */ |
|
93 | - public function process_payment( |
|
94 | - EE_Payment_Method $payment_method, |
|
95 | - EE_Transaction $transaction, |
|
96 | - $amount = null, |
|
97 | - $billing_form = null, |
|
98 | - $return_url = null, |
|
99 | - $method = 'CART', |
|
100 | - $by_admin = false, |
|
101 | - $update_txn = true, |
|
102 | - $cancel_url = '' |
|
103 | - ) { |
|
104 | - if ((float) $amount < 0) { |
|
105 | - throw new EE_Error( |
|
106 | - sprintf( |
|
107 | - __( |
|
108 | - 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
109 | - 'event_espresso' |
|
110 | - ), |
|
111 | - $amount, |
|
112 | - $transaction->ID() |
|
113 | - ) |
|
114 | - ); |
|
115 | - } |
|
116 | - // verify payment method |
|
117 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
118 | - $payment_method, |
|
119 | - true |
|
120 | - ); |
|
121 | - // verify transaction |
|
122 | - EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
123 | - $transaction->set_payment_method_ID($payment_method->ID()); |
|
124 | - // verify payment method type |
|
125 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
126 | - $payment = $payment_method->type_obj()->process_payment( |
|
127 | - $transaction, |
|
128 | - min($amount, $transaction->remaining()), // make sure we don't overcharge |
|
129 | - $billing_form, |
|
130 | - $return_url, |
|
131 | - add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
132 | - $method, |
|
133 | - $by_admin |
|
134 | - ); |
|
135 | - // check if payment method uses an off-site gateway |
|
136 | - if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
137 | - // don't process payments for off-site gateways yet because no payment has occurred yet |
|
138 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
139 | - } |
|
140 | - return $payment; |
|
141 | - } |
|
142 | - EE_Error::add_error( |
|
143 | - sprintf( |
|
144 | - __( |
|
145 | - 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
146 | - 'event_espresso' |
|
147 | - ), |
|
148 | - '<br/>', |
|
149 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
150 | - ), |
|
151 | - __FILE__, |
|
152 | - __FUNCTION__, |
|
153 | - __LINE__ |
|
154 | - ); |
|
155 | - return null; |
|
156 | - } |
|
157 | - |
|
158 | - |
|
159 | - /** |
|
160 | - * @param EE_Transaction|int $transaction |
|
161 | - * @param EE_Payment_Method $payment_method |
|
162 | - * @return string |
|
163 | - * @throws EE_Error |
|
164 | - * @throws InvalidArgumentException |
|
165 | - * @throws InvalidDataTypeException |
|
166 | - * @throws InvalidInterfaceException |
|
167 | - */ |
|
168 | - public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
169 | - { |
|
170 | - /** @type \EE_Transaction $transaction */ |
|
171 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
172 | - $primary_reg = $transaction->primary_registration(); |
|
173 | - if (! $primary_reg instanceof EE_Registration) { |
|
174 | - throw new EE_Error( |
|
175 | - sprintf( |
|
176 | - __( |
|
177 | - 'Cannot get IPN URL for transaction with ID %d because it has no primary registration', |
|
178 | - 'event_espresso' |
|
179 | - ), |
|
180 | - $transaction->ID() |
|
181 | - ) |
|
182 | - ); |
|
183 | - } |
|
184 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
185 | - $payment_method, |
|
186 | - true |
|
187 | - ); |
|
188 | - $url = add_query_arg( |
|
189 | - array( |
|
190 | - 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
191 | - 'ee_payment_method' => $payment_method->slug(), |
|
192 | - ), |
|
193 | - EE_Registry::instance()->CFG->core->txn_page_url() |
|
194 | - ); |
|
195 | - return $url; |
|
196 | - } |
|
197 | - |
|
198 | - |
|
199 | - /** |
|
200 | - * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
201 | - * we can easily find what registration the IPN is for and what payment method. |
|
202 | - * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
203 | - * If a payment is found for the IPN info, it is saved. |
|
204 | - * |
|
205 | - * @param array $_req_data eg $_REQUEST |
|
206 | - * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
207 | - * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
208 | - * @param boolean $update_txn whether or not to call |
|
209 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
210 | - * @param bool $separate_IPN_request whether the IPN uses a separate request (true, like PayPal) |
|
211 | - * or is processed manually (false, like Authorize.net) |
|
212 | - * @throws EE_Error |
|
213 | - * @throws Exception |
|
214 | - * @return EE_Payment |
|
215 | - * @throws \RuntimeException |
|
216 | - * @throws \ReflectionException |
|
217 | - * @throws \InvalidArgumentException |
|
218 | - * @throws InvalidInterfaceException |
|
219 | - * @throws InvalidDataTypeException |
|
220 | - */ |
|
221 | - public function process_ipn( |
|
222 | - $_req_data, |
|
223 | - $transaction = null, |
|
224 | - $payment_method = null, |
|
225 | - $update_txn = true, |
|
226 | - $separate_IPN_request = true |
|
227 | - ) { |
|
228 | - EE_Registry::instance()->load_model('Change_Log'); |
|
229 | - $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data); |
|
230 | - EE_Processor_Base::set_IPN($separate_IPN_request); |
|
231 | - $obj_for_log = null; |
|
232 | - if ($transaction instanceof EE_Transaction) { |
|
233 | - $obj_for_log = $transaction; |
|
234 | - if ($payment_method instanceof EE_Payment_Method) { |
|
235 | - $obj_for_log = EEM_Payment::instance()->get_one( |
|
236 | - array( |
|
237 | - array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
238 | - 'order_by' => array('PAY_timestamp' => 'desc'), |
|
239 | - ) |
|
240 | - ); |
|
241 | - } |
|
242 | - } elseif ($payment_method instanceof EE_Payment) { |
|
243 | - $obj_for_log = $payment_method; |
|
244 | - } |
|
245 | - $log = EEM_Change_Log::instance()->log( |
|
246 | - EEM_Change_Log::type_gateway, |
|
247 | - array('IPN data received' => $_req_data), |
|
248 | - $obj_for_log |
|
249 | - ); |
|
250 | - try { |
|
251 | - /** |
|
252 | - * @var EE_Payment $payment |
|
253 | - */ |
|
254 | - $payment = null; |
|
255 | - if ($transaction && $payment_method) { |
|
256 | - /** @type EE_Transaction $transaction */ |
|
257 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
258 | - /** @type EE_Payment_Method $payment_method */ |
|
259 | - $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
260 | - if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
261 | - try { |
|
262 | - $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
263 | - $log->set_object($payment); |
|
264 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
265 | - EEM_Change_Log::instance()->log( |
|
266 | - EEM_Change_Log::type_gateway, |
|
267 | - array( |
|
268 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
269 | - 'current_url' => EEH_URL::current_url(), |
|
270 | - 'payment' => $e->getPaymentProperties(), |
|
271 | - 'IPN_data' => $e->getIpnData(), |
|
272 | - ), |
|
273 | - $obj_for_log |
|
274 | - ); |
|
275 | - return $e->getPayment(); |
|
276 | - } |
|
277 | - } else { |
|
278 | - // not a payment |
|
279 | - EE_Error::add_error( |
|
280 | - sprintf( |
|
281 | - __( |
|
282 | - 'A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', |
|
283 | - 'event_espresso' |
|
284 | - ), |
|
285 | - '<br/>', |
|
286 | - EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
287 | - ), |
|
288 | - __FILE__, |
|
289 | - __FUNCTION__, |
|
290 | - __LINE__ |
|
291 | - ); |
|
292 | - } |
|
293 | - } else { |
|
294 | - // that's actually pretty ok. The IPN just wasn't able |
|
295 | - // to identify which transaction or payment method this was for |
|
296 | - // give all active payment methods a chance to claim it |
|
297 | - $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
298 | - foreach ($active_payment_methods as $active_payment_method) { |
|
299 | - try { |
|
300 | - $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
301 | - $payment_method = $active_payment_method; |
|
302 | - EEM_Change_Log::instance()->log( |
|
303 | - EEM_Change_Log::type_gateway, |
|
304 | - array('IPN data' => $_req_data), |
|
305 | - $payment |
|
306 | - ); |
|
307 | - break; |
|
308 | - } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
309 | - EEM_Change_Log::instance()->log( |
|
310 | - EEM_Change_Log::type_gateway, |
|
311 | - array( |
|
312 | - 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
313 | - 'current_url' => EEH_URL::current_url(), |
|
314 | - 'payment' => $e->getPaymentProperties(), |
|
315 | - 'IPN_data' => $e->getIpnData(), |
|
316 | - ), |
|
317 | - $obj_for_log |
|
318 | - ); |
|
319 | - return $e->getPayment(); |
|
320 | - } catch (EE_Error $e) { |
|
321 | - // that's fine- it apparently couldn't handle the IPN |
|
322 | - } |
|
323 | - } |
|
324 | - } |
|
325 | - // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
326 | - if ($payment instanceof EE_Payment) { |
|
327 | - $payment->save(); |
|
328 | - // update the TXN |
|
329 | - $this->update_txn_based_on_payment( |
|
330 | - $transaction, |
|
331 | - $payment, |
|
332 | - $update_txn, |
|
333 | - $separate_IPN_request |
|
334 | - ); |
|
335 | - } else { |
|
336 | - // we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
337 | - if ($payment_method) { |
|
338 | - EEM_Change_Log::instance()->log( |
|
339 | - EEM_Change_Log::type_gateway, |
|
340 | - array('IPN data' => $_req_data), |
|
341 | - $payment_method |
|
342 | - ); |
|
343 | - } elseif ($transaction) { |
|
344 | - EEM_Change_Log::instance()->log( |
|
345 | - EEM_Change_Log::type_gateway, |
|
346 | - array('IPN data' => $_req_data), |
|
347 | - $transaction |
|
348 | - ); |
|
349 | - } |
|
350 | - } |
|
351 | - return $payment; |
|
352 | - } catch (EE_Error $e) { |
|
353 | - do_action( |
|
354 | - 'AHEE__log', |
|
355 | - __FILE__, |
|
356 | - __FUNCTION__, |
|
357 | - sprintf( |
|
358 | - __( |
|
359 | - 'Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', |
|
360 | - 'event_espresso' |
|
361 | - ), |
|
362 | - print_r($transaction, true), |
|
363 | - print_r($_req_data, true), |
|
364 | - $e->getMessage() |
|
365 | - ) |
|
366 | - ); |
|
367 | - throw $e; |
|
368 | - } |
|
369 | - } |
|
370 | - |
|
371 | - |
|
372 | - /** |
|
373 | - * Removes any non-printable illegal characters from the input, |
|
374 | - * which might cause a raucous when trying to insert into the database |
|
375 | - * |
|
376 | - * @param array $request_data |
|
377 | - * @return array |
|
378 | - */ |
|
379 | - protected function _remove_unusable_characters_from_array(array $request_data) |
|
380 | - { |
|
381 | - $return_data = array(); |
|
382 | - foreach ($request_data as $key => $value) { |
|
383 | - $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
384 | - $value |
|
385 | - ); |
|
386 | - } |
|
387 | - return $return_data; |
|
388 | - } |
|
389 | - |
|
390 | - |
|
391 | - /** |
|
392 | - * Removes any non-printable illegal characters from the input, |
|
393 | - * which might cause a raucous when trying to insert into the database |
|
394 | - * |
|
395 | - * @param string $request_data |
|
396 | - * @return string |
|
397 | - */ |
|
398 | - protected function _remove_unusable_characters($request_data) |
|
399 | - { |
|
400 | - return preg_replace('/[^[:print:]]/', '', $request_data); |
|
401 | - } |
|
402 | - |
|
403 | - |
|
404 | - /** |
|
405 | - * Should be called just before displaying the payment attempt results to the user, |
|
406 | - * when the payment attempt has finished. Some payment methods may have special |
|
407 | - * logic to perform here. For example, if process_payment() happens on a special request |
|
408 | - * and then the user is redirected to a page that displays the payment's status, this |
|
409 | - * should be called while loading the page that displays the payment's status. If the user is |
|
410 | - * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
411 | - * provider. |
|
412 | - * |
|
413 | - * @param EE_Transaction|int $transaction |
|
414 | - * @param bool $update_txn whether or not to call |
|
415 | - * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
416 | - * @return EE_Payment |
|
417 | - * @throws EE_Error |
|
418 | - * @throws InvalidArgumentException |
|
419 | - * @throws ReflectionException |
|
420 | - * @throws RuntimeException |
|
421 | - * @throws InvalidDataTypeException |
|
422 | - * @throws InvalidInterfaceException |
|
423 | - * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
424 | - * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
425 | - */ |
|
426 | - public function finalize_payment_for($transaction, $update_txn = true) |
|
427 | - { |
|
428 | - /** @var $transaction EE_Transaction */ |
|
429 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
430 | - $last_payment_method = $transaction->payment_method(); |
|
431 | - if ($last_payment_method instanceof EE_Payment_Method) { |
|
432 | - $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
433 | - $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
434 | - return $payment; |
|
435 | - } |
|
436 | - return null; |
|
437 | - } |
|
438 | - |
|
439 | - |
|
440 | - /** |
|
441 | - * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
442 | - * |
|
443 | - * @param EE_Payment_Method $payment_method |
|
444 | - * @param EE_Payment $payment_to_refund |
|
445 | - * @param array $refund_info |
|
446 | - * @return EE_Payment |
|
447 | - * @throws EE_Error |
|
448 | - * @throws InvalidArgumentException |
|
449 | - * @throws ReflectionException |
|
450 | - * @throws RuntimeException |
|
451 | - * @throws InvalidDataTypeException |
|
452 | - * @throws InvalidInterfaceException |
|
453 | - */ |
|
454 | - public function process_refund( |
|
455 | - EE_Payment_Method $payment_method, |
|
456 | - EE_Payment $payment_to_refund, |
|
457 | - array $refund_info = array() |
|
458 | - ) { |
|
459 | - if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
460 | - $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
461 | - $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
462 | - } |
|
463 | - return $payment_to_refund; |
|
464 | - } |
|
465 | - |
|
466 | - |
|
467 | - /** |
|
468 | - * This should be called each time there may have been an update to a |
|
469 | - * payment on a transaction (ie, we asked for a payment to process a |
|
470 | - * payment for a transaction, or we told a payment method about an IPN, or |
|
471 | - * we told a payment method to |
|
472 | - * "finalize_payment_for" (a transaction), or we told a payment method to |
|
473 | - * process a refund. This should handle firing the correct hooks to |
|
474 | - * indicate |
|
475 | - * what exactly happened and updating the transaction appropriately). This |
|
476 | - * could be integrated directly into EE_Transaction upon save, but we want |
|
477 | - * this logic to be separate from 'normal' plain-jane saving and updating |
|
478 | - * of transactions and payments, and to be tied to payment processing. |
|
479 | - * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
480 | - * of previous code to decide whether or not to save (because the payment passed into |
|
481 | - * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
482 | - * in which case we only want that payment object for some temporary usage during this request, |
|
483 | - * but we don't want it to be saved). |
|
484 | - * |
|
485 | - * @param EE_Transaction|int $transaction |
|
486 | - * @param EE_Payment $payment |
|
487 | - * @param boolean $update_txn |
|
488 | - * whether or not to call |
|
489 | - * EE_Transaction_Processor:: |
|
490 | - * update_transaction_and_registrations_after_checkout_or_payment() |
|
491 | - * (you can save 1 DB query if you know you're going |
|
492 | - * to save it later instead) |
|
493 | - * @param bool $IPN |
|
494 | - * if processing IPNs or other similar payment |
|
495 | - * related activities that occur in alternate |
|
496 | - * requests than the main one that is processing the |
|
497 | - * TXN, then set this to true to check whether the |
|
498 | - * TXN is locked before updating |
|
499 | - * @throws EE_Error |
|
500 | - * @throws InvalidArgumentException |
|
501 | - * @throws ReflectionException |
|
502 | - * @throws RuntimeException |
|
503 | - * @throws InvalidDataTypeException |
|
504 | - * @throws InvalidInterfaceException |
|
505 | - */ |
|
506 | - public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
507 | - { |
|
508 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
509 | - /** @type EE_Transaction $transaction */ |
|
510 | - $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
511 | - // can we freely update the TXN at this moment? |
|
512 | - if ($IPN && $transaction->is_locked()) { |
|
513 | - // don't update the transaction at this exact moment |
|
514 | - // because the TXN is active in another request |
|
515 | - EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
516 | - time(), |
|
517 | - $transaction->ID(), |
|
518 | - $payment->ID() |
|
519 | - ); |
|
520 | - } else { |
|
521 | - // verify payment and that it has been saved |
|
522 | - if ($payment instanceof EE_Payment && $payment->ID()) { |
|
523 | - if ($payment->payment_method() instanceof EE_Payment_Method |
|
524 | - && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
525 | - ) { |
|
526 | - $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
527 | - // update TXN registrations with payment info |
|
528 | - $this->process_registration_payments($transaction, $payment); |
|
529 | - } |
|
530 | - $do_action = $payment->just_approved() |
|
531 | - ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
532 | - : $do_action; |
|
533 | - } else { |
|
534 | - // send out notifications |
|
535 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
536 | - $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
537 | - } |
|
538 | - if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
539 | - /** @type EE_Transaction_Payments $transaction_payments */ |
|
540 | - $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
541 | - // set new value for total paid |
|
542 | - $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
543 | - // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
544 | - if ($update_txn) { |
|
545 | - $this->_post_payment_processing($transaction, $payment, $IPN); |
|
546 | - } |
|
547 | - } |
|
548 | - // granular hook for others to use. |
|
549 | - do_action($do_action, $transaction, $payment); |
|
550 | - do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
551 | - // global hook for others to use. |
|
552 | - do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
553 | - } |
|
554 | - } |
|
555 | - |
|
556 | - |
|
557 | - /** |
|
558 | - * update registrations REG_paid field after successful payment and link registrations with payment |
|
559 | - * |
|
560 | - * @param EE_Transaction $transaction |
|
561 | - * @param EE_Payment $payment |
|
562 | - * @param EE_Registration[] $registrations |
|
563 | - * @throws EE_Error |
|
564 | - * @throws InvalidArgumentException |
|
565 | - * @throws RuntimeException |
|
566 | - * @throws InvalidDataTypeException |
|
567 | - * @throws InvalidInterfaceException |
|
568 | - */ |
|
569 | - public function process_registration_payments( |
|
570 | - EE_Transaction $transaction, |
|
571 | - EE_Payment $payment, |
|
572 | - array $registrations = array() |
|
573 | - ) { |
|
574 | - // only process if payment was successful |
|
575 | - if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
576 | - return; |
|
577 | - } |
|
578 | - // EEM_Registration::instance()->show_next_x_db_queries(); |
|
579 | - if (empty($registrations)) { |
|
580 | - // find registrations with monies owing that can receive a payment |
|
581 | - $registrations = $transaction->registrations( |
|
582 | - array( |
|
583 | - array( |
|
584 | - // only these reg statuses can receive payments |
|
585 | - 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
586 | - 'REG_final_price' => array('!=', 0), |
|
587 | - 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
588 | - ), |
|
589 | - ) |
|
590 | - ); |
|
591 | - } |
|
592 | - // still nothing ??!?? |
|
593 | - if (empty($registrations)) { |
|
594 | - return; |
|
595 | - } |
|
596 | - // todo: break out the following logic into a separate strategy class |
|
597 | - // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
598 | - // todo: which would apply payments using the capitalist "first come first paid" approach |
|
599 | - // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
600 | - // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
601 | - // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
602 | - $refund = $payment->is_a_refund(); |
|
603 | - // how much is available to apply to registrations? |
|
604 | - $available_payment_amount = abs($payment->amount()); |
|
605 | - foreach ($registrations as $registration) { |
|
606 | - if ($registration instanceof EE_Registration) { |
|
607 | - // nothing left? |
|
608 | - if ($available_payment_amount <= 0) { |
|
609 | - break; |
|
610 | - } |
|
611 | - if ($refund) { |
|
612 | - $available_payment_amount = $this->process_registration_refund( |
|
613 | - $registration, |
|
614 | - $payment, |
|
615 | - $available_payment_amount |
|
616 | - ); |
|
617 | - } else { |
|
618 | - $available_payment_amount = $this->process_registration_payment( |
|
619 | - $registration, |
|
620 | - $payment, |
|
621 | - $available_payment_amount |
|
622 | - ); |
|
623 | - } |
|
624 | - } |
|
625 | - } |
|
626 | - if ($available_payment_amount > 0 |
|
627 | - && apply_filters( |
|
628 | - 'FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', |
|
629 | - false |
|
630 | - )) { |
|
631 | - EE_Error::add_attention( |
|
632 | - sprintf( |
|
633 | - __( |
|
634 | - 'A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
635 | - 'event_espresso' |
|
636 | - ), |
|
637 | - EEH_Template::format_currency($available_payment_amount), |
|
638 | - implode(', ', array_keys($registrations)), |
|
639 | - '<br/>', |
|
640 | - EEH_Template::format_currency($payment->amount()) |
|
641 | - ), |
|
642 | - __FILE__, |
|
643 | - __FUNCTION__, |
|
644 | - __LINE__ |
|
645 | - ); |
|
646 | - } |
|
647 | - } |
|
648 | - |
|
649 | - |
|
650 | - /** |
|
651 | - * update registration REG_paid field after successful payment and link registration with payment |
|
652 | - * |
|
653 | - * @param EE_Registration $registration |
|
654 | - * @param EE_Payment $payment |
|
655 | - * @param float $available_payment_amount |
|
656 | - * @return float |
|
657 | - * @throws EE_Error |
|
658 | - * @throws InvalidArgumentException |
|
659 | - * @throws RuntimeException |
|
660 | - * @throws InvalidDataTypeException |
|
661 | - * @throws InvalidInterfaceException |
|
662 | - */ |
|
663 | - public function process_registration_payment( |
|
664 | - EE_Registration $registration, |
|
665 | - EE_Payment $payment, |
|
666 | - $available_payment_amount = 0.00 |
|
667 | - ) { |
|
668 | - $owing = $registration->final_price() - $registration->paid(); |
|
669 | - if ($owing > 0) { |
|
670 | - // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
671 | - $payment_amount = min($available_payment_amount, $owing); |
|
672 | - // update $available_payment_amount |
|
673 | - $available_payment_amount -= $payment_amount; |
|
674 | - // calculate and set new REG_paid |
|
675 | - $registration->set_paid($registration->paid() + $payment_amount); |
|
676 | - // now save it |
|
677 | - $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
678 | - } |
|
679 | - return $available_payment_amount; |
|
680 | - } |
|
681 | - |
|
682 | - |
|
683 | - /** |
|
684 | - * update registration REG_paid field after successful payment and link registration with payment |
|
685 | - * |
|
686 | - * @param EE_Registration $registration |
|
687 | - * @param EE_Payment $payment |
|
688 | - * @param float $payment_amount |
|
689 | - * @return void |
|
690 | - * @throws EE_Error |
|
691 | - * @throws InvalidArgumentException |
|
692 | - * @throws InvalidDataTypeException |
|
693 | - * @throws InvalidInterfaceException |
|
694 | - */ |
|
695 | - protected function _apply_registration_payment( |
|
696 | - EE_Registration $registration, |
|
697 | - EE_Payment $payment, |
|
698 | - $payment_amount = 0.00 |
|
699 | - ) { |
|
700 | - // find any existing reg payment records for this registration and payment |
|
701 | - $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
702 | - array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
703 | - ); |
|
704 | - // if existing registration payment exists |
|
705 | - if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
706 | - // then update that record |
|
707 | - $existing_reg_payment->set_amount($payment_amount); |
|
708 | - $existing_reg_payment->save(); |
|
709 | - } else { |
|
710 | - // or add new relation between registration and payment and set amount |
|
711 | - $registration->_add_relation_to( |
|
712 | - $payment, |
|
713 | - 'Payment', |
|
714 | - array('RPY_amount' => $payment_amount) |
|
715 | - ); |
|
716 | - // make it stick |
|
717 | - $registration->save(); |
|
718 | - } |
|
719 | - } |
|
720 | - |
|
721 | - |
|
722 | - /** |
|
723 | - * update registration REG_paid field after refund and link registration with payment |
|
724 | - * |
|
725 | - * @param EE_Registration $registration |
|
726 | - * @param EE_Payment $payment |
|
727 | - * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
728 | - * @return float |
|
729 | - * @throws EE_Error |
|
730 | - * @throws InvalidArgumentException |
|
731 | - * @throws RuntimeException |
|
732 | - * @throws InvalidDataTypeException |
|
733 | - * @throws InvalidInterfaceException |
|
734 | - */ |
|
735 | - public function process_registration_refund( |
|
736 | - EE_Registration $registration, |
|
737 | - EE_Payment $payment, |
|
738 | - $available_refund_amount = 0.00 |
|
739 | - ) { |
|
740 | - // EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
741 | - if ($registration->paid() > 0) { |
|
742 | - // ensure $available_refund_amount is NOT negative |
|
743 | - $available_refund_amount = (float) abs($available_refund_amount); |
|
744 | - // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
745 | - $refund_amount = min($available_refund_amount, (float) $registration->paid()); |
|
746 | - // update $available_payment_amount |
|
747 | - $available_refund_amount -= $refund_amount; |
|
748 | - // calculate and set new REG_paid |
|
749 | - $registration->set_paid($registration->paid() - $refund_amount); |
|
750 | - // convert payment amount back to a negative value for storage in the db |
|
751 | - $refund_amount = (float) abs($refund_amount) * -1; |
|
752 | - // now save it |
|
753 | - $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
754 | - } |
|
755 | - return $available_refund_amount; |
|
756 | - } |
|
757 | - |
|
758 | - |
|
759 | - /** |
|
760 | - * Process payments and transaction after payment process completed. |
|
761 | - * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
762 | - * if this request happens to be processing an IPN, |
|
763 | - * then we will also set the Payment Options Reg Step to completed, |
|
764 | - * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
765 | - * |
|
766 | - * @param EE_Transaction $transaction |
|
767 | - * @param EE_Payment $payment |
|
768 | - * @param bool $IPN |
|
769 | - * @throws EE_Error |
|
770 | - * @throws InvalidArgumentException |
|
771 | - * @throws ReflectionException |
|
772 | - * @throws RuntimeException |
|
773 | - * @throws InvalidDataTypeException |
|
774 | - * @throws InvalidInterfaceException |
|
775 | - */ |
|
776 | - protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
777 | - { |
|
778 | - /** @type EE_Transaction_Processor $transaction_processor */ |
|
779 | - $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
780 | - // is the Payment Options Reg Step completed ? |
|
781 | - $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
782 | - // if the Payment Options Reg Step is completed... |
|
783 | - $revisit = $payment_options_step_completed === true; |
|
784 | - // then this is kinda sorta a revisit with regards to payments at least |
|
785 | - $transaction_processor->set_revisit($revisit); |
|
786 | - // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
787 | - if ($IPN |
|
788 | - && $payment_options_step_completed !== true |
|
789 | - && ($payment->is_approved() || $payment->is_pending()) |
|
790 | - ) { |
|
791 | - $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
792 | - 'payment_options' |
|
793 | - ); |
|
794 | - } |
|
795 | - // maybe update status, but don't save transaction just yet |
|
796 | - $transaction->update_status_based_on_total_paid(false); |
|
797 | - // check if 'finalize_registration' step has been completed... |
|
798 | - $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
799 | - // if this is an IPN and the final step has not been initiated |
|
800 | - if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
801 | - // and if it hasn't already been set as being started... |
|
802 | - $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
803 | - } |
|
804 | - $transaction->save(); |
|
805 | - // because the above will return false if the final step was not fully completed, we need to check again... |
|
806 | - if ($IPN && $finalized !== false) { |
|
807 | - // and if we are all good to go, then send out notifications |
|
808 | - add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
809 | - // ok, now process the transaction according to the payment |
|
810 | - $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
811 | - $transaction, |
|
812 | - $payment |
|
813 | - ); |
|
814 | - } |
|
815 | - // DEBUG LOG |
|
816 | - $payment_method = $payment->payment_method(); |
|
817 | - if ($payment_method instanceof EE_Payment_Method) { |
|
818 | - $payment_method_type_obj = $payment_method->type_obj(); |
|
819 | - if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
820 | - $gateway = $payment_method_type_obj->get_gateway(); |
|
821 | - if ($gateway instanceof EE_Gateway) { |
|
822 | - $gateway->log( |
|
823 | - array( |
|
824 | - 'message' => (string) __('Post Payment Transaction Details', 'event_espresso'), |
|
825 | - 'transaction' => $transaction->model_field_array(), |
|
826 | - 'finalized' => $finalized, |
|
827 | - 'IPN' => $IPN, |
|
828 | - 'deliver_notifications' => has_filter( |
|
829 | - 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
830 | - ), |
|
831 | - ), |
|
832 | - $payment |
|
833 | - ); |
|
834 | - } |
|
835 | - } |
|
836 | - } |
|
837 | - } |
|
838 | - |
|
839 | - |
|
840 | - /** |
|
841 | - * Force posts to PayPal to use TLS v1.2. See: |
|
842 | - * https://core.trac.wordpress.org/ticket/36320 |
|
843 | - * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
844 | - * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
845 | - * This will affect PayPal standard, pro, express, and Payflow. |
|
846 | - * |
|
847 | - * @param $handle |
|
848 | - * @param $r |
|
849 | - * @param $url |
|
850 | - */ |
|
851 | - public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
852 | - { |
|
853 | - if (strpos($url, 'https://') !== false && strpos($url, '.paypal.com') !== false) { |
|
854 | - // Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
855 | - // instead of the constant because it might not be defined |
|
856 | - curl_setopt($handle, CURLOPT_SSLVERSION, 6); |
|
857 | - } |
|
858 | - } |
|
21 | + /** |
|
22 | + * @var EE_Payment_Processor $_instance |
|
23 | + * @access private |
|
24 | + */ |
|
25 | + private static $_instance; |
|
26 | + |
|
27 | + |
|
28 | + /** |
|
29 | + * @singleton method used to instantiate class object |
|
30 | + * @access public |
|
31 | + * @return EE_Payment_Processor instance |
|
32 | + */ |
|
33 | + public static function instance() |
|
34 | + { |
|
35 | + // check if class object is instantiated |
|
36 | + if (! self::$_instance instanceof EE_Payment_Processor) { |
|
37 | + self::$_instance = new self(); |
|
38 | + } |
|
39 | + return self::$_instance; |
|
40 | + } |
|
41 | + |
|
42 | + |
|
43 | + /** |
|
44 | + * @return EE_Payment_Processor |
|
45 | + */ |
|
46 | + public static function reset() |
|
47 | + { |
|
48 | + self::$_instance = null; |
|
49 | + return self::instance(); |
|
50 | + } |
|
51 | + |
|
52 | + |
|
53 | + /** |
|
54 | + *private constructor to prevent direct creation |
|
55 | + * |
|
56 | + * @Constructor |
|
57 | + * @access private |
|
58 | + */ |
|
59 | + private function __construct() |
|
60 | + { |
|
61 | + do_action('AHEE__EE_Payment_Processor__construct'); |
|
62 | + add_action('http_api_curl', array($this, '_curl_requests_to_paypal_use_tls'), 10, 3); |
|
63 | + } |
|
64 | + |
|
65 | + |
|
66 | + /** |
|
67 | + * Using the selected gateway, processes the payment for that transaction, and updates the transaction |
|
68 | + * appropriately. Saves the payment that is generated |
|
69 | + * |
|
70 | + * @param EE_Payment_Method $payment_method |
|
71 | + * @param EE_Transaction $transaction |
|
72 | + * @param float $amount if only part of the transaction is to be paid for, how much. |
|
73 | + * Leave null if payment is for the full amount owing |
|
74 | + * @param EE_Billing_Info_Form $billing_form (or probably null, if it's an offline or offsite payment method). |
|
75 | + * Receive_form_submission() should have |
|
76 | + * already been called on the billing form |
|
77 | + * (ie, its inputs should have their normalized values set). |
|
78 | + * @param string $return_url string used mostly by offsite gateways to specify |
|
79 | + * where to go AFTER the offsite gateway |
|
80 | + * @param string $method like 'CART', indicates who the client who called this was |
|
81 | + * @param bool $by_admin TRUE if payment is being attempted from the admin |
|
82 | + * @param boolean $update_txn whether or not to call |
|
83 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
84 | + * @param string $cancel_url URL to return to if off-site payments are cancelled |
|
85 | + * @return EE_Payment |
|
86 | + * @throws EE_Error |
|
87 | + * @throws InvalidArgumentException |
|
88 | + * @throws ReflectionException |
|
89 | + * @throws RuntimeException |
|
90 | + * @throws InvalidDataTypeException |
|
91 | + * @throws InvalidInterfaceException |
|
92 | + */ |
|
93 | + public function process_payment( |
|
94 | + EE_Payment_Method $payment_method, |
|
95 | + EE_Transaction $transaction, |
|
96 | + $amount = null, |
|
97 | + $billing_form = null, |
|
98 | + $return_url = null, |
|
99 | + $method = 'CART', |
|
100 | + $by_admin = false, |
|
101 | + $update_txn = true, |
|
102 | + $cancel_url = '' |
|
103 | + ) { |
|
104 | + if ((float) $amount < 0) { |
|
105 | + throw new EE_Error( |
|
106 | + sprintf( |
|
107 | + __( |
|
108 | + 'Attempting to make a payment for a negative amount of %1$d for transaction %2$d. That should be a refund', |
|
109 | + 'event_espresso' |
|
110 | + ), |
|
111 | + $amount, |
|
112 | + $transaction->ID() |
|
113 | + ) |
|
114 | + ); |
|
115 | + } |
|
116 | + // verify payment method |
|
117 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
118 | + $payment_method, |
|
119 | + true |
|
120 | + ); |
|
121 | + // verify transaction |
|
122 | + EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
123 | + $transaction->set_payment_method_ID($payment_method->ID()); |
|
124 | + // verify payment method type |
|
125 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
126 | + $payment = $payment_method->type_obj()->process_payment( |
|
127 | + $transaction, |
|
128 | + min($amount, $transaction->remaining()), // make sure we don't overcharge |
|
129 | + $billing_form, |
|
130 | + $return_url, |
|
131 | + add_query_arg(array('ee_cancel_payment' => true), $cancel_url), |
|
132 | + $method, |
|
133 | + $by_admin |
|
134 | + ); |
|
135 | + // check if payment method uses an off-site gateway |
|
136 | + if ($payment_method->type_obj()->payment_occurs() !== EE_PMT_Base::offsite) { |
|
137 | + // don't process payments for off-site gateways yet because no payment has occurred yet |
|
138 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
139 | + } |
|
140 | + return $payment; |
|
141 | + } |
|
142 | + EE_Error::add_error( |
|
143 | + sprintf( |
|
144 | + __( |
|
145 | + 'A valid payment method could not be determined due to a technical issue.%sPlease try again or contact %s for assistance.', |
|
146 | + 'event_espresso' |
|
147 | + ), |
|
148 | + '<br/>', |
|
149 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
150 | + ), |
|
151 | + __FILE__, |
|
152 | + __FUNCTION__, |
|
153 | + __LINE__ |
|
154 | + ); |
|
155 | + return null; |
|
156 | + } |
|
157 | + |
|
158 | + |
|
159 | + /** |
|
160 | + * @param EE_Transaction|int $transaction |
|
161 | + * @param EE_Payment_Method $payment_method |
|
162 | + * @return string |
|
163 | + * @throws EE_Error |
|
164 | + * @throws InvalidArgumentException |
|
165 | + * @throws InvalidDataTypeException |
|
166 | + * @throws InvalidInterfaceException |
|
167 | + */ |
|
168 | + public function get_ipn_url_for_payment_method($transaction, $payment_method) |
|
169 | + { |
|
170 | + /** @type \EE_Transaction $transaction */ |
|
171 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
172 | + $primary_reg = $transaction->primary_registration(); |
|
173 | + if (! $primary_reg instanceof EE_Registration) { |
|
174 | + throw new EE_Error( |
|
175 | + sprintf( |
|
176 | + __( |
|
177 | + 'Cannot get IPN URL for transaction with ID %d because it has no primary registration', |
|
178 | + 'event_espresso' |
|
179 | + ), |
|
180 | + $transaction->ID() |
|
181 | + ) |
|
182 | + ); |
|
183 | + } |
|
184 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj( |
|
185 | + $payment_method, |
|
186 | + true |
|
187 | + ); |
|
188 | + $url = add_query_arg( |
|
189 | + array( |
|
190 | + 'e_reg_url_link' => $primary_reg->reg_url_link(), |
|
191 | + 'ee_payment_method' => $payment_method->slug(), |
|
192 | + ), |
|
193 | + EE_Registry::instance()->CFG->core->txn_page_url() |
|
194 | + ); |
|
195 | + return $url; |
|
196 | + } |
|
197 | + |
|
198 | + |
|
199 | + /** |
|
200 | + * Process the IPN. Firstly, we'll hope we put the standard args into the IPN URL so |
|
201 | + * we can easily find what registration the IPN is for and what payment method. |
|
202 | + * However, if not, we'll give all payment methods a chance to claim it and process it. |
|
203 | + * If a payment is found for the IPN info, it is saved. |
|
204 | + * |
|
205 | + * @param array $_req_data eg $_REQUEST |
|
206 | + * @param EE_Transaction|int $transaction optional (or a transactions id) |
|
207 | + * @param EE_Payment_Method $payment_method (or a slug or id of one) |
|
208 | + * @param boolean $update_txn whether or not to call |
|
209 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
210 | + * @param bool $separate_IPN_request whether the IPN uses a separate request (true, like PayPal) |
|
211 | + * or is processed manually (false, like Authorize.net) |
|
212 | + * @throws EE_Error |
|
213 | + * @throws Exception |
|
214 | + * @return EE_Payment |
|
215 | + * @throws \RuntimeException |
|
216 | + * @throws \ReflectionException |
|
217 | + * @throws \InvalidArgumentException |
|
218 | + * @throws InvalidInterfaceException |
|
219 | + * @throws InvalidDataTypeException |
|
220 | + */ |
|
221 | + public function process_ipn( |
|
222 | + $_req_data, |
|
223 | + $transaction = null, |
|
224 | + $payment_method = null, |
|
225 | + $update_txn = true, |
|
226 | + $separate_IPN_request = true |
|
227 | + ) { |
|
228 | + EE_Registry::instance()->load_model('Change_Log'); |
|
229 | + $_req_data = $this->_remove_unusable_characters_from_array((array) $_req_data); |
|
230 | + EE_Processor_Base::set_IPN($separate_IPN_request); |
|
231 | + $obj_for_log = null; |
|
232 | + if ($transaction instanceof EE_Transaction) { |
|
233 | + $obj_for_log = $transaction; |
|
234 | + if ($payment_method instanceof EE_Payment_Method) { |
|
235 | + $obj_for_log = EEM_Payment::instance()->get_one( |
|
236 | + array( |
|
237 | + array('TXN_ID' => $transaction->ID(), 'PMD_ID' => $payment_method->ID()), |
|
238 | + 'order_by' => array('PAY_timestamp' => 'desc'), |
|
239 | + ) |
|
240 | + ); |
|
241 | + } |
|
242 | + } elseif ($payment_method instanceof EE_Payment) { |
|
243 | + $obj_for_log = $payment_method; |
|
244 | + } |
|
245 | + $log = EEM_Change_Log::instance()->log( |
|
246 | + EEM_Change_Log::type_gateway, |
|
247 | + array('IPN data received' => $_req_data), |
|
248 | + $obj_for_log |
|
249 | + ); |
|
250 | + try { |
|
251 | + /** |
|
252 | + * @var EE_Payment $payment |
|
253 | + */ |
|
254 | + $payment = null; |
|
255 | + if ($transaction && $payment_method) { |
|
256 | + /** @type EE_Transaction $transaction */ |
|
257 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
258 | + /** @type EE_Payment_Method $payment_method */ |
|
259 | + $payment_method = EEM_Payment_Method::instance()->ensure_is_obj($payment_method); |
|
260 | + if ($payment_method->type_obj() instanceof EE_PMT_Base) { |
|
261 | + try { |
|
262 | + $payment = $payment_method->type_obj()->handle_ipn($_req_data, $transaction); |
|
263 | + $log->set_object($payment); |
|
264 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
265 | + EEM_Change_Log::instance()->log( |
|
266 | + EEM_Change_Log::type_gateway, |
|
267 | + array( |
|
268 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
269 | + 'current_url' => EEH_URL::current_url(), |
|
270 | + 'payment' => $e->getPaymentProperties(), |
|
271 | + 'IPN_data' => $e->getIpnData(), |
|
272 | + ), |
|
273 | + $obj_for_log |
|
274 | + ); |
|
275 | + return $e->getPayment(); |
|
276 | + } |
|
277 | + } else { |
|
278 | + // not a payment |
|
279 | + EE_Error::add_error( |
|
280 | + sprintf( |
|
281 | + __( |
|
282 | + 'A valid payment method could not be determined due to a technical issue.%sPlease refresh your browser and try again or contact %s for assistance.', |
|
283 | + 'event_espresso' |
|
284 | + ), |
|
285 | + '<br/>', |
|
286 | + EE_Registry::instance()->CFG->organization->get_pretty('email') |
|
287 | + ), |
|
288 | + __FILE__, |
|
289 | + __FUNCTION__, |
|
290 | + __LINE__ |
|
291 | + ); |
|
292 | + } |
|
293 | + } else { |
|
294 | + // that's actually pretty ok. The IPN just wasn't able |
|
295 | + // to identify which transaction or payment method this was for |
|
296 | + // give all active payment methods a chance to claim it |
|
297 | + $active_payment_methods = EEM_Payment_Method::instance()->get_all_active(); |
|
298 | + foreach ($active_payment_methods as $active_payment_method) { |
|
299 | + try { |
|
300 | + $payment = $active_payment_method->type_obj()->handle_unclaimed_ipn($_req_data); |
|
301 | + $payment_method = $active_payment_method; |
|
302 | + EEM_Change_Log::instance()->log( |
|
303 | + EEM_Change_Log::type_gateway, |
|
304 | + array('IPN data' => $_req_data), |
|
305 | + $payment |
|
306 | + ); |
|
307 | + break; |
|
308 | + } catch (EventEspresso\core\exceptions\IpnException $e) { |
|
309 | + EEM_Change_Log::instance()->log( |
|
310 | + EEM_Change_Log::type_gateway, |
|
311 | + array( |
|
312 | + 'message' => 'IPN Exception: ' . $e->getMessage(), |
|
313 | + 'current_url' => EEH_URL::current_url(), |
|
314 | + 'payment' => $e->getPaymentProperties(), |
|
315 | + 'IPN_data' => $e->getIpnData(), |
|
316 | + ), |
|
317 | + $obj_for_log |
|
318 | + ); |
|
319 | + return $e->getPayment(); |
|
320 | + } catch (EE_Error $e) { |
|
321 | + // that's fine- it apparently couldn't handle the IPN |
|
322 | + } |
|
323 | + } |
|
324 | + } |
|
325 | + // EEM_Payment_Log::instance()->log("got to 7",$transaction,$payment_method); |
|
326 | + if ($payment instanceof EE_Payment) { |
|
327 | + $payment->save(); |
|
328 | + // update the TXN |
|
329 | + $this->update_txn_based_on_payment( |
|
330 | + $transaction, |
|
331 | + $payment, |
|
332 | + $update_txn, |
|
333 | + $separate_IPN_request |
|
334 | + ); |
|
335 | + } else { |
|
336 | + // we couldn't find the payment for this IPN... let's try and log at least SOMETHING |
|
337 | + if ($payment_method) { |
|
338 | + EEM_Change_Log::instance()->log( |
|
339 | + EEM_Change_Log::type_gateway, |
|
340 | + array('IPN data' => $_req_data), |
|
341 | + $payment_method |
|
342 | + ); |
|
343 | + } elseif ($transaction) { |
|
344 | + EEM_Change_Log::instance()->log( |
|
345 | + EEM_Change_Log::type_gateway, |
|
346 | + array('IPN data' => $_req_data), |
|
347 | + $transaction |
|
348 | + ); |
|
349 | + } |
|
350 | + } |
|
351 | + return $payment; |
|
352 | + } catch (EE_Error $e) { |
|
353 | + do_action( |
|
354 | + 'AHEE__log', |
|
355 | + __FILE__, |
|
356 | + __FUNCTION__, |
|
357 | + sprintf( |
|
358 | + __( |
|
359 | + 'Error occurred while receiving IPN. Transaction: %1$s, req data: %2$s. The error was "%3$s"', |
|
360 | + 'event_espresso' |
|
361 | + ), |
|
362 | + print_r($transaction, true), |
|
363 | + print_r($_req_data, true), |
|
364 | + $e->getMessage() |
|
365 | + ) |
|
366 | + ); |
|
367 | + throw $e; |
|
368 | + } |
|
369 | + } |
|
370 | + |
|
371 | + |
|
372 | + /** |
|
373 | + * Removes any non-printable illegal characters from the input, |
|
374 | + * which might cause a raucous when trying to insert into the database |
|
375 | + * |
|
376 | + * @param array $request_data |
|
377 | + * @return array |
|
378 | + */ |
|
379 | + protected function _remove_unusable_characters_from_array(array $request_data) |
|
380 | + { |
|
381 | + $return_data = array(); |
|
382 | + foreach ($request_data as $key => $value) { |
|
383 | + $return_data[ $this->_remove_unusable_characters($key) ] = $this->_remove_unusable_characters( |
|
384 | + $value |
|
385 | + ); |
|
386 | + } |
|
387 | + return $return_data; |
|
388 | + } |
|
389 | + |
|
390 | + |
|
391 | + /** |
|
392 | + * Removes any non-printable illegal characters from the input, |
|
393 | + * which might cause a raucous when trying to insert into the database |
|
394 | + * |
|
395 | + * @param string $request_data |
|
396 | + * @return string |
|
397 | + */ |
|
398 | + protected function _remove_unusable_characters($request_data) |
|
399 | + { |
|
400 | + return preg_replace('/[^[:print:]]/', '', $request_data); |
|
401 | + } |
|
402 | + |
|
403 | + |
|
404 | + /** |
|
405 | + * Should be called just before displaying the payment attempt results to the user, |
|
406 | + * when the payment attempt has finished. Some payment methods may have special |
|
407 | + * logic to perform here. For example, if process_payment() happens on a special request |
|
408 | + * and then the user is redirected to a page that displays the payment's status, this |
|
409 | + * should be called while loading the page that displays the payment's status. If the user is |
|
410 | + * sent to an offsite payment provider, this should be called upon returning from that offsite payment |
|
411 | + * provider. |
|
412 | + * |
|
413 | + * @param EE_Transaction|int $transaction |
|
414 | + * @param bool $update_txn whether or not to call |
|
415 | + * EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() |
|
416 | + * @return EE_Payment |
|
417 | + * @throws EE_Error |
|
418 | + * @throws InvalidArgumentException |
|
419 | + * @throws ReflectionException |
|
420 | + * @throws RuntimeException |
|
421 | + * @throws InvalidDataTypeException |
|
422 | + * @throws InvalidInterfaceException |
|
423 | + * @deprecated 4.6.24 method is no longer used. Instead it is up to client code, like SPCO, |
|
424 | + * to call handle_ipn() for offsite gateways that don't receive separate IPNs |
|
425 | + */ |
|
426 | + public function finalize_payment_for($transaction, $update_txn = true) |
|
427 | + { |
|
428 | + /** @var $transaction EE_Transaction */ |
|
429 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
430 | + $last_payment_method = $transaction->payment_method(); |
|
431 | + if ($last_payment_method instanceof EE_Payment_Method) { |
|
432 | + $payment = $last_payment_method->type_obj()->finalize_payment_for($transaction); |
|
433 | + $this->update_txn_based_on_payment($transaction, $payment, $update_txn); |
|
434 | + return $payment; |
|
435 | + } |
|
436 | + return null; |
|
437 | + } |
|
438 | + |
|
439 | + |
|
440 | + /** |
|
441 | + * Processes a direct refund request, saves the payment, and updates the transaction appropriately. |
|
442 | + * |
|
443 | + * @param EE_Payment_Method $payment_method |
|
444 | + * @param EE_Payment $payment_to_refund |
|
445 | + * @param array $refund_info |
|
446 | + * @return EE_Payment |
|
447 | + * @throws EE_Error |
|
448 | + * @throws InvalidArgumentException |
|
449 | + * @throws ReflectionException |
|
450 | + * @throws RuntimeException |
|
451 | + * @throws InvalidDataTypeException |
|
452 | + * @throws InvalidInterfaceException |
|
453 | + */ |
|
454 | + public function process_refund( |
|
455 | + EE_Payment_Method $payment_method, |
|
456 | + EE_Payment $payment_to_refund, |
|
457 | + array $refund_info = array() |
|
458 | + ) { |
|
459 | + if ($payment_method instanceof EE_Payment_Method && $payment_method->type_obj()->supports_sending_refunds()) { |
|
460 | + $payment_method->type_obj()->process_refund($payment_to_refund, $refund_info); |
|
461 | + $this->update_txn_based_on_payment($payment_to_refund->transaction(), $payment_to_refund); |
|
462 | + } |
|
463 | + return $payment_to_refund; |
|
464 | + } |
|
465 | + |
|
466 | + |
|
467 | + /** |
|
468 | + * This should be called each time there may have been an update to a |
|
469 | + * payment on a transaction (ie, we asked for a payment to process a |
|
470 | + * payment for a transaction, or we told a payment method about an IPN, or |
|
471 | + * we told a payment method to |
|
472 | + * "finalize_payment_for" (a transaction), or we told a payment method to |
|
473 | + * process a refund. This should handle firing the correct hooks to |
|
474 | + * indicate |
|
475 | + * what exactly happened and updating the transaction appropriately). This |
|
476 | + * could be integrated directly into EE_Transaction upon save, but we want |
|
477 | + * this logic to be separate from 'normal' plain-jane saving and updating |
|
478 | + * of transactions and payments, and to be tied to payment processing. |
|
479 | + * Note: this method DOES NOT save the payment passed into it. It is the responsibility |
|
480 | + * of previous code to decide whether or not to save (because the payment passed into |
|
481 | + * this method might be a temporary, never-to-be-saved payment from an offline gateway, |
|
482 | + * in which case we only want that payment object for some temporary usage during this request, |
|
483 | + * but we don't want it to be saved). |
|
484 | + * |
|
485 | + * @param EE_Transaction|int $transaction |
|
486 | + * @param EE_Payment $payment |
|
487 | + * @param boolean $update_txn |
|
488 | + * whether or not to call |
|
489 | + * EE_Transaction_Processor:: |
|
490 | + * update_transaction_and_registrations_after_checkout_or_payment() |
|
491 | + * (you can save 1 DB query if you know you're going |
|
492 | + * to save it later instead) |
|
493 | + * @param bool $IPN |
|
494 | + * if processing IPNs or other similar payment |
|
495 | + * related activities that occur in alternate |
|
496 | + * requests than the main one that is processing the |
|
497 | + * TXN, then set this to true to check whether the |
|
498 | + * TXN is locked before updating |
|
499 | + * @throws EE_Error |
|
500 | + * @throws InvalidArgumentException |
|
501 | + * @throws ReflectionException |
|
502 | + * @throws RuntimeException |
|
503 | + * @throws InvalidDataTypeException |
|
504 | + * @throws InvalidInterfaceException |
|
505 | + */ |
|
506 | + public function update_txn_based_on_payment($transaction, $payment, $update_txn = true, $IPN = false) |
|
507 | + { |
|
508 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__not_successful'; |
|
509 | + /** @type EE_Transaction $transaction */ |
|
510 | + $transaction = EEM_Transaction::instance()->ensure_is_obj($transaction); |
|
511 | + // can we freely update the TXN at this moment? |
|
512 | + if ($IPN && $transaction->is_locked()) { |
|
513 | + // don't update the transaction at this exact moment |
|
514 | + // because the TXN is active in another request |
|
515 | + EE_Cron_Tasks::schedule_update_transaction_with_payment( |
|
516 | + time(), |
|
517 | + $transaction->ID(), |
|
518 | + $payment->ID() |
|
519 | + ); |
|
520 | + } else { |
|
521 | + // verify payment and that it has been saved |
|
522 | + if ($payment instanceof EE_Payment && $payment->ID()) { |
|
523 | + if ($payment->payment_method() instanceof EE_Payment_Method |
|
524 | + && $payment->payment_method()->type_obj() instanceof EE_PMT_Base |
|
525 | + ) { |
|
526 | + $payment->payment_method()->type_obj()->update_txn_based_on_payment($payment); |
|
527 | + // update TXN registrations with payment info |
|
528 | + $this->process_registration_payments($transaction, $payment); |
|
529 | + } |
|
530 | + $do_action = $payment->just_approved() |
|
531 | + ? 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__successful' |
|
532 | + : $do_action; |
|
533 | + } else { |
|
534 | + // send out notifications |
|
535 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
536 | + $do_action = 'AHEE__EE_Payment_Processor__update_txn_based_on_payment__no_payment_made'; |
|
537 | + } |
|
538 | + if ($payment instanceof EE_Payment && $payment->status() !== EEM_Payment::status_id_failed) { |
|
539 | + /** @type EE_Transaction_Payments $transaction_payments */ |
|
540 | + $transaction_payments = EE_Registry::instance()->load_class('Transaction_Payments'); |
|
541 | + // set new value for total paid |
|
542 | + $transaction_payments->calculate_total_payments_and_update_status($transaction); |
|
543 | + // call EE_Transaction_Processor::update_transaction_and_registrations_after_checkout_or_payment() ??? |
|
544 | + if ($update_txn) { |
|
545 | + $this->_post_payment_processing($transaction, $payment, $IPN); |
|
546 | + } |
|
547 | + } |
|
548 | + // granular hook for others to use. |
|
549 | + do_action($do_action, $transaction, $payment); |
|
550 | + do_action('AHEE_log', __CLASS__, __FUNCTION__, $do_action, '$do_action'); |
|
551 | + // global hook for others to use. |
|
552 | + do_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', $transaction, $payment); |
|
553 | + } |
|
554 | + } |
|
555 | + |
|
556 | + |
|
557 | + /** |
|
558 | + * update registrations REG_paid field after successful payment and link registrations with payment |
|
559 | + * |
|
560 | + * @param EE_Transaction $transaction |
|
561 | + * @param EE_Payment $payment |
|
562 | + * @param EE_Registration[] $registrations |
|
563 | + * @throws EE_Error |
|
564 | + * @throws InvalidArgumentException |
|
565 | + * @throws RuntimeException |
|
566 | + * @throws InvalidDataTypeException |
|
567 | + * @throws InvalidInterfaceException |
|
568 | + */ |
|
569 | + public function process_registration_payments( |
|
570 | + EE_Transaction $transaction, |
|
571 | + EE_Payment $payment, |
|
572 | + array $registrations = array() |
|
573 | + ) { |
|
574 | + // only process if payment was successful |
|
575 | + if ($payment->status() !== EEM_Payment::status_id_approved) { |
|
576 | + return; |
|
577 | + } |
|
578 | + // EEM_Registration::instance()->show_next_x_db_queries(); |
|
579 | + if (empty($registrations)) { |
|
580 | + // find registrations with monies owing that can receive a payment |
|
581 | + $registrations = $transaction->registrations( |
|
582 | + array( |
|
583 | + array( |
|
584 | + // only these reg statuses can receive payments |
|
585 | + 'STS_ID' => array('IN', EEM_Registration::reg_statuses_that_allow_payment()), |
|
586 | + 'REG_final_price' => array('!=', 0), |
|
587 | + 'REG_final_price*' => array('!=', 'REG_paid', true), |
|
588 | + ), |
|
589 | + ) |
|
590 | + ); |
|
591 | + } |
|
592 | + // still nothing ??!?? |
|
593 | + if (empty($registrations)) { |
|
594 | + return; |
|
595 | + } |
|
596 | + // todo: break out the following logic into a separate strategy class |
|
597 | + // todo: named something like "Sequential_Reg_Payment_Strategy" |
|
598 | + // todo: which would apply payments using the capitalist "first come first paid" approach |
|
599 | + // todo: then have another strategy class like "Distributed_Reg_Payment_Strategy" |
|
600 | + // todo: which would be the socialist "everybody gets a piece of pie" approach, |
|
601 | + // todo: which would be better for deposits, where you want a bit of the payment applied to each registration |
|
602 | + $refund = $payment->is_a_refund(); |
|
603 | + // how much is available to apply to registrations? |
|
604 | + $available_payment_amount = abs($payment->amount()); |
|
605 | + foreach ($registrations as $registration) { |
|
606 | + if ($registration instanceof EE_Registration) { |
|
607 | + // nothing left? |
|
608 | + if ($available_payment_amount <= 0) { |
|
609 | + break; |
|
610 | + } |
|
611 | + if ($refund) { |
|
612 | + $available_payment_amount = $this->process_registration_refund( |
|
613 | + $registration, |
|
614 | + $payment, |
|
615 | + $available_payment_amount |
|
616 | + ); |
|
617 | + } else { |
|
618 | + $available_payment_amount = $this->process_registration_payment( |
|
619 | + $registration, |
|
620 | + $payment, |
|
621 | + $available_payment_amount |
|
622 | + ); |
|
623 | + } |
|
624 | + } |
|
625 | + } |
|
626 | + if ($available_payment_amount > 0 |
|
627 | + && apply_filters( |
|
628 | + 'FHEE__EE_Payment_Processor__process_registration_payments__display_notifications', |
|
629 | + false |
|
630 | + )) { |
|
631 | + EE_Error::add_attention( |
|
632 | + sprintf( |
|
633 | + __( |
|
634 | + 'A remainder of %1$s exists after applying this payment to Registration(s) %2$s.%3$sPlease verify that the original payment amount of %4$s is correct. If so, you should edit this payment and select at least one additional registration in the "Registrations to Apply Payment to" section, so that the remainder of this payment can be applied to the additional registration(s).', |
|
635 | + 'event_espresso' |
|
636 | + ), |
|
637 | + EEH_Template::format_currency($available_payment_amount), |
|
638 | + implode(', ', array_keys($registrations)), |
|
639 | + '<br/>', |
|
640 | + EEH_Template::format_currency($payment->amount()) |
|
641 | + ), |
|
642 | + __FILE__, |
|
643 | + __FUNCTION__, |
|
644 | + __LINE__ |
|
645 | + ); |
|
646 | + } |
|
647 | + } |
|
648 | + |
|
649 | + |
|
650 | + /** |
|
651 | + * update registration REG_paid field after successful payment and link registration with payment |
|
652 | + * |
|
653 | + * @param EE_Registration $registration |
|
654 | + * @param EE_Payment $payment |
|
655 | + * @param float $available_payment_amount |
|
656 | + * @return float |
|
657 | + * @throws EE_Error |
|
658 | + * @throws InvalidArgumentException |
|
659 | + * @throws RuntimeException |
|
660 | + * @throws InvalidDataTypeException |
|
661 | + * @throws InvalidInterfaceException |
|
662 | + */ |
|
663 | + public function process_registration_payment( |
|
664 | + EE_Registration $registration, |
|
665 | + EE_Payment $payment, |
|
666 | + $available_payment_amount = 0.00 |
|
667 | + ) { |
|
668 | + $owing = $registration->final_price() - $registration->paid(); |
|
669 | + if ($owing > 0) { |
|
670 | + // don't allow payment amount to exceed the available payment amount, OR the amount owing |
|
671 | + $payment_amount = min($available_payment_amount, $owing); |
|
672 | + // update $available_payment_amount |
|
673 | + $available_payment_amount -= $payment_amount; |
|
674 | + // calculate and set new REG_paid |
|
675 | + $registration->set_paid($registration->paid() + $payment_amount); |
|
676 | + // now save it |
|
677 | + $this->_apply_registration_payment($registration, $payment, $payment_amount); |
|
678 | + } |
|
679 | + return $available_payment_amount; |
|
680 | + } |
|
681 | + |
|
682 | + |
|
683 | + /** |
|
684 | + * update registration REG_paid field after successful payment and link registration with payment |
|
685 | + * |
|
686 | + * @param EE_Registration $registration |
|
687 | + * @param EE_Payment $payment |
|
688 | + * @param float $payment_amount |
|
689 | + * @return void |
|
690 | + * @throws EE_Error |
|
691 | + * @throws InvalidArgumentException |
|
692 | + * @throws InvalidDataTypeException |
|
693 | + * @throws InvalidInterfaceException |
|
694 | + */ |
|
695 | + protected function _apply_registration_payment( |
|
696 | + EE_Registration $registration, |
|
697 | + EE_Payment $payment, |
|
698 | + $payment_amount = 0.00 |
|
699 | + ) { |
|
700 | + // find any existing reg payment records for this registration and payment |
|
701 | + $existing_reg_payment = EEM_Registration_Payment::instance()->get_one( |
|
702 | + array(array('REG_ID' => $registration->ID(), 'PAY_ID' => $payment->ID())) |
|
703 | + ); |
|
704 | + // if existing registration payment exists |
|
705 | + if ($existing_reg_payment instanceof EE_Registration_Payment) { |
|
706 | + // then update that record |
|
707 | + $existing_reg_payment->set_amount($payment_amount); |
|
708 | + $existing_reg_payment->save(); |
|
709 | + } else { |
|
710 | + // or add new relation between registration and payment and set amount |
|
711 | + $registration->_add_relation_to( |
|
712 | + $payment, |
|
713 | + 'Payment', |
|
714 | + array('RPY_amount' => $payment_amount) |
|
715 | + ); |
|
716 | + // make it stick |
|
717 | + $registration->save(); |
|
718 | + } |
|
719 | + } |
|
720 | + |
|
721 | + |
|
722 | + /** |
|
723 | + * update registration REG_paid field after refund and link registration with payment |
|
724 | + * |
|
725 | + * @param EE_Registration $registration |
|
726 | + * @param EE_Payment $payment |
|
727 | + * @param float $available_refund_amount - IMPORTANT !!! SEND AVAILABLE REFUND AMOUNT AS A POSITIVE NUMBER |
|
728 | + * @return float |
|
729 | + * @throws EE_Error |
|
730 | + * @throws InvalidArgumentException |
|
731 | + * @throws RuntimeException |
|
732 | + * @throws InvalidDataTypeException |
|
733 | + * @throws InvalidInterfaceException |
|
734 | + */ |
|
735 | + public function process_registration_refund( |
|
736 | + EE_Registration $registration, |
|
737 | + EE_Payment $payment, |
|
738 | + $available_refund_amount = 0.00 |
|
739 | + ) { |
|
740 | + // EEH_Debug_Tools::printr( $payment->amount(), '$payment->amount()', __FILE__, __LINE__ ); |
|
741 | + if ($registration->paid() > 0) { |
|
742 | + // ensure $available_refund_amount is NOT negative |
|
743 | + $available_refund_amount = (float) abs($available_refund_amount); |
|
744 | + // don't allow refund amount to exceed the available payment amount, OR the amount paid |
|
745 | + $refund_amount = min($available_refund_amount, (float) $registration->paid()); |
|
746 | + // update $available_payment_amount |
|
747 | + $available_refund_amount -= $refund_amount; |
|
748 | + // calculate and set new REG_paid |
|
749 | + $registration->set_paid($registration->paid() - $refund_amount); |
|
750 | + // convert payment amount back to a negative value for storage in the db |
|
751 | + $refund_amount = (float) abs($refund_amount) * -1; |
|
752 | + // now save it |
|
753 | + $this->_apply_registration_payment($registration, $payment, $refund_amount); |
|
754 | + } |
|
755 | + return $available_refund_amount; |
|
756 | + } |
|
757 | + |
|
758 | + |
|
759 | + /** |
|
760 | + * Process payments and transaction after payment process completed. |
|
761 | + * ultimately this will send the TXN and payment details off so that notifications can be sent out. |
|
762 | + * if this request happens to be processing an IPN, |
|
763 | + * then we will also set the Payment Options Reg Step to completed, |
|
764 | + * and attempt to completely finalize the TXN if all of the other Reg Steps are completed as well. |
|
765 | + * |
|
766 | + * @param EE_Transaction $transaction |
|
767 | + * @param EE_Payment $payment |
|
768 | + * @param bool $IPN |
|
769 | + * @throws EE_Error |
|
770 | + * @throws InvalidArgumentException |
|
771 | + * @throws ReflectionException |
|
772 | + * @throws RuntimeException |
|
773 | + * @throws InvalidDataTypeException |
|
774 | + * @throws InvalidInterfaceException |
|
775 | + */ |
|
776 | + protected function _post_payment_processing(EE_Transaction $transaction, EE_Payment $payment, $IPN = false) |
|
777 | + { |
|
778 | + /** @type EE_Transaction_Processor $transaction_processor */ |
|
779 | + $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor'); |
|
780 | + // is the Payment Options Reg Step completed ? |
|
781 | + $payment_options_step_completed = $transaction->reg_step_completed('payment_options'); |
|
782 | + // if the Payment Options Reg Step is completed... |
|
783 | + $revisit = $payment_options_step_completed === true; |
|
784 | + // then this is kinda sorta a revisit with regards to payments at least |
|
785 | + $transaction_processor->set_revisit($revisit); |
|
786 | + // if this is an IPN, let's consider the Payment Options Reg Step completed if not already |
|
787 | + if ($IPN |
|
788 | + && $payment_options_step_completed !== true |
|
789 | + && ($payment->is_approved() || $payment->is_pending()) |
|
790 | + ) { |
|
791 | + $payment_options_step_completed = $transaction->set_reg_step_completed( |
|
792 | + 'payment_options' |
|
793 | + ); |
|
794 | + } |
|
795 | + // maybe update status, but don't save transaction just yet |
|
796 | + $transaction->update_status_based_on_total_paid(false); |
|
797 | + // check if 'finalize_registration' step has been completed... |
|
798 | + $finalized = $transaction->reg_step_completed('finalize_registration'); |
|
799 | + // if this is an IPN and the final step has not been initiated |
|
800 | + if ($IPN && $payment_options_step_completed && $finalized === false) { |
|
801 | + // and if it hasn't already been set as being started... |
|
802 | + $finalized = $transaction->set_reg_step_initiated('finalize_registration'); |
|
803 | + } |
|
804 | + $transaction->save(); |
|
805 | + // because the above will return false if the final step was not fully completed, we need to check again... |
|
806 | + if ($IPN && $finalized !== false) { |
|
807 | + // and if we are all good to go, then send out notifications |
|
808 | + add_filter('FHEE__EED_Messages___maybe_registration__deliver_notifications', '__return_true'); |
|
809 | + // ok, now process the transaction according to the payment |
|
810 | + $transaction_processor->update_transaction_and_registrations_after_checkout_or_payment( |
|
811 | + $transaction, |
|
812 | + $payment |
|
813 | + ); |
|
814 | + } |
|
815 | + // DEBUG LOG |
|
816 | + $payment_method = $payment->payment_method(); |
|
817 | + if ($payment_method instanceof EE_Payment_Method) { |
|
818 | + $payment_method_type_obj = $payment_method->type_obj(); |
|
819 | + if ($payment_method_type_obj instanceof EE_PMT_Base) { |
|
820 | + $gateway = $payment_method_type_obj->get_gateway(); |
|
821 | + if ($gateway instanceof EE_Gateway) { |
|
822 | + $gateway->log( |
|
823 | + array( |
|
824 | + 'message' => (string) __('Post Payment Transaction Details', 'event_espresso'), |
|
825 | + 'transaction' => $transaction->model_field_array(), |
|
826 | + 'finalized' => $finalized, |
|
827 | + 'IPN' => $IPN, |
|
828 | + 'deliver_notifications' => has_filter( |
|
829 | + 'FHEE__EED_Messages___maybe_registration__deliver_notifications' |
|
830 | + ), |
|
831 | + ), |
|
832 | + $payment |
|
833 | + ); |
|
834 | + } |
|
835 | + } |
|
836 | + } |
|
837 | + } |
|
838 | + |
|
839 | + |
|
840 | + /** |
|
841 | + * Force posts to PayPal to use TLS v1.2. See: |
|
842 | + * https://core.trac.wordpress.org/ticket/36320 |
|
843 | + * https://core.trac.wordpress.org/ticket/34924#comment:15 |
|
844 | + * https://www.paypal-knowledge.com/infocenter/index?page=content&widgetview=true&id=FAQ1914&viewlocale=en_US |
|
845 | + * This will affect PayPal standard, pro, express, and Payflow. |
|
846 | + * |
|
847 | + * @param $handle |
|
848 | + * @param $r |
|
849 | + * @param $url |
|
850 | + */ |
|
851 | + public static function _curl_requests_to_paypal_use_tls($handle, $r, $url) |
|
852 | + { |
|
853 | + if (strpos($url, 'https://') !== false && strpos($url, '.paypal.com') !== false) { |
|
854 | + // Use the value of the constant CURL_SSLVERSION_TLSv1 = 1 |
|
855 | + // instead of the constant because it might not be defined |
|
856 | + curl_setopt($handle, CURLOPT_SSLVERSION, 6); |
|
857 | + } |
|
858 | + } |
|
859 | 859 | } |
@@ -13,82 +13,82 @@ |
||
13 | 13 | class EED_Invalid_Checkout_Access extends EED_Module |
14 | 14 | { |
15 | 15 | |
16 | - /** |
|
17 | - * @var InvalidCheckoutAccess $invalid_checkout_access_form |
|
18 | - */ |
|
19 | - private static $invalid_checkout_access_form; |
|
16 | + /** |
|
17 | + * @var InvalidCheckoutAccess $invalid_checkout_access_form |
|
18 | + */ |
|
19 | + private static $invalid_checkout_access_form; |
|
20 | 20 | |
21 | - /** |
|
22 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
23 | - */ |
|
24 | - public static function set_hooks() |
|
25 | - { |
|
26 | - } |
|
21 | + /** |
|
22 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
23 | + */ |
|
24 | + public static function set_hooks() |
|
25 | + { |
|
26 | + } |
|
27 | 27 | |
28 | 28 | |
29 | - /** |
|
30 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
31 | - */ |
|
32 | - public static function set_hooks_admin() |
|
33 | - { |
|
34 | - add_action( |
|
35 | - 'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template', |
|
36 | - array('EED_Invalid_Checkout_Access', 'display_invalid_checkout_access_form'), |
|
37 | - 15 |
|
38 | - ); |
|
39 | - add_filter( |
|
40 | - 'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration', |
|
41 | - array('EED_Invalid_Checkout_Access', 'process_invalid_checkout_access_form') |
|
42 | - ); |
|
43 | - } |
|
29 | + /** |
|
30 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
31 | + */ |
|
32 | + public static function set_hooks_admin() |
|
33 | + { |
|
34 | + add_action( |
|
35 | + 'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template', |
|
36 | + array('EED_Invalid_Checkout_Access', 'display_invalid_checkout_access_form'), |
|
37 | + 15 |
|
38 | + ); |
|
39 | + add_filter( |
|
40 | + 'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration', |
|
41 | + array('EED_Invalid_Checkout_Access', 'process_invalid_checkout_access_form') |
|
42 | + ); |
|
43 | + } |
|
44 | 44 | |
45 | 45 | |
46 | - /** |
|
47 | - * run - initial module setup |
|
48 | - * this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters |
|
49 | - * |
|
50 | - * @var WP $WP |
|
51 | - */ |
|
52 | - public function run($WP) |
|
53 | - { |
|
54 | - // TODO: Implement run() method. |
|
55 | - } |
|
46 | + /** |
|
47 | + * run - initial module setup |
|
48 | + * this method is primarily used for activating resources in the EE_Front_Controller thru the use of filters |
|
49 | + * |
|
50 | + * @var WP $WP |
|
51 | + */ |
|
52 | + public function run($WP) |
|
53 | + { |
|
54 | + // TODO: Implement run() method. |
|
55 | + } |
|
56 | 56 | |
57 | 57 | |
58 | - /** |
|
59 | - * @return InvalidCheckoutAccess |
|
60 | - */ |
|
61 | - public static function getInvalidCheckoutAccess() |
|
62 | - { |
|
63 | - if (! self::$invalid_checkout_access_form instanceof InvalidCheckoutAccess) { |
|
64 | - self::$invalid_checkout_access_form = new InvalidCheckoutAccess(); |
|
65 | - } |
|
66 | - return self::$invalid_checkout_access_form; |
|
67 | - } |
|
58 | + /** |
|
59 | + * @return InvalidCheckoutAccess |
|
60 | + */ |
|
61 | + public static function getInvalidCheckoutAccess() |
|
62 | + { |
|
63 | + if (! self::$invalid_checkout_access_form instanceof InvalidCheckoutAccess) { |
|
64 | + self::$invalid_checkout_access_form = new InvalidCheckoutAccess(); |
|
65 | + } |
|
66 | + return self::$invalid_checkout_access_form; |
|
67 | + } |
|
68 | 68 | |
69 | 69 | |
70 | - /** |
|
71 | - * email_validation_settings_form |
|
72 | - * |
|
73 | - * @return void |
|
74 | - * @throws \EE_Error |
|
75 | - */ |
|
76 | - public static function display_invalid_checkout_access_form() |
|
77 | - { |
|
78 | - $invalid_checkout_access_form = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
79 | - echo $invalid_checkout_access_form->getForm()->get_html(); |
|
80 | - } |
|
70 | + /** |
|
71 | + * email_validation_settings_form |
|
72 | + * |
|
73 | + * @return void |
|
74 | + * @throws \EE_Error |
|
75 | + */ |
|
76 | + public static function display_invalid_checkout_access_form() |
|
77 | + { |
|
78 | + $invalid_checkout_access_form = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
79 | + echo $invalid_checkout_access_form->getForm()->get_html(); |
|
80 | + } |
|
81 | 81 | |
82 | 82 | |
83 | - /** |
|
84 | - * email_validation_settings_form |
|
85 | - * |
|
86 | - * @param \EE_Registration_Config $EE_Registration_Config |
|
87 | - * @return \EE_Registration_Config |
|
88 | - */ |
|
89 | - public static function process_invalid_checkout_access_form(\EE_Registration_Config $EE_Registration_Config) |
|
90 | - { |
|
91 | - $invalid_checkout_access_form = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
92 | - return $invalid_checkout_access_form->processForm($EE_Registration_Config); |
|
93 | - } |
|
83 | + /** |
|
84 | + * email_validation_settings_form |
|
85 | + * |
|
86 | + * @param \EE_Registration_Config $EE_Registration_Config |
|
87 | + * @return \EE_Registration_Config |
|
88 | + */ |
|
89 | + public static function process_invalid_checkout_access_form(\EE_Registration_Config $EE_Registration_Config) |
|
90 | + { |
|
91 | + $invalid_checkout_access_form = \EED_Invalid_Checkout_Access::getInvalidCheckoutAccess(); |
|
92 | + return $invalid_checkout_access_form->processForm($EE_Registration_Config); |
|
93 | + } |
|
94 | 94 | } |
@@ -60,7 +60,7 @@ |
||
60 | 60 | */ |
61 | 61 | public static function getInvalidCheckoutAccess() |
62 | 62 | { |
63 | - if (! self::$invalid_checkout_access_form instanceof InvalidCheckoutAccess) { |
|
63 | + if ( ! self::$invalid_checkout_access_form instanceof InvalidCheckoutAccess) { |
|
64 | 64 | self::$invalid_checkout_access_form = new InvalidCheckoutAccess(); |
65 | 65 | } |
66 | 66 | return self::$invalid_checkout_access_form; |
@@ -12,69 +12,69 @@ |
||
12 | 12 | { |
13 | 13 | |
14 | 14 | |
15 | - /** |
|
16 | - * @return EED_Csv |
|
17 | - */ |
|
18 | - public static function instance() |
|
19 | - { |
|
20 | - return parent::get_instance(__CLASS__); |
|
21 | - } |
|
15 | + /** |
|
16 | + * @return EED_Csv |
|
17 | + */ |
|
18 | + public static function instance() |
|
19 | + { |
|
20 | + return parent::get_instance(__CLASS__); |
|
21 | + } |
|
22 | 22 | |
23 | 23 | |
24 | - /** |
|
25 | - * set_hooks - for hooking into EE Core, other modules, etc |
|
26 | - * |
|
27 | - * @access public |
|
28 | - * @return void |
|
29 | - */ |
|
30 | - public static function set_hooks() |
|
31 | - { |
|
32 | - } |
|
24 | + /** |
|
25 | + * set_hooks - for hooking into EE Core, other modules, etc |
|
26 | + * |
|
27 | + * @access public |
|
28 | + * @return void |
|
29 | + */ |
|
30 | + public static function set_hooks() |
|
31 | + { |
|
32 | + } |
|
33 | 33 | |
34 | - /** |
|
35 | - * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
36 | - * |
|
37 | - * @access public |
|
38 | - * @return void |
|
39 | - */ |
|
40 | - public static function set_hooks_admin() |
|
41 | - { |
|
42 | - } |
|
34 | + /** |
|
35 | + * set_hooks_admin - for hooking into EE Admin Core, other modules, etc |
|
36 | + * |
|
37 | + * @access public |
|
38 | + * @return void |
|
39 | + */ |
|
40 | + public static function set_hooks_admin() |
|
41 | + { |
|
42 | + } |
|
43 | 43 | |
44 | 44 | |
45 | - /** |
|
46 | - * run - initial module setup |
|
47 | - * |
|
48 | - * @access public |
|
49 | - * @return void |
|
50 | - */ |
|
51 | - public function run($WP) |
|
52 | - { |
|
53 | - } |
|
45 | + /** |
|
46 | + * run - initial module setup |
|
47 | + * |
|
48 | + * @access public |
|
49 | + * @return void |
|
50 | + */ |
|
51 | + public function run($WP) |
|
52 | + { |
|
53 | + } |
|
54 | 54 | |
55 | 55 | |
56 | - /** |
|
57 | - * export |
|
58 | - * |
|
59 | - * @access public |
|
60 | - * @return void |
|
61 | - */ |
|
62 | - public function export() |
|
63 | - { |
|
64 | - $Export = EE_Registry::instance()->load_class('Export'); |
|
65 | - $Export->export(); |
|
66 | - } |
|
56 | + /** |
|
57 | + * export |
|
58 | + * |
|
59 | + * @access public |
|
60 | + * @return void |
|
61 | + */ |
|
62 | + public function export() |
|
63 | + { |
|
64 | + $Export = EE_Registry::instance()->load_class('Export'); |
|
65 | + $Export->export(); |
|
66 | + } |
|
67 | 67 | |
68 | 68 | |
69 | - /** |
|
70 | - * import |
|
71 | - * |
|
72 | - * @access public |
|
73 | - * @return void |
|
74 | - */ |
|
75 | - public function import() |
|
76 | - { |
|
77 | - $Import = EE_Registry::instance()->load_class('Import'); |
|
78 | - $Import->import(); |
|
79 | - } |
|
69 | + /** |
|
70 | + * import |
|
71 | + * |
|
72 | + * @access public |
|
73 | + * @return void |
|
74 | + */ |
|
75 | + public function import() |
|
76 | + { |
|
77 | + $Import = EE_Registry::instance()->load_class('Import'); |
|
78 | + $Import->import(); |
|
79 | + } |
|
80 | 80 | } |