@@ -12,12 +12,12 @@ |
||
12 | 12 | */ |
13 | 13 | class EE_Admin_Page_Sub_Menu extends AdminMenuSubItem |
14 | 14 | { |
15 | - /** |
|
16 | - * @return string |
|
17 | - * @deprecated $VID:$ |
|
18 | - */ |
|
19 | - protected function _add_menu_page() |
|
20 | - { |
|
21 | - return $this->registerMenuItem(); |
|
22 | - } |
|
15 | + /** |
|
16 | + * @return string |
|
17 | + * @deprecated $VID:$ |
|
18 | + */ |
|
19 | + protected function _add_menu_page() |
|
20 | + { |
|
21 | + return $this->registerMenuItem(); |
|
22 | + } |
|
23 | 23 | } |
@@ -16,51 +16,51 @@ |
||
16 | 16 | */ |
17 | 17 | class Pricing_Admin_Page_Init extends EE_Admin_Page_Init |
18 | 18 | { |
19 | - /** |
|
20 | - * @Constructor |
|
21 | - */ |
|
22 | - public function __construct() |
|
23 | - { |
|
24 | - if (! defined('PRICING_PG_SLUG')) { |
|
25 | - define('PRICING_PG_SLUG', 'pricing'); |
|
26 | - define('PRICING_LABEL', esc_html__('Pricing', 'event_espresso')); |
|
27 | - define('PRICING_PG_NAME', ucwords(str_replace('_', '', PRICING_PG_SLUG))); |
|
28 | - define('PRICING_ADMIN', EE_CORE_CAF_ADMIN . 'new/' . PRICING_PG_SLUG . '/'); |
|
29 | - define('PRICING_ADMIN_URL', admin_url('admin.php?page=' . PRICING_PG_SLUG)); |
|
30 | - define('PRICING_ASSETS_PATH', PRICING_ADMIN . 'assets/'); |
|
31 | - define('PRICING_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/assets/'); |
|
32 | - define('PRICING_TEMPLATE_PATH', PRICING_ADMIN . 'templates/'); |
|
33 | - define('PRICING_TEMPLATE_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/templates/'); |
|
34 | - } |
|
35 | - parent::__construct(); |
|
36 | - $this->_folder_path = EE_CORE_CAF_ADMIN . 'new/' . $this->_folder_name . '/'; |
|
37 | - } |
|
19 | + /** |
|
20 | + * @Constructor |
|
21 | + */ |
|
22 | + public function __construct() |
|
23 | + { |
|
24 | + if (! defined('PRICING_PG_SLUG')) { |
|
25 | + define('PRICING_PG_SLUG', 'pricing'); |
|
26 | + define('PRICING_LABEL', esc_html__('Pricing', 'event_espresso')); |
|
27 | + define('PRICING_PG_NAME', ucwords(str_replace('_', '', PRICING_PG_SLUG))); |
|
28 | + define('PRICING_ADMIN', EE_CORE_CAF_ADMIN . 'new/' . PRICING_PG_SLUG . '/'); |
|
29 | + define('PRICING_ADMIN_URL', admin_url('admin.php?page=' . PRICING_PG_SLUG)); |
|
30 | + define('PRICING_ASSETS_PATH', PRICING_ADMIN . 'assets/'); |
|
31 | + define('PRICING_ASSETS_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/assets/'); |
|
32 | + define('PRICING_TEMPLATE_PATH', PRICING_ADMIN . 'templates/'); |
|
33 | + define('PRICING_TEMPLATE_URL', EE_CORE_CAF_ADMIN_URL . 'new/' . PRICING_PG_SLUG . '/templates/'); |
|
34 | + } |
|
35 | + parent::__construct(); |
|
36 | + $this->_folder_path = EE_CORE_CAF_ADMIN . 'new/' . $this->_folder_name . '/'; |
|
37 | + } |
|
38 | 38 | |
39 | 39 | |
40 | - protected function _set_init_properties() |
|
41 | - { |
|
42 | - $this->label = PRICING_LABEL; |
|
43 | - } |
|
40 | + protected function _set_init_properties() |
|
41 | + { |
|
42 | + $this->label = PRICING_LABEL; |
|
43 | + } |
|
44 | 44 | |
45 | 45 | |
46 | - /** |
|
47 | - * @return array|void |
|
48 | - * @throws EE_Error |
|
49 | - * @since $VID:$ |
|
50 | - */ |
|
51 | - protected function _set_menu_map() |
|
52 | - { |
|
53 | - $this->_menu_map = new AdminMenuSubItem( |
|
54 | - array( |
|
55 | - 'menu_group' => 'management', |
|
56 | - 'menu_order' => 20, |
|
57 | - 'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_ONLY, |
|
58 | - 'parent_slug' => 'espresso_events', |
|
59 | - 'menu_slug' => PRICING_PG_SLUG, |
|
60 | - 'menu_label' => PRICING_LABEL, |
|
61 | - 'capability' => 'ee_read_default_prices', |
|
62 | - 'admin_init_page' => $this, |
|
63 | - ) |
|
64 | - ); |
|
65 | - } |
|
46 | + /** |
|
47 | + * @return array|void |
|
48 | + * @throws EE_Error |
|
49 | + * @since $VID:$ |
|
50 | + */ |
|
51 | + protected function _set_menu_map() |
|
52 | + { |
|
53 | + $this->_menu_map = new AdminMenuSubItem( |
|
54 | + array( |
|
55 | + 'menu_group' => 'management', |
|
56 | + 'menu_order' => 20, |
|
57 | + 'show_on_menu' => AdminMenuItem::DISPLAY_BLOG_ONLY, |
|
58 | + 'parent_slug' => 'espresso_events', |
|
59 | + 'menu_slug' => PRICING_PG_SLUG, |
|
60 | + 'menu_label' => PRICING_LABEL, |
|
61 | + 'capability' => 'ee_read_default_prices', |
|
62 | + 'admin_init_page' => $this, |
|
63 | + ) |
|
64 | + ); |
|
65 | + } |
|
66 | 66 | } |
@@ -23,332 +23,332 @@ |
||
23 | 23 | abstract class AssetManager implements AssetManagerInterface |
24 | 24 | { |
25 | 25 | |
26 | - /** |
|
27 | - * @var AssetCollection|Asset[] $assets |
|
28 | - */ |
|
29 | - protected $assets; |
|
30 | - |
|
31 | - /** |
|
32 | - * @var DomainInterface |
|
33 | - */ |
|
34 | - protected $domain; |
|
35 | - |
|
36 | - /** |
|
37 | - * @var Registry $registry |
|
38 | - */ |
|
39 | - protected $registry; |
|
40 | - |
|
41 | - |
|
42 | - /** |
|
43 | - * AssetRegister constructor. |
|
44 | - * |
|
45 | - * @param DomainInterface $domain |
|
46 | - * @param AssetCollection $assets |
|
47 | - * @param Registry $registry |
|
48 | - */ |
|
49 | - public function __construct(DomainInterface $domain, AssetCollection $assets, Registry $registry) |
|
50 | - { |
|
51 | - $this->domain = $domain; |
|
52 | - $this->assets = $assets; |
|
53 | - $this->registry = $registry; |
|
54 | - $this->registry->addAssetCollection($assets); |
|
55 | - add_action('wp_enqueue_scripts', array($this, 'addAssets'), 2); |
|
56 | - add_action('admin_enqueue_scripts', array($this, 'addAssets'), 2); |
|
57 | - } |
|
58 | - |
|
59 | - |
|
60 | - /** |
|
61 | - * @return AssetCollection |
|
62 | - */ |
|
63 | - public function getAssets() |
|
64 | - { |
|
65 | - return $this->assets; |
|
66 | - } |
|
67 | - |
|
68 | - |
|
69 | - /** |
|
70 | - * @since 4.9.71.p |
|
71 | - * @return string |
|
72 | - */ |
|
73 | - public function assetNamespace() |
|
74 | - { |
|
75 | - return $this->domain->assetNamespace(); |
|
76 | - } |
|
77 | - |
|
78 | - |
|
79 | - /** |
|
80 | - * @param string $handle |
|
81 | - * @param string $source |
|
82 | - * @param array $dependencies |
|
83 | - * @param bool $load_in_footer |
|
84 | - * @param string $version |
|
85 | - * @return JavascriptAsset |
|
86 | - * @throws DuplicateCollectionIdentifierException |
|
87 | - * @throws InvalidDataTypeException |
|
88 | - * @throws InvalidEntityException |
|
89 | - * @throws DomainException |
|
90 | - * @since 4.9.62.p |
|
91 | - */ |
|
92 | - public function addJavascript( |
|
93 | - $handle, |
|
94 | - $source, |
|
95 | - array $dependencies = array(), |
|
96 | - $load_in_footer = true, |
|
97 | - $version = '' |
|
98 | - ) { |
|
99 | - $asset = new JavascriptAsset( |
|
100 | - $handle, |
|
101 | - $source, |
|
102 | - array_unique($dependencies), |
|
103 | - $load_in_footer, |
|
104 | - $this->domain, |
|
105 | - $version |
|
106 | - ); |
|
107 | - $this->assets->add($asset, $handle); |
|
108 | - return $asset; |
|
109 | - } |
|
110 | - |
|
111 | - |
|
112 | - /** |
|
113 | - * Used to register a javascript asset where everything is dynamically derived from the given handle. |
|
114 | - * |
|
115 | - * @param string $handle |
|
116 | - * @param string|array $extra_dependencies |
|
117 | - * @return JavascriptAsset |
|
118 | - * @throws DuplicateCollectionIdentifierException |
|
119 | - * @throws InvalidDataTypeException |
|
120 | - * @throws InvalidEntityException |
|
121 | - * @throws DomainException |
|
122 | - */ |
|
123 | - public function addJs($handle, $extra_dependencies = []) |
|
124 | - { |
|
125 | - $details = $this->getAssetDetails( |
|
126 | - Asset::TYPE_JS, |
|
127 | - $handle, |
|
128 | - $extra_dependencies |
|
129 | - ); |
|
130 | - $source = $this->registry->getJsUrl($this->domain->assetNamespace(), $handle); |
|
131 | - return $this->addJavascript( |
|
132 | - $handle, |
|
133 | - $source, |
|
134 | - $details['dependencies'], |
|
135 | - true, |
|
136 | - $details['version'] |
|
137 | - ); |
|
138 | - } |
|
139 | - |
|
140 | - |
|
141 | - /** |
|
142 | - * @param string $handle |
|
143 | - * @param array $dependencies |
|
144 | - * @param bool $load_in_footer |
|
145 | - * @param string $version |
|
146 | - * @return JavascriptAsset |
|
147 | - * @throws DomainException |
|
148 | - * @throws DuplicateCollectionIdentifierException |
|
149 | - * @throws InvalidDataTypeException |
|
150 | - * @throws InvalidEntityException |
|
151 | - * @since 4.9.71.p |
|
152 | - */ |
|
153 | - public function addVendorJavascript( |
|
154 | - $handle, |
|
155 | - array $dependencies = array(), |
|
156 | - $load_in_footer = true, |
|
157 | - $version = '' |
|
158 | - ) { |
|
159 | - $dev_suffix = wp_scripts_get_suffix('dev'); |
|
160 | - $vendor_path = $this->domain->pluginUrl() . 'assets/vendor/'; |
|
161 | - return $this->addJavascript( |
|
162 | - $handle, |
|
163 | - "{$vendor_path}{$handle}{$dev_suffix}". Asset::EXT_JS, |
|
164 | - $dependencies, |
|
165 | - $load_in_footer, |
|
166 | - $version |
|
167 | - ); |
|
168 | - } |
|
169 | - |
|
170 | - |
|
171 | - /** |
|
172 | - * @param string $handle |
|
173 | - * @param string $source |
|
174 | - * @param array $dependencies |
|
175 | - * @param string $media |
|
176 | - * @param string $version |
|
177 | - * @return StylesheetAsset |
|
178 | - * @throws DomainException |
|
179 | - * @throws DuplicateCollectionIdentifierException |
|
180 | - * @throws InvalidDataTypeException |
|
181 | - * @throws InvalidEntityException |
|
182 | - * @since 4.9.62.p |
|
183 | - */ |
|
184 | - public function addStylesheet( |
|
185 | - $handle, |
|
186 | - $source, |
|
187 | - array $dependencies = array(), |
|
188 | - $media = 'all', |
|
189 | - $version = '' |
|
190 | - ) { |
|
191 | - $asset = new StylesheetAsset( |
|
192 | - $handle, |
|
193 | - $source, |
|
194 | - array_unique($dependencies), |
|
195 | - $this->domain, |
|
196 | - $media, |
|
197 | - $version |
|
198 | - ); |
|
199 | - $this->assets->add($asset, $handle); |
|
200 | - return $asset; |
|
201 | - } |
|
202 | - |
|
203 | - |
|
204 | - /** |
|
205 | - * Used to register a css asset where everything is dynamically derived from the given handle. |
|
206 | - * |
|
207 | - * @param string $handle |
|
208 | - * @param string|array $extra_dependencies |
|
209 | - * @return StylesheetAsset |
|
210 | - * @throws DuplicateCollectionIdentifierException |
|
211 | - * @throws InvalidDataTypeException |
|
212 | - * @throws InvalidEntityException |
|
213 | - * @throws DomainException |
|
214 | - */ |
|
215 | - public function addCss($handle, $extra_dependencies = []) |
|
216 | - { |
|
217 | - $details = $this->getAssetDetails( |
|
218 | - Asset::TYPE_CSS, |
|
219 | - $handle, |
|
220 | - $extra_dependencies |
|
221 | - ); |
|
222 | - return $this->addStylesheet( |
|
223 | - $handle, |
|
224 | - $this->registry->getCssUrl($this->domain->assetNamespace(), $handle), |
|
225 | - $details['dependencies'], |
|
226 | - 'all', |
|
227 | - $details['version'] |
|
228 | - ); |
|
229 | - } |
|
230 | - |
|
231 | - |
|
232 | - /** |
|
233 | - * @param string $handle |
|
234 | - * @return bool |
|
235 | - * @since 4.9.62.p |
|
236 | - */ |
|
237 | - public function enqueueAsset($handle) |
|
238 | - { |
|
239 | - if ($this->assets->has($handle)) { |
|
240 | - /** @var Asset $asset */ |
|
241 | - $asset = $this->assets->get($handle); |
|
242 | - if ($asset instanceof BrowserAsset && $asset->isRegistered()) { |
|
243 | - $asset->enqueueAsset(); |
|
244 | - return true; |
|
245 | - } |
|
246 | - } |
|
247 | - return false; |
|
248 | - } |
|
249 | - |
|
250 | - |
|
251 | - /** |
|
252 | - * @return void |
|
253 | - * @since $VID:$ |
|
254 | - */ |
|
255 | - public function enqueueBrowserAssets() |
|
256 | - { |
|
257 | - foreach ($this->assets as $asset) { |
|
258 | - if ($asset instanceof BrowserAsset && $asset->isRegistered()) { |
|
259 | - $asset->enqueueAsset(); |
|
260 | - } |
|
261 | - } |
|
262 | - } |
|
263 | - |
|
264 | - |
|
265 | - /** |
|
266 | - * @param string $asset_type |
|
267 | - * @param string $handle |
|
268 | - * @param array $extra_dependencies |
|
269 | - * @return array |
|
270 | - * @since 4.10.2.p |
|
271 | - */ |
|
272 | - private function getAssetDetails($asset_type, $handle, $extra_dependencies = []) |
|
273 | - { |
|
274 | - $getAssetDetails = ''; |
|
275 | - switch ($asset_type) { |
|
276 | - case Asset::TYPE_JS : |
|
277 | - $getAssetDetails = 'getJsAssetDetails'; |
|
278 | - break; |
|
279 | - case Asset::TYPE_CSS : |
|
280 | - $getAssetDetails = 'getCssAssetDetails'; |
|
281 | - break; |
|
282 | - } |
|
283 | - if ($getAssetDetails === '') { |
|
284 | - return ['dependencies' => [], 'version' => '']; |
|
285 | - } |
|
286 | - $details = $this->registry->$getAssetDetails( |
|
287 | - $this->domain->assetNamespace(), |
|
288 | - $handle |
|
289 | - ); |
|
290 | - $details['dependencies'] = isset($details['dependencies']) |
|
291 | - ? $details['dependencies'] |
|
292 | - : []; |
|
293 | - $details['version'] = isset($details['version']) |
|
294 | - ? $details['version'] |
|
295 | - : ''; |
|
296 | - $details['dependencies'] = ! empty($extra_dependencies) |
|
297 | - ? array_merge($details['dependencies'], (array) $extra_dependencies) |
|
298 | - : $details['dependencies']; |
|
299 | - return $details; |
|
300 | - |
|
301 | - } |
|
302 | - |
|
303 | - |
|
304 | - /** |
|
305 | - * @param string $handle |
|
306 | - * @return bool |
|
307 | - * @throws DomainException |
|
308 | - */ |
|
309 | - public function verifyAssetIsRegistered($handle) |
|
310 | - { |
|
311 | - if (wp_script_is($handle, 'registered')) { |
|
312 | - return true; |
|
313 | - } |
|
314 | - if (WP_DEBUG) { |
|
315 | - throw new DomainException( |
|
316 | - sprintf( |
|
317 | - esc_html__( |
|
318 | - 'The "%1$s" script is not registered when it should be!%2$s |
|
26 | + /** |
|
27 | + * @var AssetCollection|Asset[] $assets |
|
28 | + */ |
|
29 | + protected $assets; |
|
30 | + |
|
31 | + /** |
|
32 | + * @var DomainInterface |
|
33 | + */ |
|
34 | + protected $domain; |
|
35 | + |
|
36 | + /** |
|
37 | + * @var Registry $registry |
|
38 | + */ |
|
39 | + protected $registry; |
|
40 | + |
|
41 | + |
|
42 | + /** |
|
43 | + * AssetRegister constructor. |
|
44 | + * |
|
45 | + * @param DomainInterface $domain |
|
46 | + * @param AssetCollection $assets |
|
47 | + * @param Registry $registry |
|
48 | + */ |
|
49 | + public function __construct(DomainInterface $domain, AssetCollection $assets, Registry $registry) |
|
50 | + { |
|
51 | + $this->domain = $domain; |
|
52 | + $this->assets = $assets; |
|
53 | + $this->registry = $registry; |
|
54 | + $this->registry->addAssetCollection($assets); |
|
55 | + add_action('wp_enqueue_scripts', array($this, 'addAssets'), 2); |
|
56 | + add_action('admin_enqueue_scripts', array($this, 'addAssets'), 2); |
|
57 | + } |
|
58 | + |
|
59 | + |
|
60 | + /** |
|
61 | + * @return AssetCollection |
|
62 | + */ |
|
63 | + public function getAssets() |
|
64 | + { |
|
65 | + return $this->assets; |
|
66 | + } |
|
67 | + |
|
68 | + |
|
69 | + /** |
|
70 | + * @since 4.9.71.p |
|
71 | + * @return string |
|
72 | + */ |
|
73 | + public function assetNamespace() |
|
74 | + { |
|
75 | + return $this->domain->assetNamespace(); |
|
76 | + } |
|
77 | + |
|
78 | + |
|
79 | + /** |
|
80 | + * @param string $handle |
|
81 | + * @param string $source |
|
82 | + * @param array $dependencies |
|
83 | + * @param bool $load_in_footer |
|
84 | + * @param string $version |
|
85 | + * @return JavascriptAsset |
|
86 | + * @throws DuplicateCollectionIdentifierException |
|
87 | + * @throws InvalidDataTypeException |
|
88 | + * @throws InvalidEntityException |
|
89 | + * @throws DomainException |
|
90 | + * @since 4.9.62.p |
|
91 | + */ |
|
92 | + public function addJavascript( |
|
93 | + $handle, |
|
94 | + $source, |
|
95 | + array $dependencies = array(), |
|
96 | + $load_in_footer = true, |
|
97 | + $version = '' |
|
98 | + ) { |
|
99 | + $asset = new JavascriptAsset( |
|
100 | + $handle, |
|
101 | + $source, |
|
102 | + array_unique($dependencies), |
|
103 | + $load_in_footer, |
|
104 | + $this->domain, |
|
105 | + $version |
|
106 | + ); |
|
107 | + $this->assets->add($asset, $handle); |
|
108 | + return $asset; |
|
109 | + } |
|
110 | + |
|
111 | + |
|
112 | + /** |
|
113 | + * Used to register a javascript asset where everything is dynamically derived from the given handle. |
|
114 | + * |
|
115 | + * @param string $handle |
|
116 | + * @param string|array $extra_dependencies |
|
117 | + * @return JavascriptAsset |
|
118 | + * @throws DuplicateCollectionIdentifierException |
|
119 | + * @throws InvalidDataTypeException |
|
120 | + * @throws InvalidEntityException |
|
121 | + * @throws DomainException |
|
122 | + */ |
|
123 | + public function addJs($handle, $extra_dependencies = []) |
|
124 | + { |
|
125 | + $details = $this->getAssetDetails( |
|
126 | + Asset::TYPE_JS, |
|
127 | + $handle, |
|
128 | + $extra_dependencies |
|
129 | + ); |
|
130 | + $source = $this->registry->getJsUrl($this->domain->assetNamespace(), $handle); |
|
131 | + return $this->addJavascript( |
|
132 | + $handle, |
|
133 | + $source, |
|
134 | + $details['dependencies'], |
|
135 | + true, |
|
136 | + $details['version'] |
|
137 | + ); |
|
138 | + } |
|
139 | + |
|
140 | + |
|
141 | + /** |
|
142 | + * @param string $handle |
|
143 | + * @param array $dependencies |
|
144 | + * @param bool $load_in_footer |
|
145 | + * @param string $version |
|
146 | + * @return JavascriptAsset |
|
147 | + * @throws DomainException |
|
148 | + * @throws DuplicateCollectionIdentifierException |
|
149 | + * @throws InvalidDataTypeException |
|
150 | + * @throws InvalidEntityException |
|
151 | + * @since 4.9.71.p |
|
152 | + */ |
|
153 | + public function addVendorJavascript( |
|
154 | + $handle, |
|
155 | + array $dependencies = array(), |
|
156 | + $load_in_footer = true, |
|
157 | + $version = '' |
|
158 | + ) { |
|
159 | + $dev_suffix = wp_scripts_get_suffix('dev'); |
|
160 | + $vendor_path = $this->domain->pluginUrl() . 'assets/vendor/'; |
|
161 | + return $this->addJavascript( |
|
162 | + $handle, |
|
163 | + "{$vendor_path}{$handle}{$dev_suffix}". Asset::EXT_JS, |
|
164 | + $dependencies, |
|
165 | + $load_in_footer, |
|
166 | + $version |
|
167 | + ); |
|
168 | + } |
|
169 | + |
|
170 | + |
|
171 | + /** |
|
172 | + * @param string $handle |
|
173 | + * @param string $source |
|
174 | + * @param array $dependencies |
|
175 | + * @param string $media |
|
176 | + * @param string $version |
|
177 | + * @return StylesheetAsset |
|
178 | + * @throws DomainException |
|
179 | + * @throws DuplicateCollectionIdentifierException |
|
180 | + * @throws InvalidDataTypeException |
|
181 | + * @throws InvalidEntityException |
|
182 | + * @since 4.9.62.p |
|
183 | + */ |
|
184 | + public function addStylesheet( |
|
185 | + $handle, |
|
186 | + $source, |
|
187 | + array $dependencies = array(), |
|
188 | + $media = 'all', |
|
189 | + $version = '' |
|
190 | + ) { |
|
191 | + $asset = new StylesheetAsset( |
|
192 | + $handle, |
|
193 | + $source, |
|
194 | + array_unique($dependencies), |
|
195 | + $this->domain, |
|
196 | + $media, |
|
197 | + $version |
|
198 | + ); |
|
199 | + $this->assets->add($asset, $handle); |
|
200 | + return $asset; |
|
201 | + } |
|
202 | + |
|
203 | + |
|
204 | + /** |
|
205 | + * Used to register a css asset where everything is dynamically derived from the given handle. |
|
206 | + * |
|
207 | + * @param string $handle |
|
208 | + * @param string|array $extra_dependencies |
|
209 | + * @return StylesheetAsset |
|
210 | + * @throws DuplicateCollectionIdentifierException |
|
211 | + * @throws InvalidDataTypeException |
|
212 | + * @throws InvalidEntityException |
|
213 | + * @throws DomainException |
|
214 | + */ |
|
215 | + public function addCss($handle, $extra_dependencies = []) |
|
216 | + { |
|
217 | + $details = $this->getAssetDetails( |
|
218 | + Asset::TYPE_CSS, |
|
219 | + $handle, |
|
220 | + $extra_dependencies |
|
221 | + ); |
|
222 | + return $this->addStylesheet( |
|
223 | + $handle, |
|
224 | + $this->registry->getCssUrl($this->domain->assetNamespace(), $handle), |
|
225 | + $details['dependencies'], |
|
226 | + 'all', |
|
227 | + $details['version'] |
|
228 | + ); |
|
229 | + } |
|
230 | + |
|
231 | + |
|
232 | + /** |
|
233 | + * @param string $handle |
|
234 | + * @return bool |
|
235 | + * @since 4.9.62.p |
|
236 | + */ |
|
237 | + public function enqueueAsset($handle) |
|
238 | + { |
|
239 | + if ($this->assets->has($handle)) { |
|
240 | + /** @var Asset $asset */ |
|
241 | + $asset = $this->assets->get($handle); |
|
242 | + if ($asset instanceof BrowserAsset && $asset->isRegistered()) { |
|
243 | + $asset->enqueueAsset(); |
|
244 | + return true; |
|
245 | + } |
|
246 | + } |
|
247 | + return false; |
|
248 | + } |
|
249 | + |
|
250 | + |
|
251 | + /** |
|
252 | + * @return void |
|
253 | + * @since $VID:$ |
|
254 | + */ |
|
255 | + public function enqueueBrowserAssets() |
|
256 | + { |
|
257 | + foreach ($this->assets as $asset) { |
|
258 | + if ($asset instanceof BrowserAsset && $asset->isRegistered()) { |
|
259 | + $asset->enqueueAsset(); |
|
260 | + } |
|
261 | + } |
|
262 | + } |
|
263 | + |
|
264 | + |
|
265 | + /** |
|
266 | + * @param string $asset_type |
|
267 | + * @param string $handle |
|
268 | + * @param array $extra_dependencies |
|
269 | + * @return array |
|
270 | + * @since 4.10.2.p |
|
271 | + */ |
|
272 | + private function getAssetDetails($asset_type, $handle, $extra_dependencies = []) |
|
273 | + { |
|
274 | + $getAssetDetails = ''; |
|
275 | + switch ($asset_type) { |
|
276 | + case Asset::TYPE_JS : |
|
277 | + $getAssetDetails = 'getJsAssetDetails'; |
|
278 | + break; |
|
279 | + case Asset::TYPE_CSS : |
|
280 | + $getAssetDetails = 'getCssAssetDetails'; |
|
281 | + break; |
|
282 | + } |
|
283 | + if ($getAssetDetails === '') { |
|
284 | + return ['dependencies' => [], 'version' => '']; |
|
285 | + } |
|
286 | + $details = $this->registry->$getAssetDetails( |
|
287 | + $this->domain->assetNamespace(), |
|
288 | + $handle |
|
289 | + ); |
|
290 | + $details['dependencies'] = isset($details['dependencies']) |
|
291 | + ? $details['dependencies'] |
|
292 | + : []; |
|
293 | + $details['version'] = isset($details['version']) |
|
294 | + ? $details['version'] |
|
295 | + : ''; |
|
296 | + $details['dependencies'] = ! empty($extra_dependencies) |
|
297 | + ? array_merge($details['dependencies'], (array) $extra_dependencies) |
|
298 | + : $details['dependencies']; |
|
299 | + return $details; |
|
300 | + |
|
301 | + } |
|
302 | + |
|
303 | + |
|
304 | + /** |
|
305 | + * @param string $handle |
|
306 | + * @return bool |
|
307 | + * @throws DomainException |
|
308 | + */ |
|
309 | + public function verifyAssetIsRegistered($handle) |
|
310 | + { |
|
311 | + if (wp_script_is($handle, 'registered')) { |
|
312 | + return true; |
|
313 | + } |
|
314 | + if (WP_DEBUG) { |
|
315 | + throw new DomainException( |
|
316 | + sprintf( |
|
317 | + esc_html__( |
|
318 | + 'The "%1$s" script is not registered when it should be!%2$s |
|
319 | 319 | Are you running the Barista plugin for development purposes? |
320 | 320 | If so, then you need to build the appropriate assets for this domain.%2$s |
321 | 321 | If you are seeing this error on a live website, then you should not have |
322 | 322 | the WP_DEBUG constant in your wp-config.php file set to "true". |
323 | 323 | Please contact Event Espresso support for more information.', |
324 | - 'event_espresso' |
|
325 | - ), |
|
326 | - $handle, |
|
327 | - '<br />' |
|
328 | - ) |
|
329 | - ); |
|
330 | - } |
|
331 | - return false; |
|
332 | - } |
|
333 | - |
|
334 | - |
|
335 | - /**************** deprecated ****************/ |
|
336 | - |
|
337 | - |
|
338 | - /** |
|
339 | - * @return void |
|
340 | - * @deprecated $VID:$ |
|
341 | - */ |
|
342 | - public function addManifestFile() |
|
343 | - { |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - /** |
|
348 | - * @return void |
|
349 | - * @deprecated $VID:$ |
|
350 | - */ |
|
351 | - public function getManifestFile() |
|
352 | - { |
|
353 | - } |
|
324 | + 'event_espresso' |
|
325 | + ), |
|
326 | + $handle, |
|
327 | + '<br />' |
|
328 | + ) |
|
329 | + ); |
|
330 | + } |
|
331 | + return false; |
|
332 | + } |
|
333 | + |
|
334 | + |
|
335 | + /**************** deprecated ****************/ |
|
336 | + |
|
337 | + |
|
338 | + /** |
|
339 | + * @return void |
|
340 | + * @deprecated $VID:$ |
|
341 | + */ |
|
342 | + public function addManifestFile() |
|
343 | + { |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + /** |
|
348 | + * @return void |
|
349 | + * @deprecated $VID:$ |
|
350 | + */ |
|
351 | + public function getManifestFile() |
|
352 | + { |
|
353 | + } |
|
354 | 354 | } |
@@ -25,581 +25,581 @@ |
||
25 | 25 | class Registry |
26 | 26 | { |
27 | 27 | |
28 | - const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json'; |
|
29 | - |
|
30 | - /** |
|
31 | - * @var AssetCollection[] $assets |
|
32 | - */ |
|
33 | - protected $assets = []; |
|
34 | - |
|
35 | - /** |
|
36 | - * @var AssetManifestInterface |
|
37 | - */ |
|
38 | - private $asset_manifest; |
|
39 | - |
|
40 | - /** |
|
41 | - * This holds the js_data data object that will be exposed on pages that enqueue the `eejs-core` script. |
|
42 | - * |
|
43 | - * @var array |
|
44 | - */ |
|
45 | - protected $js_data = []; |
|
46 | - |
|
47 | - /** |
|
48 | - * This keeps track of all scripts with registered data. It is used to prevent duplicate data objects setup in the |
|
49 | - * page source. |
|
50 | - * |
|
51 | - * @var array |
|
52 | - */ |
|
53 | - private $script_handles_with_data = []; |
|
54 | - |
|
55 | - |
|
56 | - /** |
|
57 | - * Registry constructor. |
|
58 | - * Hooking into WP actions for script registry. |
|
59 | - * |
|
60 | - * @param AssetCollection $assets |
|
61 | - * @param AssetManifestInterface $asset_manifest |
|
62 | - * @throws InvalidArgumentException |
|
63 | - * @throws InvalidDataTypeException |
|
64 | - * @throws InvalidInterfaceException |
|
65 | - */ |
|
66 | - public function __construct(AssetCollection $assets, AssetManifestInterface $asset_manifest) |
|
67 | - { |
|
68 | - $this->addAssetCollection($assets); |
|
69 | - $this->asset_manifest = $asset_manifest; |
|
70 | - $this->asset_manifest->initialize(); |
|
71 | - add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 4); |
|
72 | - add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 4); |
|
73 | - add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 5); |
|
74 | - add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 5); |
|
75 | - add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
76 | - add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
77 | - } |
|
78 | - |
|
79 | - |
|
80 | - /** |
|
81 | - * @param AssetCollection $asset_collection |
|
82 | - */ |
|
83 | - public function addAssetCollection(AssetCollection $asset_collection) |
|
84 | - { |
|
85 | - $id = $asset_collection->collectionIdentifier(); |
|
86 | - if (! array_key_exists($id, $this->assets)) { |
|
87 | - $this->assets[ $id ] = $asset_collection; |
|
88 | - } |
|
89 | - } |
|
90 | - |
|
91 | - |
|
92 | - |
|
93 | - /** |
|
94 | - * Callback for the wp_enqueue_scripts actions used to register assets. |
|
95 | - * |
|
96 | - * @throws Exception |
|
97 | - * @since 4.9.62.p |
|
98 | - */ |
|
99 | - public function registerScriptsAndStyles() |
|
100 | - { |
|
101 | - try { |
|
102 | - foreach ($this->assets as $asset_collection) { |
|
103 | - $this->registerScripts($asset_collection->getJavascriptAssets()); |
|
104 | - $this->registerStyles($asset_collection->getStylesheetAssets()); |
|
105 | - } |
|
106 | - } catch (Exception $exception) { |
|
107 | - new ExceptionStackTraceDisplay($exception); |
|
108 | - } |
|
109 | - } |
|
110 | - |
|
111 | - |
|
112 | - /** |
|
113 | - * Registers JS assets with WP core |
|
114 | - * |
|
115 | - * @param JavascriptAsset[] $scripts |
|
116 | - * @throws AssetRegistrationException |
|
117 | - * @throws InvalidDataTypeException |
|
118 | - * @throws DomainException |
|
119 | - * @since 4.9.62.p |
|
120 | - */ |
|
121 | - public function registerScripts(array $scripts) |
|
122 | - { |
|
123 | - foreach ($scripts as $script) { |
|
124 | - // skip to next script if this has already been done |
|
125 | - if ($script->isRegistered()) { |
|
126 | - continue; |
|
127 | - } |
|
128 | - do_action( |
|
129 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script', |
|
130 | - $script |
|
131 | - ); |
|
132 | - $registered = wp_register_script( |
|
133 | - $script->handle(), |
|
134 | - $script->source(), |
|
135 | - $script->dependencies(), |
|
136 | - $script->version(), |
|
137 | - $script->loadInFooter() |
|
138 | - ); |
|
139 | - if (! $registered && $this->debug()) { |
|
140 | - throw new AssetRegistrationException($script->handle()); |
|
141 | - } |
|
142 | - $script->setRegistered($registered); |
|
143 | - if ($script->enqueueImmediately()) { |
|
144 | - wp_enqueue_script($script->handle()); |
|
145 | - } |
|
146 | - do_action( |
|
147 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script', |
|
148 | - $script |
|
149 | - ); |
|
150 | - } |
|
151 | - } |
|
152 | - |
|
153 | - |
|
154 | - /** |
|
155 | - * Registers CSS assets with WP core |
|
156 | - * |
|
157 | - * @param StylesheetAsset[] $styles |
|
158 | - * @throws InvalidDataTypeException |
|
159 | - * @throws DomainException |
|
160 | - * @since 4.9.62.p |
|
161 | - */ |
|
162 | - public function registerStyles(array $styles) |
|
163 | - { |
|
164 | - foreach ($styles as $style) { |
|
165 | - // skip to next style if this has already been done |
|
166 | - if ($style->isRegistered()) { |
|
167 | - continue; |
|
168 | - } |
|
169 | - do_action( |
|
170 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style', |
|
171 | - $style |
|
172 | - ); |
|
173 | - wp_register_style( |
|
174 | - $style->handle(), |
|
175 | - $style->source(), |
|
176 | - $style->dependencies(), |
|
177 | - $style->version(), |
|
178 | - $style->media() |
|
179 | - ); |
|
180 | - $style->setRegistered(); |
|
181 | - if ($style->enqueueImmediately()) { |
|
182 | - wp_enqueue_style($style->handle()); |
|
183 | - } |
|
184 | - do_action( |
|
185 | - 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style', |
|
186 | - $style |
|
187 | - ); |
|
188 | - } |
|
189 | - } |
|
190 | - |
|
191 | - |
|
192 | - /** |
|
193 | - * Call back for the script print in frontend and backend. |
|
194 | - * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point. |
|
195 | - * |
|
196 | - * @throws Exception |
|
197 | - * @since 4.9.31.rc.015 |
|
198 | - */ |
|
199 | - public function enqueueData() |
|
200 | - { |
|
201 | - try { |
|
202 | - $this->removeAlreadyRegisteredDataForScriptHandles(); |
|
203 | - wp_add_inline_script( |
|
204 | - CoreAssetManager::JS_HANDLE_JS_CORE, |
|
205 | - 'var eejsdata=' . wp_json_encode(['data' => $this->js_data]), |
|
206 | - 'before' |
|
207 | - ); |
|
208 | - foreach ($this->assets as $asset_collection) { |
|
209 | - $scripts = $asset_collection->getJavascriptAssetsWithData(); |
|
210 | - foreach ($scripts as $script) { |
|
211 | - $this->addRegisteredScriptHandlesWithData($script->handle()); |
|
212 | - if ($script->hasInlineDataCallback()) { |
|
213 | - $localize = $script->inlineDataCallback(); |
|
214 | - $localize(); |
|
215 | - } |
|
216 | - } |
|
217 | - } |
|
218 | - } catch (Exception $exception) { |
|
219 | - EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
220 | - new ExceptionStackTraceDisplay($exception); |
|
221 | - } |
|
222 | - } |
|
223 | - |
|
224 | - |
|
225 | - /** |
|
226 | - * Used to add data to eejs.data object. |
|
227 | - * Note: Overriding existing data is not allowed. |
|
228 | - * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript. |
|
229 | - * If the data you add is something like this: |
|
230 | - * $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) ); |
|
231 | - * It will be exposed in the page source as: |
|
232 | - * eejs.data.my_plugin_data.foo == gar |
|
233 | - * |
|
234 | - * @param string $key Key used to access your data |
|
235 | - * @param string|array $value Value to attach to key |
|
236 | - * @throws InvalidArgumentException |
|
237 | - */ |
|
238 | - public function addData(string $key, $value) |
|
239 | - { |
|
240 | - if ($this->verifyDataNotExisting($key)) { |
|
241 | - $this->js_data[ $key ] = $value; |
|
242 | - } |
|
243 | - } |
|
244 | - |
|
245 | - |
|
246 | - /** |
|
247 | - * Similar to addData except this allows for users to push values to an existing key where the values on key are |
|
248 | - * elements in an array. |
|
249 | - * |
|
250 | - * When you use this method, the value you include will be merged with the array on $key. |
|
251 | - * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript |
|
252 | - * object like this, eejs.data.test = [ my_data, |
|
253 | - * ] |
|
254 | - * If there has already been a scalar value attached to the data object given key (via addData for instance), then |
|
255 | - * this will throw an exception. |
|
256 | - * |
|
257 | - * Caution: Only add data using this method if you are okay with the potential for additional data added on the same |
|
258 | - * key potentially overriding the existing data on merge (specifically with associative arrays). |
|
259 | - * |
|
260 | - * @param string $key Key to attach data to. |
|
261 | - * @param string|array $value Value being registered. |
|
262 | - * @throws InvalidArgumentException |
|
263 | - */ |
|
264 | - public function pushData(string $key, $value) |
|
265 | - { |
|
266 | - if ( |
|
267 | - isset($this->js_data[ $key ]) |
|
268 | - && ! is_array($this->js_data[ $key ]) |
|
269 | - ) { |
|
270 | - if (! $this->debug()) { |
|
271 | - return; |
|
272 | - } |
|
273 | - throw new InvalidArgumentException( |
|
274 | - sprintf( |
|
275 | - esc_html__( |
|
276 | - 'The value for %1$s is already set and it is not an array. The %2$s method can only be used to |
|
28 | + const FILE_NAME_BUILD_MANIFEST = 'build-manifest.json'; |
|
29 | + |
|
30 | + /** |
|
31 | + * @var AssetCollection[] $assets |
|
32 | + */ |
|
33 | + protected $assets = []; |
|
34 | + |
|
35 | + /** |
|
36 | + * @var AssetManifestInterface |
|
37 | + */ |
|
38 | + private $asset_manifest; |
|
39 | + |
|
40 | + /** |
|
41 | + * This holds the js_data data object that will be exposed on pages that enqueue the `eejs-core` script. |
|
42 | + * |
|
43 | + * @var array |
|
44 | + */ |
|
45 | + protected $js_data = []; |
|
46 | + |
|
47 | + /** |
|
48 | + * This keeps track of all scripts with registered data. It is used to prevent duplicate data objects setup in the |
|
49 | + * page source. |
|
50 | + * |
|
51 | + * @var array |
|
52 | + */ |
|
53 | + private $script_handles_with_data = []; |
|
54 | + |
|
55 | + |
|
56 | + /** |
|
57 | + * Registry constructor. |
|
58 | + * Hooking into WP actions for script registry. |
|
59 | + * |
|
60 | + * @param AssetCollection $assets |
|
61 | + * @param AssetManifestInterface $asset_manifest |
|
62 | + * @throws InvalidArgumentException |
|
63 | + * @throws InvalidDataTypeException |
|
64 | + * @throws InvalidInterfaceException |
|
65 | + */ |
|
66 | + public function __construct(AssetCollection $assets, AssetManifestInterface $asset_manifest) |
|
67 | + { |
|
68 | + $this->addAssetCollection($assets); |
|
69 | + $this->asset_manifest = $asset_manifest; |
|
70 | + $this->asset_manifest->initialize(); |
|
71 | + add_action('wp_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 4); |
|
72 | + add_action('admin_enqueue_scripts', array($this, 'registerScriptsAndStyles'), 4); |
|
73 | + add_action('wp_enqueue_scripts', array($this, 'enqueueData'), 5); |
|
74 | + add_action('admin_enqueue_scripts', array($this, 'enqueueData'), 5); |
|
75 | + add_action('wp_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
76 | + add_action('admin_print_footer_scripts', array($this, 'enqueueData'), 1); |
|
77 | + } |
|
78 | + |
|
79 | + |
|
80 | + /** |
|
81 | + * @param AssetCollection $asset_collection |
|
82 | + */ |
|
83 | + public function addAssetCollection(AssetCollection $asset_collection) |
|
84 | + { |
|
85 | + $id = $asset_collection->collectionIdentifier(); |
|
86 | + if (! array_key_exists($id, $this->assets)) { |
|
87 | + $this->assets[ $id ] = $asset_collection; |
|
88 | + } |
|
89 | + } |
|
90 | + |
|
91 | + |
|
92 | + |
|
93 | + /** |
|
94 | + * Callback for the wp_enqueue_scripts actions used to register assets. |
|
95 | + * |
|
96 | + * @throws Exception |
|
97 | + * @since 4.9.62.p |
|
98 | + */ |
|
99 | + public function registerScriptsAndStyles() |
|
100 | + { |
|
101 | + try { |
|
102 | + foreach ($this->assets as $asset_collection) { |
|
103 | + $this->registerScripts($asset_collection->getJavascriptAssets()); |
|
104 | + $this->registerStyles($asset_collection->getStylesheetAssets()); |
|
105 | + } |
|
106 | + } catch (Exception $exception) { |
|
107 | + new ExceptionStackTraceDisplay($exception); |
|
108 | + } |
|
109 | + } |
|
110 | + |
|
111 | + |
|
112 | + /** |
|
113 | + * Registers JS assets with WP core |
|
114 | + * |
|
115 | + * @param JavascriptAsset[] $scripts |
|
116 | + * @throws AssetRegistrationException |
|
117 | + * @throws InvalidDataTypeException |
|
118 | + * @throws DomainException |
|
119 | + * @since 4.9.62.p |
|
120 | + */ |
|
121 | + public function registerScripts(array $scripts) |
|
122 | + { |
|
123 | + foreach ($scripts as $script) { |
|
124 | + // skip to next script if this has already been done |
|
125 | + if ($script->isRegistered()) { |
|
126 | + continue; |
|
127 | + } |
|
128 | + do_action( |
|
129 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script', |
|
130 | + $script |
|
131 | + ); |
|
132 | + $registered = wp_register_script( |
|
133 | + $script->handle(), |
|
134 | + $script->source(), |
|
135 | + $script->dependencies(), |
|
136 | + $script->version(), |
|
137 | + $script->loadInFooter() |
|
138 | + ); |
|
139 | + if (! $registered && $this->debug()) { |
|
140 | + throw new AssetRegistrationException($script->handle()); |
|
141 | + } |
|
142 | + $script->setRegistered($registered); |
|
143 | + if ($script->enqueueImmediately()) { |
|
144 | + wp_enqueue_script($script->handle()); |
|
145 | + } |
|
146 | + do_action( |
|
147 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__after_script', |
|
148 | + $script |
|
149 | + ); |
|
150 | + } |
|
151 | + } |
|
152 | + |
|
153 | + |
|
154 | + /** |
|
155 | + * Registers CSS assets with WP core |
|
156 | + * |
|
157 | + * @param StylesheetAsset[] $styles |
|
158 | + * @throws InvalidDataTypeException |
|
159 | + * @throws DomainException |
|
160 | + * @since 4.9.62.p |
|
161 | + */ |
|
162 | + public function registerStyles(array $styles) |
|
163 | + { |
|
164 | + foreach ($styles as $style) { |
|
165 | + // skip to next style if this has already been done |
|
166 | + if ($style->isRegistered()) { |
|
167 | + continue; |
|
168 | + } |
|
169 | + do_action( |
|
170 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__before_style', |
|
171 | + $style |
|
172 | + ); |
|
173 | + wp_register_style( |
|
174 | + $style->handle(), |
|
175 | + $style->source(), |
|
176 | + $style->dependencies(), |
|
177 | + $style->version(), |
|
178 | + $style->media() |
|
179 | + ); |
|
180 | + $style->setRegistered(); |
|
181 | + if ($style->enqueueImmediately()) { |
|
182 | + wp_enqueue_style($style->handle()); |
|
183 | + } |
|
184 | + do_action( |
|
185 | + 'AHEE__EventEspresso_core_services_assets_Registry__registerStyles__after_style', |
|
186 | + $style |
|
187 | + ); |
|
188 | + } |
|
189 | + } |
|
190 | + |
|
191 | + |
|
192 | + /** |
|
193 | + * Call back for the script print in frontend and backend. |
|
194 | + * Used to call wp_localize_scripts so that data can be added throughout the runtime until this later hook point. |
|
195 | + * |
|
196 | + * @throws Exception |
|
197 | + * @since 4.9.31.rc.015 |
|
198 | + */ |
|
199 | + public function enqueueData() |
|
200 | + { |
|
201 | + try { |
|
202 | + $this->removeAlreadyRegisteredDataForScriptHandles(); |
|
203 | + wp_add_inline_script( |
|
204 | + CoreAssetManager::JS_HANDLE_JS_CORE, |
|
205 | + 'var eejsdata=' . wp_json_encode(['data' => $this->js_data]), |
|
206 | + 'before' |
|
207 | + ); |
|
208 | + foreach ($this->assets as $asset_collection) { |
|
209 | + $scripts = $asset_collection->getJavascriptAssetsWithData(); |
|
210 | + foreach ($scripts as $script) { |
|
211 | + $this->addRegisteredScriptHandlesWithData($script->handle()); |
|
212 | + if ($script->hasInlineDataCallback()) { |
|
213 | + $localize = $script->inlineDataCallback(); |
|
214 | + $localize(); |
|
215 | + } |
|
216 | + } |
|
217 | + } |
|
218 | + } catch (Exception $exception) { |
|
219 | + EE_Error::add_error($exception->getMessage(), __FILE__, __FUNCTION__, __LINE__); |
|
220 | + new ExceptionStackTraceDisplay($exception); |
|
221 | + } |
|
222 | + } |
|
223 | + |
|
224 | + |
|
225 | + /** |
|
226 | + * Used to add data to eejs.data object. |
|
227 | + * Note: Overriding existing data is not allowed. |
|
228 | + * Data will be accessible as a javascript object when you list `eejs-core` as a dependency for your javascript. |
|
229 | + * If the data you add is something like this: |
|
230 | + * $this->addData( 'my_plugin_data', array( 'foo' => 'gar' ) ); |
|
231 | + * It will be exposed in the page source as: |
|
232 | + * eejs.data.my_plugin_data.foo == gar |
|
233 | + * |
|
234 | + * @param string $key Key used to access your data |
|
235 | + * @param string|array $value Value to attach to key |
|
236 | + * @throws InvalidArgumentException |
|
237 | + */ |
|
238 | + public function addData(string $key, $value) |
|
239 | + { |
|
240 | + if ($this->verifyDataNotExisting($key)) { |
|
241 | + $this->js_data[ $key ] = $value; |
|
242 | + } |
|
243 | + } |
|
244 | + |
|
245 | + |
|
246 | + /** |
|
247 | + * Similar to addData except this allows for users to push values to an existing key where the values on key are |
|
248 | + * elements in an array. |
|
249 | + * |
|
250 | + * When you use this method, the value you include will be merged with the array on $key. |
|
251 | + * So if the $key was 'test' and you added a value of ['my_data'] then it would be represented in the javascript |
|
252 | + * object like this, eejs.data.test = [ my_data, |
|
253 | + * ] |
|
254 | + * If there has already been a scalar value attached to the data object given key (via addData for instance), then |
|
255 | + * this will throw an exception. |
|
256 | + * |
|
257 | + * Caution: Only add data using this method if you are okay with the potential for additional data added on the same |
|
258 | + * key potentially overriding the existing data on merge (specifically with associative arrays). |
|
259 | + * |
|
260 | + * @param string $key Key to attach data to. |
|
261 | + * @param string|array $value Value being registered. |
|
262 | + * @throws InvalidArgumentException |
|
263 | + */ |
|
264 | + public function pushData(string $key, $value) |
|
265 | + { |
|
266 | + if ( |
|
267 | + isset($this->js_data[ $key ]) |
|
268 | + && ! is_array($this->js_data[ $key ]) |
|
269 | + ) { |
|
270 | + if (! $this->debug()) { |
|
271 | + return; |
|
272 | + } |
|
273 | + throw new InvalidArgumentException( |
|
274 | + sprintf( |
|
275 | + esc_html__( |
|
276 | + 'The value for %1$s is already set and it is not an array. The %2$s method can only be used to |
|
277 | 277 | push values to this data element when it is an array.', |
278 | - 'event_espresso' |
|
279 | - ), |
|
280 | - $key, |
|
281 | - __METHOD__ |
|
282 | - ) |
|
283 | - ); |
|
284 | - } |
|
285 | - if (! isset($this->js_data[ $key ])) { |
|
286 | - $this->js_data[ $key ] = is_array($value) ? $value : [$value]; |
|
287 | - } else { |
|
288 | - $this->js_data[ $key ] = array_merge($this->js_data[ $key ], (array) $value); |
|
289 | - } |
|
290 | - } |
|
291 | - |
|
292 | - |
|
293 | - /** |
|
294 | - * Used to set content used by javascript for a template. |
|
295 | - * Note: Overrides of existing registered templates are not allowed. |
|
296 | - * |
|
297 | - * @param string $template_reference |
|
298 | - * @param string $template_content |
|
299 | - * @throws InvalidArgumentException |
|
300 | - */ |
|
301 | - public function addTemplate(string $template_reference, string $template_content) |
|
302 | - { |
|
303 | - if (! isset($this->js_data['templates'])) { |
|
304 | - $this->js_data['templates'] = []; |
|
305 | - } |
|
306 | - //no overrides allowed. |
|
307 | - if (isset($this->js_data['templates'][ $template_reference ])) { |
|
308 | - if (! $this->debug()) { |
|
309 | - return; |
|
310 | - } |
|
311 | - throw new InvalidArgumentException( |
|
312 | - sprintf( |
|
313 | - esc_html__( |
|
314 | - 'The %1$s key already exists for the templates array in the js data array. No overrides are allowed.', |
|
315 | - 'event_espresso' |
|
316 | - ), |
|
317 | - $template_reference |
|
318 | - ) |
|
319 | - ); |
|
320 | - } |
|
321 | - $this->js_data['templates'][ $template_reference ] = $template_content; |
|
322 | - } |
|
323 | - |
|
324 | - |
|
325 | - /** |
|
326 | - * Retrieve the template content already registered for the given reference. |
|
327 | - * |
|
328 | - * @param string $template_reference |
|
329 | - * @return string |
|
330 | - */ |
|
331 | - public function getTemplate(string $template_reference): string |
|
332 | - { |
|
333 | - return $this->js_data['templates'][ $template_reference ] ?? ''; |
|
334 | - } |
|
335 | - |
|
336 | - |
|
337 | - /** |
|
338 | - * Retrieve registered data. |
|
339 | - * |
|
340 | - * @param string $key Name of key to attach data to. |
|
341 | - * @return mixed If there is no for the given key, then false is returned. |
|
342 | - */ |
|
343 | - public function getData(string $key) |
|
344 | - { |
|
345 | - return array_key_exists($key, $this->js_data) ? $this->js_data[ $key ] : null; |
|
346 | - } |
|
347 | - |
|
348 | - |
|
349 | - /** |
|
350 | - * Verifies whether the given data exists already on the js_data array. |
|
351 | - * Overriding data is not allowed. |
|
352 | - * |
|
353 | - * @param string $key Index for data. |
|
354 | - * @return bool If valid then return true. |
|
355 | - * @throws InvalidArgumentException if data already exists. |
|
356 | - */ |
|
357 | - protected function verifyDataNotExisting(string $key): bool |
|
358 | - { |
|
359 | - if (isset($this->js_data[ $key ])) { |
|
360 | - if (! $this->debug()) { |
|
361 | - return false; |
|
362 | - } |
|
363 | - if (is_array($this->js_data[ $key ])) { |
|
364 | - throw new InvalidArgumentException( |
|
365 | - sprintf( |
|
366 | - esc_html__( |
|
367 | - 'The value for %1$s already exists in the Registry::eejs object. |
|
278 | + 'event_espresso' |
|
279 | + ), |
|
280 | + $key, |
|
281 | + __METHOD__ |
|
282 | + ) |
|
283 | + ); |
|
284 | + } |
|
285 | + if (! isset($this->js_data[ $key ])) { |
|
286 | + $this->js_data[ $key ] = is_array($value) ? $value : [$value]; |
|
287 | + } else { |
|
288 | + $this->js_data[ $key ] = array_merge($this->js_data[ $key ], (array) $value); |
|
289 | + } |
|
290 | + } |
|
291 | + |
|
292 | + |
|
293 | + /** |
|
294 | + * Used to set content used by javascript for a template. |
|
295 | + * Note: Overrides of existing registered templates are not allowed. |
|
296 | + * |
|
297 | + * @param string $template_reference |
|
298 | + * @param string $template_content |
|
299 | + * @throws InvalidArgumentException |
|
300 | + */ |
|
301 | + public function addTemplate(string $template_reference, string $template_content) |
|
302 | + { |
|
303 | + if (! isset($this->js_data['templates'])) { |
|
304 | + $this->js_data['templates'] = []; |
|
305 | + } |
|
306 | + //no overrides allowed. |
|
307 | + if (isset($this->js_data['templates'][ $template_reference ])) { |
|
308 | + if (! $this->debug()) { |
|
309 | + return; |
|
310 | + } |
|
311 | + throw new InvalidArgumentException( |
|
312 | + sprintf( |
|
313 | + esc_html__( |
|
314 | + 'The %1$s key already exists for the templates array in the js data array. No overrides are allowed.', |
|
315 | + 'event_espresso' |
|
316 | + ), |
|
317 | + $template_reference |
|
318 | + ) |
|
319 | + ); |
|
320 | + } |
|
321 | + $this->js_data['templates'][ $template_reference ] = $template_content; |
|
322 | + } |
|
323 | + |
|
324 | + |
|
325 | + /** |
|
326 | + * Retrieve the template content already registered for the given reference. |
|
327 | + * |
|
328 | + * @param string $template_reference |
|
329 | + * @return string |
|
330 | + */ |
|
331 | + public function getTemplate(string $template_reference): string |
|
332 | + { |
|
333 | + return $this->js_data['templates'][ $template_reference ] ?? ''; |
|
334 | + } |
|
335 | + |
|
336 | + |
|
337 | + /** |
|
338 | + * Retrieve registered data. |
|
339 | + * |
|
340 | + * @param string $key Name of key to attach data to. |
|
341 | + * @return mixed If there is no for the given key, then false is returned. |
|
342 | + */ |
|
343 | + public function getData(string $key) |
|
344 | + { |
|
345 | + return array_key_exists($key, $this->js_data) ? $this->js_data[ $key ] : null; |
|
346 | + } |
|
347 | + |
|
348 | + |
|
349 | + /** |
|
350 | + * Verifies whether the given data exists already on the js_data array. |
|
351 | + * Overriding data is not allowed. |
|
352 | + * |
|
353 | + * @param string $key Index for data. |
|
354 | + * @return bool If valid then return true. |
|
355 | + * @throws InvalidArgumentException if data already exists. |
|
356 | + */ |
|
357 | + protected function verifyDataNotExisting(string $key): bool |
|
358 | + { |
|
359 | + if (isset($this->js_data[ $key ])) { |
|
360 | + if (! $this->debug()) { |
|
361 | + return false; |
|
362 | + } |
|
363 | + if (is_array($this->js_data[ $key ])) { |
|
364 | + throw new InvalidArgumentException( |
|
365 | + sprintf( |
|
366 | + esc_html__( |
|
367 | + 'The value for %1$s already exists in the Registry::eejs object. |
|
368 | 368 | Overrides are not allowed. Since the value of this data is an array, you may want to use the |
369 | 369 | %2$s method to push your value to the array.', |
370 | - 'event_espresso' |
|
371 | - ), |
|
372 | - $key, |
|
373 | - 'pushData()' |
|
374 | - ) |
|
375 | - ); |
|
376 | - } |
|
377 | - throw new InvalidArgumentException( |
|
378 | - sprintf( |
|
379 | - esc_html__( |
|
380 | - 'The value for %1$s already exists in the Registry::eejs object. Overrides are not |
|
370 | + 'event_espresso' |
|
371 | + ), |
|
372 | + $key, |
|
373 | + 'pushData()' |
|
374 | + ) |
|
375 | + ); |
|
376 | + } |
|
377 | + throw new InvalidArgumentException( |
|
378 | + sprintf( |
|
379 | + esc_html__( |
|
380 | + 'The value for %1$s already exists in the Registry::eejs object. Overrides are not |
|
381 | 381 | allowed. Consider attaching your value to a different key', |
382 | - 'event_espresso' |
|
383 | - ), |
|
384 | - $key |
|
385 | - ) |
|
386 | - ); |
|
387 | - } |
|
388 | - return true; |
|
389 | - } |
|
390 | - |
|
391 | - |
|
392 | - /** |
|
393 | - * Get the actual asset path for asset manifests. |
|
394 | - * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned. |
|
395 | - * |
|
396 | - * @param string $namespace The namespace associated with the manifest file hosting the map of chunk_name to actual |
|
397 | - * asset file location. |
|
398 | - * @param string $chunk_name |
|
399 | - * @param string $asset_type |
|
400 | - * @return string |
|
401 | - * @since 4.9.59.p |
|
402 | - */ |
|
403 | - public function getAssetUrl(string $namespace, string $chunk_name, string $asset_type): string |
|
404 | - { |
|
405 | - return apply_filters( |
|
406 | - 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
|
407 | - $this->asset_manifest->getAssetUrl($chunk_name, $asset_type), |
|
408 | - $namespace, |
|
409 | - $chunk_name, |
|
410 | - $asset_type |
|
411 | - ); |
|
412 | - } |
|
413 | - |
|
414 | - |
|
415 | - /** |
|
416 | - * Return the url to a js file for the given namespace and chunk name. |
|
417 | - * |
|
418 | - * @param string $namespace |
|
419 | - * @param string $chunk_name |
|
420 | - * @return string |
|
421 | - */ |
|
422 | - public function getJsUrl(string $namespace, string $chunk_name): string |
|
423 | - { |
|
424 | - return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS); |
|
425 | - } |
|
426 | - |
|
427 | - |
|
428 | - /** |
|
429 | - * Return the url to a css file for the given namespace and chunk name. |
|
430 | - * |
|
431 | - * @param string $namespace |
|
432 | - * @param string $chunk_name |
|
433 | - * @return string |
|
434 | - */ |
|
435 | - public function getCssUrl(string $namespace, string $chunk_name): string |
|
436 | - { |
|
437 | - return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS); |
|
438 | - } |
|
439 | - |
|
440 | - |
|
441 | - /** |
|
442 | - * This is used to set registered script handles that have data. |
|
443 | - * |
|
444 | - * @param string $script_handle |
|
445 | - */ |
|
446 | - private function addRegisteredScriptHandlesWithData(string $script_handle) |
|
447 | - { |
|
448 | - $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
449 | - } |
|
450 | - |
|
451 | - |
|
452 | - /**i |
|
382 | + 'event_espresso' |
|
383 | + ), |
|
384 | + $key |
|
385 | + ) |
|
386 | + ); |
|
387 | + } |
|
388 | + return true; |
|
389 | + } |
|
390 | + |
|
391 | + |
|
392 | + /** |
|
393 | + * Get the actual asset path for asset manifests. |
|
394 | + * If there is no asset path found for the given $chunk_name, then the $chunk_name is returned. |
|
395 | + * |
|
396 | + * @param string $namespace The namespace associated with the manifest file hosting the map of chunk_name to actual |
|
397 | + * asset file location. |
|
398 | + * @param string $chunk_name |
|
399 | + * @param string $asset_type |
|
400 | + * @return string |
|
401 | + * @since 4.9.59.p |
|
402 | + */ |
|
403 | + public function getAssetUrl(string $namespace, string $chunk_name, string $asset_type): string |
|
404 | + { |
|
405 | + return apply_filters( |
|
406 | + 'FHEE__EventEspresso_core_services_assets_Registry__getAssetUrl', |
|
407 | + $this->asset_manifest->getAssetUrl($chunk_name, $asset_type), |
|
408 | + $namespace, |
|
409 | + $chunk_name, |
|
410 | + $asset_type |
|
411 | + ); |
|
412 | + } |
|
413 | + |
|
414 | + |
|
415 | + /** |
|
416 | + * Return the url to a js file for the given namespace and chunk name. |
|
417 | + * |
|
418 | + * @param string $namespace |
|
419 | + * @param string $chunk_name |
|
420 | + * @return string |
|
421 | + */ |
|
422 | + public function getJsUrl(string $namespace, string $chunk_name): string |
|
423 | + { |
|
424 | + return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_JS); |
|
425 | + } |
|
426 | + |
|
427 | + |
|
428 | + /** |
|
429 | + * Return the url to a css file for the given namespace and chunk name. |
|
430 | + * |
|
431 | + * @param string $namespace |
|
432 | + * @param string $chunk_name |
|
433 | + * @return string |
|
434 | + */ |
|
435 | + public function getCssUrl(string $namespace, string $chunk_name): string |
|
436 | + { |
|
437 | + return $this->getAssetUrl($namespace, $chunk_name, Asset::TYPE_CSS); |
|
438 | + } |
|
439 | + |
|
440 | + |
|
441 | + /** |
|
442 | + * This is used to set registered script handles that have data. |
|
443 | + * |
|
444 | + * @param string $script_handle |
|
445 | + */ |
|
446 | + private function addRegisteredScriptHandlesWithData(string $script_handle) |
|
447 | + { |
|
448 | + $this->script_handles_with_data[ $script_handle ] = $script_handle; |
|
449 | + } |
|
450 | + |
|
451 | + |
|
452 | + /**i |
|
453 | 453 | * Checks WP_Scripts for all of each script handle registered internally as having data and unsets from the |
454 | 454 | * Dependency stored in WP_Scripts if its set. |
455 | 455 | */ |
456 | - private function removeAlreadyRegisteredDataForScriptHandles() |
|
457 | - { |
|
458 | - if (empty($this->script_handles_with_data)) { |
|
459 | - return; |
|
460 | - } |
|
461 | - foreach ($this->script_handles_with_data as $script_handle) { |
|
462 | - $this->removeAlreadyRegisteredDataForScriptHandle($script_handle); |
|
463 | - } |
|
464 | - } |
|
465 | - |
|
466 | - |
|
467 | - /** |
|
468 | - * Removes any data dependency registered in WP_Scripts if its set. |
|
469 | - * |
|
470 | - * @param string $script_handle |
|
471 | - */ |
|
472 | - private function removeAlreadyRegisteredDataForScriptHandle(string $script_handle) |
|
473 | - { |
|
474 | - if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
475 | - global $wp_scripts; |
|
476 | - $unset_handle = false; |
|
477 | - if ($wp_scripts->get_data($script_handle, 'data')) { |
|
478 | - unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
479 | - $unset_handle = true; |
|
480 | - } |
|
481 | - //deal with inline_scripts |
|
482 | - if ($wp_scripts->get_data($script_handle, 'before')) { |
|
483 | - unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
484 | - $unset_handle = true; |
|
485 | - } |
|
486 | - if ($wp_scripts->get_data($script_handle, 'after')) { |
|
487 | - unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
488 | - } |
|
489 | - if ($unset_handle) { |
|
490 | - unset($this->script_handles_with_data[ $script_handle ]); |
|
491 | - } |
|
492 | - } |
|
493 | - } |
|
494 | - |
|
495 | - |
|
496 | - /** |
|
497 | - * @since 4.9.63.p |
|
498 | - * @return bool |
|
499 | - * @since 4.9.63.p |
|
500 | - */ |
|
501 | - private function debug(): bool |
|
502 | - { |
|
503 | - return apply_filters( |
|
504 | - 'FHEE__EventEspresso_core_services_assets_Registry__debug', |
|
505 | - defined('EE_DEBUG') && EE_DEBUG |
|
506 | - ); |
|
507 | - } |
|
508 | - |
|
509 | - |
|
510 | - /**************** deprecated ****************/ |
|
511 | - |
|
512 | - |
|
513 | - |
|
514 | - /** |
|
515 | - * @return null |
|
516 | - * @deprecated $VID:$ |
|
517 | - */ |
|
518 | - public function getI18nRegistry() |
|
519 | - { |
|
520 | - return null; |
|
521 | - } |
|
522 | - |
|
523 | - |
|
524 | - /** |
|
525 | - * @param string $handle |
|
526 | - * @deprecated $VID:$ |
|
527 | - */ |
|
528 | - public function registerTranslation($handle) |
|
529 | - { |
|
530 | - } |
|
531 | - |
|
532 | - |
|
533 | - /** |
|
534 | - * @param string $namespace |
|
535 | - * @param string $chunk_name |
|
536 | - * @return array |
|
537 | - * @deprecated $VID:$ |
|
538 | - */ |
|
539 | - public function getCssAssetDetails($namespace, $chunk_name) |
|
540 | - { |
|
541 | - return [ |
|
542 | - AssetManifest::KEY_DEPENDENCIES => $this->asset_manifest->getAssetDependencies($chunk_name, Asset::TYPE_CSS), |
|
543 | - AssetManifest::KEY_VERSION => $this->asset_manifest->getAssetVersion($chunk_name, Asset::TYPE_CSS), |
|
544 | - ]; |
|
545 | - } |
|
546 | - |
|
547 | - |
|
548 | - /** |
|
549 | - * @param string $namespace |
|
550 | - * @param string $chunk_name |
|
551 | - * @return array |
|
552 | - * @deprecated $VID:$ |
|
553 | - */ |
|
554 | - public function getCssDependencies($namespace, $chunk_name) |
|
555 | - { |
|
556 | - return $this->asset_manifest->getAssetDependencies($chunk_name, AssetManifest::ASSET_EXT_CSS); |
|
557 | - } |
|
558 | - |
|
559 | - |
|
560 | - /** |
|
561 | - * @param string $namespace |
|
562 | - * @param string $chunk_name |
|
563 | - * @return array |
|
564 | - * @deprecated $VID:$ |
|
565 | - */ |
|
566 | - public function getJsAssetDetails($namespace, $chunk_name) |
|
567 | - { |
|
568 | - return [ |
|
569 | - AssetManifest::KEY_DEPENDENCIES => $this->asset_manifest->getAssetDependencies($chunk_name, Asset::TYPE_JS), |
|
570 | - AssetManifest::KEY_VERSION => $this->asset_manifest->getAssetVersion($chunk_name, Asset::TYPE_JS), |
|
571 | - ]; |
|
572 | - } |
|
573 | - |
|
574 | - |
|
575 | - /** |
|
576 | - * @param string $namespace |
|
577 | - * @param string $chunk_name |
|
578 | - * @return array |
|
579 | - * @deprecated $VID:$ |
|
580 | - */ |
|
581 | - public function getJsDependencies($namespace, $chunk_name) |
|
582 | - { |
|
583 | - return $this->asset_manifest->getAssetDependencies($chunk_name); |
|
584 | - } |
|
585 | - |
|
586 | - |
|
587 | - /** |
|
588 | - * @deprecated $VID:$ |
|
589 | - */ |
|
590 | - public function registerManifestFiles() |
|
591 | - { |
|
592 | - } |
|
593 | - |
|
594 | - |
|
595 | - /** |
|
596 | - * @param string $namespace |
|
597 | - * @param string $url_base |
|
598 | - * @param string $manifest_file |
|
599 | - * @param string $manifest_file_path |
|
600 | - * @deprecated $VID:$ |
|
601 | - */ |
|
602 | - public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '') |
|
603 | - { |
|
604 | - } |
|
456 | + private function removeAlreadyRegisteredDataForScriptHandles() |
|
457 | + { |
|
458 | + if (empty($this->script_handles_with_data)) { |
|
459 | + return; |
|
460 | + } |
|
461 | + foreach ($this->script_handles_with_data as $script_handle) { |
|
462 | + $this->removeAlreadyRegisteredDataForScriptHandle($script_handle); |
|
463 | + } |
|
464 | + } |
|
465 | + |
|
466 | + |
|
467 | + /** |
|
468 | + * Removes any data dependency registered in WP_Scripts if its set. |
|
469 | + * |
|
470 | + * @param string $script_handle |
|
471 | + */ |
|
472 | + private function removeAlreadyRegisteredDataForScriptHandle(string $script_handle) |
|
473 | + { |
|
474 | + if (isset($this->script_handles_with_data[ $script_handle ])) { |
|
475 | + global $wp_scripts; |
|
476 | + $unset_handle = false; |
|
477 | + if ($wp_scripts->get_data($script_handle, 'data')) { |
|
478 | + unset($wp_scripts->registered[ $script_handle ]->extra['data']); |
|
479 | + $unset_handle = true; |
|
480 | + } |
|
481 | + //deal with inline_scripts |
|
482 | + if ($wp_scripts->get_data($script_handle, 'before')) { |
|
483 | + unset($wp_scripts->registered[ $script_handle ]->extra['before']); |
|
484 | + $unset_handle = true; |
|
485 | + } |
|
486 | + if ($wp_scripts->get_data($script_handle, 'after')) { |
|
487 | + unset($wp_scripts->registered[ $script_handle ]->extra['after']); |
|
488 | + } |
|
489 | + if ($unset_handle) { |
|
490 | + unset($this->script_handles_with_data[ $script_handle ]); |
|
491 | + } |
|
492 | + } |
|
493 | + } |
|
494 | + |
|
495 | + |
|
496 | + /** |
|
497 | + * @since 4.9.63.p |
|
498 | + * @return bool |
|
499 | + * @since 4.9.63.p |
|
500 | + */ |
|
501 | + private function debug(): bool |
|
502 | + { |
|
503 | + return apply_filters( |
|
504 | + 'FHEE__EventEspresso_core_services_assets_Registry__debug', |
|
505 | + defined('EE_DEBUG') && EE_DEBUG |
|
506 | + ); |
|
507 | + } |
|
508 | + |
|
509 | + |
|
510 | + /**************** deprecated ****************/ |
|
511 | + |
|
512 | + |
|
513 | + |
|
514 | + /** |
|
515 | + * @return null |
|
516 | + * @deprecated $VID:$ |
|
517 | + */ |
|
518 | + public function getI18nRegistry() |
|
519 | + { |
|
520 | + return null; |
|
521 | + } |
|
522 | + |
|
523 | + |
|
524 | + /** |
|
525 | + * @param string $handle |
|
526 | + * @deprecated $VID:$ |
|
527 | + */ |
|
528 | + public function registerTranslation($handle) |
|
529 | + { |
|
530 | + } |
|
531 | + |
|
532 | + |
|
533 | + /** |
|
534 | + * @param string $namespace |
|
535 | + * @param string $chunk_name |
|
536 | + * @return array |
|
537 | + * @deprecated $VID:$ |
|
538 | + */ |
|
539 | + public function getCssAssetDetails($namespace, $chunk_name) |
|
540 | + { |
|
541 | + return [ |
|
542 | + AssetManifest::KEY_DEPENDENCIES => $this->asset_manifest->getAssetDependencies($chunk_name, Asset::TYPE_CSS), |
|
543 | + AssetManifest::KEY_VERSION => $this->asset_manifest->getAssetVersion($chunk_name, Asset::TYPE_CSS), |
|
544 | + ]; |
|
545 | + } |
|
546 | + |
|
547 | + |
|
548 | + /** |
|
549 | + * @param string $namespace |
|
550 | + * @param string $chunk_name |
|
551 | + * @return array |
|
552 | + * @deprecated $VID:$ |
|
553 | + */ |
|
554 | + public function getCssDependencies($namespace, $chunk_name) |
|
555 | + { |
|
556 | + return $this->asset_manifest->getAssetDependencies($chunk_name, AssetManifest::ASSET_EXT_CSS); |
|
557 | + } |
|
558 | + |
|
559 | + |
|
560 | + /** |
|
561 | + * @param string $namespace |
|
562 | + * @param string $chunk_name |
|
563 | + * @return array |
|
564 | + * @deprecated $VID:$ |
|
565 | + */ |
|
566 | + public function getJsAssetDetails($namespace, $chunk_name) |
|
567 | + { |
|
568 | + return [ |
|
569 | + AssetManifest::KEY_DEPENDENCIES => $this->asset_manifest->getAssetDependencies($chunk_name, Asset::TYPE_JS), |
|
570 | + AssetManifest::KEY_VERSION => $this->asset_manifest->getAssetVersion($chunk_name, Asset::TYPE_JS), |
|
571 | + ]; |
|
572 | + } |
|
573 | + |
|
574 | + |
|
575 | + /** |
|
576 | + * @param string $namespace |
|
577 | + * @param string $chunk_name |
|
578 | + * @return array |
|
579 | + * @deprecated $VID:$ |
|
580 | + */ |
|
581 | + public function getJsDependencies($namespace, $chunk_name) |
|
582 | + { |
|
583 | + return $this->asset_manifest->getAssetDependencies($chunk_name); |
|
584 | + } |
|
585 | + |
|
586 | + |
|
587 | + /** |
|
588 | + * @deprecated $VID:$ |
|
589 | + */ |
|
590 | + public function registerManifestFiles() |
|
591 | + { |
|
592 | + } |
|
593 | + |
|
594 | + |
|
595 | + /** |
|
596 | + * @param string $namespace |
|
597 | + * @param string $url_base |
|
598 | + * @param string $manifest_file |
|
599 | + * @param string $manifest_file_path |
|
600 | + * @deprecated $VID:$ |
|
601 | + */ |
|
602 | + public function registerManifestFile($namespace, $url_base, $manifest_file, $manifest_file_path = '') |
|
603 | + { |
|
604 | + } |
|
605 | 605 | } |
@@ -18,497 +18,497 @@ |
||
18 | 18 | */ |
19 | 19 | abstract class EE_Admin_Page_Init extends EE_Base |
20 | 20 | { |
21 | - // identity properties (set in _set_defaults and _set_init_properties) |
|
22 | - public $label; |
|
21 | + // identity properties (set in _set_defaults and _set_init_properties) |
|
22 | + public $label; |
|
23 | 23 | |
24 | - /** |
|
25 | - * Menu map has a capability. However, this allows admin pages to have separate capability requirements for menus |
|
26 | - * and accessing pages. If capability is NOT set, then it defaults to the menu_map capability. |
|
27 | - * |
|
28 | - * @var string |
|
29 | - */ |
|
30 | - public $capability; |
|
24 | + /** |
|
25 | + * Menu map has a capability. However, this allows admin pages to have separate capability requirements for menus |
|
26 | + * and accessing pages. If capability is NOT set, then it defaults to the menu_map capability. |
|
27 | + * |
|
28 | + * @var string |
|
29 | + */ |
|
30 | + public $capability; |
|
31 | 31 | |
32 | 32 | |
33 | - /** |
|
34 | - * This holds the menu map object for this admin page. |
|
35 | - * |
|
36 | - * @var AdminMenuItem |
|
37 | - */ |
|
38 | - protected $_menu_map = null; |
|
39 | - |
|
40 | - /** |
|
41 | - * deprecated |
|
42 | - */ |
|
43 | - public $menu_label; |
|
44 | - |
|
45 | - public $menu_slug; |
|
46 | - |
|
47 | - |
|
48 | - // set in _set_defaults |
|
49 | - protected $_folder_name; |
|
50 | - |
|
51 | - protected $_folder_path; |
|
52 | - |
|
53 | - protected $_file_name; |
|
54 | - |
|
55 | - public $hook_file; |
|
56 | - |
|
57 | - protected $_wp_page_slug; |
|
58 | - |
|
59 | - protected $_routing; |
|
60 | - |
|
61 | - |
|
62 | - /** |
|
63 | - * This holds the page object. |
|
64 | - * |
|
65 | - * @var EE_Admin_Page |
|
66 | - */ |
|
67 | - protected $_loaded_page_object; |
|
68 | - |
|
69 | - |
|
70 | - // for caf |
|
71 | - protected $_files_hooked; |
|
72 | - |
|
73 | - protected $_hook_paths; |
|
74 | - |
|
75 | - // load_page? |
|
76 | - private $_load_page; |
|
77 | - |
|
78 | - /** |
|
79 | - * @var LoaderInterface |
|
80 | - */ |
|
81 | - protected $loader; |
|
82 | - |
|
83 | - /** |
|
84 | - * @var RequestInterface |
|
85 | - */ |
|
86 | - protected $request; |
|
87 | - |
|
88 | - |
|
89 | - /** |
|
90 | - * @throws InvalidArgumentException |
|
91 | - * @throws InvalidDataTypeException |
|
92 | - * @throws InvalidInterfaceException |
|
93 | - */ |
|
94 | - public function __construct(RequestInterface $request = null) |
|
95 | - { |
|
96 | - $this->loader = LoaderFactory::getLoader(); |
|
97 | - $this->request = $request instanceof RequestInterface |
|
98 | - ? $request |
|
99 | - : $this->loader->getShared(RequestInterface::class); |
|
100 | - // set global defaults |
|
101 | - $this->_set_defaults(); |
|
102 | - // set properties that are always available with objects. |
|
103 | - $this->_set_init_properties(); |
|
104 | - // global styles/scripts across all wp admin pages |
|
105 | - add_action('admin_enqueue_scripts', [$this, 'load_wp_global_scripts_styles'], 5); |
|
106 | - // load initial stuff. |
|
107 | - $this->_set_file_and_folder_name(); |
|
108 | - } |
|
109 | - |
|
110 | - |
|
111 | - /** |
|
112 | - * _set_init_properties |
|
113 | - * Child classes use to set the following properties: |
|
114 | - * $label |
|
115 | - * |
|
116 | - * @abstract |
|
117 | - * @return void |
|
118 | - */ |
|
119 | - abstract protected function _set_init_properties(); |
|
120 | - |
|
121 | - |
|
122 | - /** |
|
123 | - * @return AdminMenuItem|null |
|
124 | - * @since 4.4.0 |
|
125 | - * @deprecated $VID:$ |
|
126 | - */ |
|
127 | - public function get_menu_map() |
|
128 | - { |
|
129 | - return $this->adminMenu(); |
|
130 | - } |
|
131 | - |
|
132 | - |
|
133 | - /** |
|
134 | - * _set_menu_map is a function that child classes use to set the menu_map property (which should be an instance of |
|
135 | - * EE_Admin_Page_Menu_Map. Their menu can either be EE_Admin_Page_Main_Menu or AdminMenuSubItem. |
|
136 | - * |
|
137 | - * @since 4.4.0 |
|
138 | - * @deprecated $VID:$ |
|
139 | - */ |
|
140 | - protected function _set_menu_map() |
|
141 | - { |
|
142 | - $this->_menu_map = null; |
|
143 | - } |
|
144 | - |
|
145 | - |
|
146 | - /** |
|
147 | - * @since $VID:$ |
|
148 | - */ |
|
149 | - public function setupLegacyAdminMenuItem() |
|
150 | - { |
|
151 | - // will be overridden by child classes not using new system |
|
152 | - $this->_set_menu_map(); |
|
153 | - } |
|
154 | - |
|
155 | - |
|
156 | - /** |
|
157 | - * Child classes should return an array of properties used to construct the AdminMenuItem |
|
158 | - * |
|
159 | - * @return array |
|
160 | - * @since $VID:$ |
|
161 | - */ |
|
162 | - public function getMenuProperties(): array |
|
163 | - { |
|
164 | - return []; |
|
165 | - } |
|
166 | - |
|
167 | - |
|
168 | - /** |
|
169 | - * @param AdminMenuItem $menu |
|
170 | - * @return void |
|
171 | - * @since $VID:$ |
|
172 | - */ |
|
173 | - public function setAdminMenu(AdminMenuItem $menu): void |
|
174 | - { |
|
175 | - $this->_menu_map = $menu; |
|
176 | - } |
|
177 | - |
|
178 | - |
|
179 | - /** |
|
180 | - * returns the menu map for this admin page |
|
181 | - * |
|
182 | - * @return AdminMenuItem|null |
|
183 | - * @since $VID:$ |
|
184 | - */ |
|
185 | - public function adminMenu(): ?AdminMenuItem |
|
186 | - { |
|
187 | - return $this->_menu_map; |
|
188 | - } |
|
189 | - |
|
190 | - |
|
191 | - /** |
|
192 | - * @param string $wp_page_slug |
|
193 | - * @since $VID:$ |
|
194 | - */ |
|
195 | - public function setWpPageSlug(string $wp_page_slug): void |
|
196 | - { |
|
197 | - $this->_wp_page_slug = $wp_page_slug; |
|
198 | - } |
|
199 | - |
|
200 | - |
|
201 | - /** |
|
202 | - * This loads scripts and styles for the EE_Admin system |
|
203 | - * that must be available on ALL WP admin pages (i.e. EE_menu items) |
|
204 | - * |
|
205 | - * @return void |
|
206 | - */ |
|
207 | - public function load_wp_global_scripts_styles() |
|
208 | - { |
|
209 | - wp_register_style( |
|
210 | - 'espresso_menu', |
|
211 | - EE_ADMIN_URL . 'assets/admin-menu-styles.css', |
|
212 | - ['dashicons'], |
|
213 | - EVENT_ESPRESSO_VERSION |
|
214 | - ); |
|
215 | - wp_enqueue_style('espresso_menu'); |
|
216 | - } |
|
217 | - |
|
218 | - |
|
219 | - /** |
|
220 | - * this sets default properties (might be overridden in _set_init_properties); |
|
221 | - * |
|
222 | - * @return void |
|
223 | - */ |
|
224 | - private function _set_defaults() |
|
225 | - { |
|
226 | - $this->_file_name = $this->_folder_name = $this->_wp_page_slug = $this->capability = null; |
|
227 | - $this->_routing = true; |
|
228 | - $this->_load_page = false; |
|
229 | - $this->_files_hooked = $this->_hook_paths = []; |
|
230 | - } |
|
231 | - |
|
232 | - |
|
233 | - public function setCapability($capability, $menu_slug) |
|
234 | - { |
|
235 | - $this->capability = apply_filters('FHEE_' . $menu_slug . '_capability', $capability); |
|
236 | - } |
|
237 | - |
|
238 | - |
|
239 | - /** |
|
240 | - * @deprecated $VID:$ |
|
241 | - */ |
|
242 | - protected function _set_capability() |
|
243 | - { |
|
244 | - if ($this->_menu_map instanceof AdminMenuItem) { |
|
245 | - $this->setCapability($this->_menu_map->capability(), $this->_menu_map->menuSlug()); |
|
246 | - } |
|
247 | - } |
|
248 | - |
|
249 | - |
|
250 | - /** |
|
251 | - * initialize_admin_page |
|
252 | - * This method is what executes the loading of the specific page class for the given dir_name as called by the |
|
253 | - * EE_Admin_Init class. |
|
254 | - * |
|
255 | - * @return void |
|
256 | - * @throws EE_Error |
|
257 | - * @throws ReflectionException |
|
258 | - */ |
|
259 | - public function initialize_admin_page() |
|
260 | - { |
|
261 | - // let's check user access first |
|
262 | - $this->_check_user_access(); |
|
263 | - if (! $this->_loaded_page_object instanceof EE_Admin_Page) { |
|
264 | - return; |
|
265 | - } |
|
266 | - $this->_loaded_page_object->route_admin_request(); |
|
267 | - } |
|
268 | - |
|
269 | - |
|
270 | - /** |
|
271 | - * @param string $wp_page_slug |
|
272 | - * @throws EE_Error |
|
273 | - */ |
|
274 | - public function set_page_dependencies(string $wp_page_slug) |
|
275 | - { |
|
276 | - if (! $this->_load_page) { |
|
277 | - return; |
|
278 | - } |
|
279 | - if (! $this->_loaded_page_object instanceof EE_Admin_Page) { |
|
280 | - $msg[] = esc_html__( |
|
281 | - 'We can\'t load the page because we\'re missing a valid page object that tells us what to load', |
|
282 | - 'event_espresso' |
|
283 | - ); |
|
284 | - $msg[] = $msg[0] . "\r\n" |
|
285 | - . sprintf( |
|
286 | - esc_html__( |
|
287 | - 'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory', |
|
288 | - 'event_espresso' |
|
289 | - ), |
|
290 | - $this->_file_name, |
|
291 | - $this->_file_name, |
|
292 | - $this->_folder_path . $this->_file_name, |
|
293 | - $this->_menu_map->menuSlug() |
|
294 | - ); |
|
295 | - throw new EE_Error(implode('||', $msg)); |
|
296 | - } |
|
297 | - $this->_loaded_page_object->set_wp_page_slug($wp_page_slug); |
|
298 | - $page_hook = "load-$wp_page_slug"; |
|
299 | - // hook into page load hook so all page specific stuff gets loaded. |
|
300 | - if (! empty($wp_page_slug)) { |
|
301 | - add_action($page_hook, [$this->_loaded_page_object, 'load_page_dependencies']); |
|
302 | - } |
|
303 | - } |
|
304 | - |
|
305 | - |
|
306 | - /** |
|
307 | - * This executes the initial page loads for EE_Admin pages to take care of any ajax or other code needing to run |
|
308 | - * before the load-page... hook. Note, the page loads are happening around the wp_init hook. |
|
309 | - * |
|
310 | - * @return void |
|
311 | - * @throws InvalidArgumentException |
|
312 | - * @throws InvalidDataTypeException |
|
313 | - * @throws InvalidInterfaceException |
|
314 | - * @throws EE_Error |
|
315 | - * @throws ReflectionException |
|
316 | - */ |
|
317 | - public function do_initial_loads() |
|
318 | - { |
|
319 | - // no loading or initializing if menu map is setup incorrectly. |
|
320 | - if (! $this->_menu_map instanceof AdminMenuItem) { |
|
321 | - return; |
|
322 | - } |
|
323 | - $this->_initialize_admin_page(); |
|
324 | - } |
|
325 | - |
|
326 | - |
|
327 | - /** |
|
328 | - * all we're doing here is setting the $_file_name property for later use. |
|
329 | - * |
|
330 | - * @return void |
|
331 | - */ |
|
332 | - private function _set_file_and_folder_name() |
|
333 | - { |
|
334 | - $bt = debug_backtrace(); |
|
335 | - // for more reliable determination of folder name |
|
336 | - // we're using this to get the actual folder name of the CALLING class (i.e. the child class that extends this). Why? Because $this->menu_slug may be different than the folder name (to avoid conflicts with other plugins) |
|
337 | - $class = get_class($this); |
|
338 | - foreach ($bt as $index => $values) { |
|
339 | - if (isset($values['class']) && $values['class'] == $class) { |
|
340 | - $file_index = $index - 1; |
|
341 | - $this->_folder_name = basename(dirname($bt[ $file_index ]['file'])); |
|
342 | - if (! empty($this->_folder_name)) { |
|
343 | - break; |
|
344 | - } |
|
345 | - } |
|
346 | - } |
|
347 | - $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/'; |
|
348 | - $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name); |
|
349 | - $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name)); |
|
350 | - $this->_file_name = str_replace(' ', '_', $this->_file_name); |
|
351 | - } |
|
352 | - |
|
353 | - |
|
354 | - /** |
|
355 | - * This automatically checks if we have a hook class in the loaded child directory. If we DO then we will register |
|
356 | - * it with the appropriate pages. That way all we have to do is make sure the file is named correctly and |
|
357 | - * "dropped" in. Example: if we wanted to set this up for Messages hooking into Events then we would do: |
|
358 | - * events_Messages_Hooks.class.php |
|
359 | - * |
|
360 | - * @param bool $extend This indicates whether we're checking the extend directory for any register_hooks |
|
361 | - * files/classes |
|
362 | - * @return array |
|
363 | - */ |
|
364 | - public function register_hooks(bool $extend = false): array |
|
365 | - { |
|
366 | - // get a list of files in the directory that have the "Hook" in their name an |
|
367 | - // if this is an extended check (i.e. caf is active) then we will scan the caffeinated/extend directory first and any hook files that are found will be have their reference added to the $_files_hook array property. Then, we make sure that when we loop through the core decaf directories to find hook files that we skip over any hooks files that have already been set by caf. |
|
368 | - if ($extend) { |
|
369 | - $hook_files_glob_path = apply_filters( |
|
370 | - 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path__extend', |
|
371 | - EE_CORE_CAF_ADMIN_EXTEND |
|
372 | - . $this->_folder_name |
|
373 | - . '/*' |
|
374 | - . $this->_file_name |
|
375 | - . '_Hooks_Extend.class.php' |
|
376 | - ); |
|
377 | - $this->_hook_paths = $this->_register_hook_files($hook_files_glob_path, $extend); |
|
378 | - } |
|
379 | - // loop through decaf folders |
|
380 | - $hook_files_glob_path = apply_filters( |
|
381 | - 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path', |
|
382 | - $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php' |
|
383 | - ); |
|
384 | - $this->_hook_paths = array_merge( |
|
385 | - $this->_register_hook_files($hook_files_glob_path), |
|
386 | - $this->_hook_paths |
|
387 | - ); // making sure any extended hook paths are later in the array than the core hook paths! |
|
388 | - return $this->_hook_paths; |
|
389 | - } |
|
390 | - |
|
391 | - |
|
392 | - protected function _register_hook_files($hook_files_glob_path, $extend = false): array |
|
393 | - { |
|
394 | - $hook_paths = glob($hook_files_glob_path); |
|
395 | - if (empty($hook_paths)) { |
|
396 | - return []; |
|
397 | - } |
|
398 | - foreach ($hook_paths as $file) { |
|
399 | - // lets get the linked admin. |
|
400 | - $hook_file = $extend |
|
401 | - ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file) |
|
402 | - : str_replace($this->_folder_path, '', $file); |
|
403 | - $replace = $extend |
|
404 | - ? '_' . $this->_file_name . '_Hooks_Extend.class.php' |
|
405 | - : '_' . $this->_file_name . '_Hooks.class.php'; |
|
406 | - $rel_admin = str_replace($replace, '', $hook_file); |
|
407 | - $rel_admin = strtolower($rel_admin); |
|
408 | - // make sure we haven't already got a hook setup for this page path |
|
409 | - if (in_array($rel_admin, $this->_files_hooked)) { |
|
410 | - continue; |
|
411 | - } |
|
412 | - require_once $file; |
|
413 | - $this->hook_file = $hook_file; |
|
414 | - $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin; |
|
415 | - add_filter($rel_admin_hook, [$this, 'load_admin_hook']); |
|
416 | - $this->_files_hooked[] = $rel_admin; |
|
417 | - } |
|
418 | - return $hook_paths; |
|
419 | - } |
|
420 | - |
|
421 | - |
|
422 | - public function load_admin_hook($registered_pages) |
|
423 | - { |
|
424 | - return array_merge((array) $this->hook_file, $registered_pages); |
|
425 | - } |
|
426 | - |
|
427 | - |
|
428 | - /** |
|
429 | - * _initialize_admin_page |
|
430 | - * |
|
431 | - * @throws EE_Error |
|
432 | - * @throws ReflectionException |
|
433 | - * @see initialize_admin_page() for info |
|
434 | - */ |
|
435 | - protected function _initialize_admin_page() |
|
436 | - { |
|
437 | - // JUST CHECK WE'RE ON RIGHT PAGE. |
|
438 | - $page = $this->request->getRequestParam('page'); |
|
439 | - $page = $this->request->getRequestParam('current_page', $page); |
|
440 | - $menu_slug = $this->_menu_map->menuSlug(); |
|
441 | - |
|
442 | - |
|
443 | - if ($this->_routing && ($page === '' || $page !== $menu_slug)) { |
|
444 | - // not on the right page so let's get out. |
|
445 | - return; |
|
446 | - } |
|
447 | - $this->_load_page = true; |
|
448 | - |
|
449 | - // we don't need to do a page_request check here because it's only called via WP menu system. |
|
450 | - $admin_page = $this->_file_name . '_Admin_Page'; |
|
451 | - $hook_suffix = "{$menu_slug}_$admin_page"; |
|
452 | - $admin_page = apply_filters( |
|
453 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__$hook_suffix", |
|
454 | - $admin_page |
|
455 | - ); |
|
456 | - if (empty($admin_page)) { |
|
457 | - return; |
|
458 | - } |
|
459 | - // define requested admin page class name then load the file and instantiate |
|
460 | - $path_to_file = str_replace(['\\', '/'], '/', $this->_folder_path . $admin_page . '.core.php'); |
|
461 | - // so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be: |
|
462 | - // FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page |
|
463 | - $path_to_file = apply_filters( |
|
464 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__$hook_suffix", |
|
465 | - $path_to_file |
|
466 | - ); |
|
467 | - if (! is_readable($path_to_file)) { |
|
468 | - return; |
|
469 | - } |
|
470 | - // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place |
|
471 | - do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization'); |
|
472 | - do_action("AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_$menu_slug"); |
|
473 | - require_once($path_to_file); |
|
474 | - $this->_loaded_page_object = $this->loader->getShared($admin_page, [$this->_routing]); |
|
475 | - $this->_loaded_page_object->initializePage(); |
|
476 | - |
|
477 | - do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization'); |
|
478 | - do_action("AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_$menu_slug"); |
|
479 | - } |
|
480 | - |
|
481 | - |
|
482 | - public function get_admin_page_name(): string |
|
483 | - { |
|
484 | - return $this->_file_name . '_Admin_Page'; |
|
485 | - } |
|
486 | - |
|
487 | - |
|
488 | - /** |
|
489 | - * @return EE_Admin_Page|null |
|
490 | - */ |
|
491 | - public function loaded_page_object(): ?EE_Admin_Page |
|
492 | - { |
|
493 | - return $this->_loaded_page_object; |
|
494 | - } |
|
495 | - |
|
496 | - |
|
497 | - /** |
|
498 | - * _check_user_access |
|
499 | - * verifies user access for this admin page. If no user access is available then let's gracefully exit with a |
|
500 | - * WordPress die message. |
|
501 | - * |
|
502 | - * @return void wp_die if fail |
|
503 | - */ |
|
504 | - private function _check_user_access() |
|
505 | - { |
|
506 | - if (! $this->_menu_map->currentUserHasAccess()) { |
|
507 | - wp_die( |
|
508 | - esc_html__('You don\'t have access to this page.', 'event_espresso'), |
|
509 | - '', |
|
510 | - ['back_link' => true] |
|
511 | - ); |
|
512 | - } |
|
513 | - } |
|
33 | + /** |
|
34 | + * This holds the menu map object for this admin page. |
|
35 | + * |
|
36 | + * @var AdminMenuItem |
|
37 | + */ |
|
38 | + protected $_menu_map = null; |
|
39 | + |
|
40 | + /** |
|
41 | + * deprecated |
|
42 | + */ |
|
43 | + public $menu_label; |
|
44 | + |
|
45 | + public $menu_slug; |
|
46 | + |
|
47 | + |
|
48 | + // set in _set_defaults |
|
49 | + protected $_folder_name; |
|
50 | + |
|
51 | + protected $_folder_path; |
|
52 | + |
|
53 | + protected $_file_name; |
|
54 | + |
|
55 | + public $hook_file; |
|
56 | + |
|
57 | + protected $_wp_page_slug; |
|
58 | + |
|
59 | + protected $_routing; |
|
60 | + |
|
61 | + |
|
62 | + /** |
|
63 | + * This holds the page object. |
|
64 | + * |
|
65 | + * @var EE_Admin_Page |
|
66 | + */ |
|
67 | + protected $_loaded_page_object; |
|
68 | + |
|
69 | + |
|
70 | + // for caf |
|
71 | + protected $_files_hooked; |
|
72 | + |
|
73 | + protected $_hook_paths; |
|
74 | + |
|
75 | + // load_page? |
|
76 | + private $_load_page; |
|
77 | + |
|
78 | + /** |
|
79 | + * @var LoaderInterface |
|
80 | + */ |
|
81 | + protected $loader; |
|
82 | + |
|
83 | + /** |
|
84 | + * @var RequestInterface |
|
85 | + */ |
|
86 | + protected $request; |
|
87 | + |
|
88 | + |
|
89 | + /** |
|
90 | + * @throws InvalidArgumentException |
|
91 | + * @throws InvalidDataTypeException |
|
92 | + * @throws InvalidInterfaceException |
|
93 | + */ |
|
94 | + public function __construct(RequestInterface $request = null) |
|
95 | + { |
|
96 | + $this->loader = LoaderFactory::getLoader(); |
|
97 | + $this->request = $request instanceof RequestInterface |
|
98 | + ? $request |
|
99 | + : $this->loader->getShared(RequestInterface::class); |
|
100 | + // set global defaults |
|
101 | + $this->_set_defaults(); |
|
102 | + // set properties that are always available with objects. |
|
103 | + $this->_set_init_properties(); |
|
104 | + // global styles/scripts across all wp admin pages |
|
105 | + add_action('admin_enqueue_scripts', [$this, 'load_wp_global_scripts_styles'], 5); |
|
106 | + // load initial stuff. |
|
107 | + $this->_set_file_and_folder_name(); |
|
108 | + } |
|
109 | + |
|
110 | + |
|
111 | + /** |
|
112 | + * _set_init_properties |
|
113 | + * Child classes use to set the following properties: |
|
114 | + * $label |
|
115 | + * |
|
116 | + * @abstract |
|
117 | + * @return void |
|
118 | + */ |
|
119 | + abstract protected function _set_init_properties(); |
|
120 | + |
|
121 | + |
|
122 | + /** |
|
123 | + * @return AdminMenuItem|null |
|
124 | + * @since 4.4.0 |
|
125 | + * @deprecated $VID:$ |
|
126 | + */ |
|
127 | + public function get_menu_map() |
|
128 | + { |
|
129 | + return $this->adminMenu(); |
|
130 | + } |
|
131 | + |
|
132 | + |
|
133 | + /** |
|
134 | + * _set_menu_map is a function that child classes use to set the menu_map property (which should be an instance of |
|
135 | + * EE_Admin_Page_Menu_Map. Their menu can either be EE_Admin_Page_Main_Menu or AdminMenuSubItem. |
|
136 | + * |
|
137 | + * @since 4.4.0 |
|
138 | + * @deprecated $VID:$ |
|
139 | + */ |
|
140 | + protected function _set_menu_map() |
|
141 | + { |
|
142 | + $this->_menu_map = null; |
|
143 | + } |
|
144 | + |
|
145 | + |
|
146 | + /** |
|
147 | + * @since $VID:$ |
|
148 | + */ |
|
149 | + public function setupLegacyAdminMenuItem() |
|
150 | + { |
|
151 | + // will be overridden by child classes not using new system |
|
152 | + $this->_set_menu_map(); |
|
153 | + } |
|
154 | + |
|
155 | + |
|
156 | + /** |
|
157 | + * Child classes should return an array of properties used to construct the AdminMenuItem |
|
158 | + * |
|
159 | + * @return array |
|
160 | + * @since $VID:$ |
|
161 | + */ |
|
162 | + public function getMenuProperties(): array |
|
163 | + { |
|
164 | + return []; |
|
165 | + } |
|
166 | + |
|
167 | + |
|
168 | + /** |
|
169 | + * @param AdminMenuItem $menu |
|
170 | + * @return void |
|
171 | + * @since $VID:$ |
|
172 | + */ |
|
173 | + public function setAdminMenu(AdminMenuItem $menu): void |
|
174 | + { |
|
175 | + $this->_menu_map = $menu; |
|
176 | + } |
|
177 | + |
|
178 | + |
|
179 | + /** |
|
180 | + * returns the menu map for this admin page |
|
181 | + * |
|
182 | + * @return AdminMenuItem|null |
|
183 | + * @since $VID:$ |
|
184 | + */ |
|
185 | + public function adminMenu(): ?AdminMenuItem |
|
186 | + { |
|
187 | + return $this->_menu_map; |
|
188 | + } |
|
189 | + |
|
190 | + |
|
191 | + /** |
|
192 | + * @param string $wp_page_slug |
|
193 | + * @since $VID:$ |
|
194 | + */ |
|
195 | + public function setWpPageSlug(string $wp_page_slug): void |
|
196 | + { |
|
197 | + $this->_wp_page_slug = $wp_page_slug; |
|
198 | + } |
|
199 | + |
|
200 | + |
|
201 | + /** |
|
202 | + * This loads scripts and styles for the EE_Admin system |
|
203 | + * that must be available on ALL WP admin pages (i.e. EE_menu items) |
|
204 | + * |
|
205 | + * @return void |
|
206 | + */ |
|
207 | + public function load_wp_global_scripts_styles() |
|
208 | + { |
|
209 | + wp_register_style( |
|
210 | + 'espresso_menu', |
|
211 | + EE_ADMIN_URL . 'assets/admin-menu-styles.css', |
|
212 | + ['dashicons'], |
|
213 | + EVENT_ESPRESSO_VERSION |
|
214 | + ); |
|
215 | + wp_enqueue_style('espresso_menu'); |
|
216 | + } |
|
217 | + |
|
218 | + |
|
219 | + /** |
|
220 | + * this sets default properties (might be overridden in _set_init_properties); |
|
221 | + * |
|
222 | + * @return void |
|
223 | + */ |
|
224 | + private function _set_defaults() |
|
225 | + { |
|
226 | + $this->_file_name = $this->_folder_name = $this->_wp_page_slug = $this->capability = null; |
|
227 | + $this->_routing = true; |
|
228 | + $this->_load_page = false; |
|
229 | + $this->_files_hooked = $this->_hook_paths = []; |
|
230 | + } |
|
231 | + |
|
232 | + |
|
233 | + public function setCapability($capability, $menu_slug) |
|
234 | + { |
|
235 | + $this->capability = apply_filters('FHEE_' . $menu_slug . '_capability', $capability); |
|
236 | + } |
|
237 | + |
|
238 | + |
|
239 | + /** |
|
240 | + * @deprecated $VID:$ |
|
241 | + */ |
|
242 | + protected function _set_capability() |
|
243 | + { |
|
244 | + if ($this->_menu_map instanceof AdminMenuItem) { |
|
245 | + $this->setCapability($this->_menu_map->capability(), $this->_menu_map->menuSlug()); |
|
246 | + } |
|
247 | + } |
|
248 | + |
|
249 | + |
|
250 | + /** |
|
251 | + * initialize_admin_page |
|
252 | + * This method is what executes the loading of the specific page class for the given dir_name as called by the |
|
253 | + * EE_Admin_Init class. |
|
254 | + * |
|
255 | + * @return void |
|
256 | + * @throws EE_Error |
|
257 | + * @throws ReflectionException |
|
258 | + */ |
|
259 | + public function initialize_admin_page() |
|
260 | + { |
|
261 | + // let's check user access first |
|
262 | + $this->_check_user_access(); |
|
263 | + if (! $this->_loaded_page_object instanceof EE_Admin_Page) { |
|
264 | + return; |
|
265 | + } |
|
266 | + $this->_loaded_page_object->route_admin_request(); |
|
267 | + } |
|
268 | + |
|
269 | + |
|
270 | + /** |
|
271 | + * @param string $wp_page_slug |
|
272 | + * @throws EE_Error |
|
273 | + */ |
|
274 | + public function set_page_dependencies(string $wp_page_slug) |
|
275 | + { |
|
276 | + if (! $this->_load_page) { |
|
277 | + return; |
|
278 | + } |
|
279 | + if (! $this->_loaded_page_object instanceof EE_Admin_Page) { |
|
280 | + $msg[] = esc_html__( |
|
281 | + 'We can\'t load the page because we\'re missing a valid page object that tells us what to load', |
|
282 | + 'event_espresso' |
|
283 | + ); |
|
284 | + $msg[] = $msg[0] . "\r\n" |
|
285 | + . sprintf( |
|
286 | + esc_html__( |
|
287 | + 'The custom slug you have set for this page is %s. This means we\'re looking for the class %s_Admin_Page (found in %s_Admin_Page.core.php) within your %s directory', |
|
288 | + 'event_espresso' |
|
289 | + ), |
|
290 | + $this->_file_name, |
|
291 | + $this->_file_name, |
|
292 | + $this->_folder_path . $this->_file_name, |
|
293 | + $this->_menu_map->menuSlug() |
|
294 | + ); |
|
295 | + throw new EE_Error(implode('||', $msg)); |
|
296 | + } |
|
297 | + $this->_loaded_page_object->set_wp_page_slug($wp_page_slug); |
|
298 | + $page_hook = "load-$wp_page_slug"; |
|
299 | + // hook into page load hook so all page specific stuff gets loaded. |
|
300 | + if (! empty($wp_page_slug)) { |
|
301 | + add_action($page_hook, [$this->_loaded_page_object, 'load_page_dependencies']); |
|
302 | + } |
|
303 | + } |
|
304 | + |
|
305 | + |
|
306 | + /** |
|
307 | + * This executes the initial page loads for EE_Admin pages to take care of any ajax or other code needing to run |
|
308 | + * before the load-page... hook. Note, the page loads are happening around the wp_init hook. |
|
309 | + * |
|
310 | + * @return void |
|
311 | + * @throws InvalidArgumentException |
|
312 | + * @throws InvalidDataTypeException |
|
313 | + * @throws InvalidInterfaceException |
|
314 | + * @throws EE_Error |
|
315 | + * @throws ReflectionException |
|
316 | + */ |
|
317 | + public function do_initial_loads() |
|
318 | + { |
|
319 | + // no loading or initializing if menu map is setup incorrectly. |
|
320 | + if (! $this->_menu_map instanceof AdminMenuItem) { |
|
321 | + return; |
|
322 | + } |
|
323 | + $this->_initialize_admin_page(); |
|
324 | + } |
|
325 | + |
|
326 | + |
|
327 | + /** |
|
328 | + * all we're doing here is setting the $_file_name property for later use. |
|
329 | + * |
|
330 | + * @return void |
|
331 | + */ |
|
332 | + private function _set_file_and_folder_name() |
|
333 | + { |
|
334 | + $bt = debug_backtrace(); |
|
335 | + // for more reliable determination of folder name |
|
336 | + // we're using this to get the actual folder name of the CALLING class (i.e. the child class that extends this). Why? Because $this->menu_slug may be different than the folder name (to avoid conflicts with other plugins) |
|
337 | + $class = get_class($this); |
|
338 | + foreach ($bt as $index => $values) { |
|
339 | + if (isset($values['class']) && $values['class'] == $class) { |
|
340 | + $file_index = $index - 1; |
|
341 | + $this->_folder_name = basename(dirname($bt[ $file_index ]['file'])); |
|
342 | + if (! empty($this->_folder_name)) { |
|
343 | + break; |
|
344 | + } |
|
345 | + } |
|
346 | + } |
|
347 | + $this->_folder_path = EE_ADMIN_PAGES . $this->_folder_name . '/'; |
|
348 | + $this->_file_name = preg_replace('/^ee/', 'EE', $this->_folder_name); |
|
349 | + $this->_file_name = ucwords(str_replace('_', ' ', $this->_file_name)); |
|
350 | + $this->_file_name = str_replace(' ', '_', $this->_file_name); |
|
351 | + } |
|
352 | + |
|
353 | + |
|
354 | + /** |
|
355 | + * This automatically checks if we have a hook class in the loaded child directory. If we DO then we will register |
|
356 | + * it with the appropriate pages. That way all we have to do is make sure the file is named correctly and |
|
357 | + * "dropped" in. Example: if we wanted to set this up for Messages hooking into Events then we would do: |
|
358 | + * events_Messages_Hooks.class.php |
|
359 | + * |
|
360 | + * @param bool $extend This indicates whether we're checking the extend directory for any register_hooks |
|
361 | + * files/classes |
|
362 | + * @return array |
|
363 | + */ |
|
364 | + public function register_hooks(bool $extend = false): array |
|
365 | + { |
|
366 | + // get a list of files in the directory that have the "Hook" in their name an |
|
367 | + // if this is an extended check (i.e. caf is active) then we will scan the caffeinated/extend directory first and any hook files that are found will be have their reference added to the $_files_hook array property. Then, we make sure that when we loop through the core decaf directories to find hook files that we skip over any hooks files that have already been set by caf. |
|
368 | + if ($extend) { |
|
369 | + $hook_files_glob_path = apply_filters( |
|
370 | + 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path__extend', |
|
371 | + EE_CORE_CAF_ADMIN_EXTEND |
|
372 | + . $this->_folder_name |
|
373 | + . '/*' |
|
374 | + . $this->_file_name |
|
375 | + . '_Hooks_Extend.class.php' |
|
376 | + ); |
|
377 | + $this->_hook_paths = $this->_register_hook_files($hook_files_glob_path, $extend); |
|
378 | + } |
|
379 | + // loop through decaf folders |
|
380 | + $hook_files_glob_path = apply_filters( |
|
381 | + 'FHEE__EE_Admin_Page_Init__register_hooks__hook_files_glob_path', |
|
382 | + $this->_folder_path . '*' . $this->_file_name . '_Hooks.class.php' |
|
383 | + ); |
|
384 | + $this->_hook_paths = array_merge( |
|
385 | + $this->_register_hook_files($hook_files_glob_path), |
|
386 | + $this->_hook_paths |
|
387 | + ); // making sure any extended hook paths are later in the array than the core hook paths! |
|
388 | + return $this->_hook_paths; |
|
389 | + } |
|
390 | + |
|
391 | + |
|
392 | + protected function _register_hook_files($hook_files_glob_path, $extend = false): array |
|
393 | + { |
|
394 | + $hook_paths = glob($hook_files_glob_path); |
|
395 | + if (empty($hook_paths)) { |
|
396 | + return []; |
|
397 | + } |
|
398 | + foreach ($hook_paths as $file) { |
|
399 | + // lets get the linked admin. |
|
400 | + $hook_file = $extend |
|
401 | + ? str_replace(EE_CORE_CAF_ADMIN_EXTEND . $this->_folder_name . '/', '', $file) |
|
402 | + : str_replace($this->_folder_path, '', $file); |
|
403 | + $replace = $extend |
|
404 | + ? '_' . $this->_file_name . '_Hooks_Extend.class.php' |
|
405 | + : '_' . $this->_file_name . '_Hooks.class.php'; |
|
406 | + $rel_admin = str_replace($replace, '', $hook_file); |
|
407 | + $rel_admin = strtolower($rel_admin); |
|
408 | + // make sure we haven't already got a hook setup for this page path |
|
409 | + if (in_array($rel_admin, $this->_files_hooked)) { |
|
410 | + continue; |
|
411 | + } |
|
412 | + require_once $file; |
|
413 | + $this->hook_file = $hook_file; |
|
414 | + $rel_admin_hook = 'FHEE_do_other_page_hooks_' . $rel_admin; |
|
415 | + add_filter($rel_admin_hook, [$this, 'load_admin_hook']); |
|
416 | + $this->_files_hooked[] = $rel_admin; |
|
417 | + } |
|
418 | + return $hook_paths; |
|
419 | + } |
|
420 | + |
|
421 | + |
|
422 | + public function load_admin_hook($registered_pages) |
|
423 | + { |
|
424 | + return array_merge((array) $this->hook_file, $registered_pages); |
|
425 | + } |
|
426 | + |
|
427 | + |
|
428 | + /** |
|
429 | + * _initialize_admin_page |
|
430 | + * |
|
431 | + * @throws EE_Error |
|
432 | + * @throws ReflectionException |
|
433 | + * @see initialize_admin_page() for info |
|
434 | + */ |
|
435 | + protected function _initialize_admin_page() |
|
436 | + { |
|
437 | + // JUST CHECK WE'RE ON RIGHT PAGE. |
|
438 | + $page = $this->request->getRequestParam('page'); |
|
439 | + $page = $this->request->getRequestParam('current_page', $page); |
|
440 | + $menu_slug = $this->_menu_map->menuSlug(); |
|
441 | + |
|
442 | + |
|
443 | + if ($this->_routing && ($page === '' || $page !== $menu_slug)) { |
|
444 | + // not on the right page so let's get out. |
|
445 | + return; |
|
446 | + } |
|
447 | + $this->_load_page = true; |
|
448 | + |
|
449 | + // we don't need to do a page_request check here because it's only called via WP menu system. |
|
450 | + $admin_page = $this->_file_name . '_Admin_Page'; |
|
451 | + $hook_suffix = "{$menu_slug}_$admin_page"; |
|
452 | + $admin_page = apply_filters( |
|
453 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__$hook_suffix", |
|
454 | + $admin_page |
|
455 | + ); |
|
456 | + if (empty($admin_page)) { |
|
457 | + return; |
|
458 | + } |
|
459 | + // define requested admin page class name then load the file and instantiate |
|
460 | + $path_to_file = str_replace(['\\', '/'], '/', $this->_folder_path . $admin_page . '.core.php'); |
|
461 | + // so if the file would be in EE_ADMIN/attendees/Attendee_Admin_Page.core.php, the filter would be: |
|
462 | + // FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__attendees_Attendee_Admin_Page |
|
463 | + $path_to_file = apply_filters( |
|
464 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__$hook_suffix", |
|
465 | + $path_to_file |
|
466 | + ); |
|
467 | + if (! is_readable($path_to_file)) { |
|
468 | + return; |
|
469 | + } |
|
470 | + // This is a place where EE plugins can hook in to make sure their own files are required in the appropriate place |
|
471 | + do_action('AHEE__EE_Admin_Page___initialize_admin_page__before_initialization'); |
|
472 | + do_action("AHEE__EE_Admin_Page___initialize_admin_page__before_initialization_$menu_slug"); |
|
473 | + require_once($path_to_file); |
|
474 | + $this->_loaded_page_object = $this->loader->getShared($admin_page, [$this->_routing]); |
|
475 | + $this->_loaded_page_object->initializePage(); |
|
476 | + |
|
477 | + do_action('AHEE__EE_Admin_Page___initialize_admin_page__after_initialization'); |
|
478 | + do_action("AHEE__EE_Admin_Page___initialize_admin_page__after_initialization_$menu_slug"); |
|
479 | + } |
|
480 | + |
|
481 | + |
|
482 | + public function get_admin_page_name(): string |
|
483 | + { |
|
484 | + return $this->_file_name . '_Admin_Page'; |
|
485 | + } |
|
486 | + |
|
487 | + |
|
488 | + /** |
|
489 | + * @return EE_Admin_Page|null |
|
490 | + */ |
|
491 | + public function loaded_page_object(): ?EE_Admin_Page |
|
492 | + { |
|
493 | + return $this->_loaded_page_object; |
|
494 | + } |
|
495 | + |
|
496 | + |
|
497 | + /** |
|
498 | + * _check_user_access |
|
499 | + * verifies user access for this admin page. If no user access is available then let's gracefully exit with a |
|
500 | + * WordPress die message. |
|
501 | + * |
|
502 | + * @return void wp_die if fail |
|
503 | + */ |
|
504 | + private function _check_user_access() |
|
505 | + { |
|
506 | + if (! $this->_menu_map->currentUserHasAccess()) { |
|
507 | + wp_die( |
|
508 | + esc_html__('You don\'t have access to this page.', 'event_espresso'), |
|
509 | + '', |
|
510 | + ['back_link' => true] |
|
511 | + ); |
|
512 | + } |
|
513 | + } |
|
514 | 514 | } |
@@ -16,437 +16,437 @@ |
||
16 | 16 | */ |
17 | 17 | class EE_Admin_Page_Loader |
18 | 18 | { |
19 | - /** |
|
20 | - * @var AdminMenuManager $menu_manager |
|
21 | - */ |
|
22 | - protected $menu_manager; |
|
23 | - |
|
24 | - /** |
|
25 | - * @var LoaderInterface $loader |
|
26 | - */ |
|
27 | - protected $loader; |
|
28 | - |
|
29 | - /** |
|
30 | - * _installed_pages |
|
31 | - * objects for page_init objects detected and loaded |
|
32 | - * |
|
33 | - * @access private |
|
34 | - * @var EE_Admin_Page_Init[] |
|
35 | - */ |
|
36 | - private $_installed_pages = []; |
|
37 | - |
|
38 | - |
|
39 | - /** |
|
40 | - * this is used to hold the registry of menu slugs for all the installed admin pages |
|
41 | - * |
|
42 | - * @var array |
|
43 | - */ |
|
44 | - private $_menu_slugs = []; |
|
45 | - |
|
46 | - |
|
47 | - /** |
|
48 | - * _caffeinated_extends |
|
49 | - * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and |
|
50 | - * pieces needed to do so). This property is defined in the _set_caffeinated method. |
|
51 | - * |
|
52 | - * @var array |
|
53 | - */ |
|
54 | - private $_caffeinated_extends = []; |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * This property will hold the hook file for setting up the filter that does all the connections between admin |
|
59 | - * pages. |
|
60 | - * |
|
61 | - * @var string |
|
62 | - */ |
|
63 | - public $hook_file; |
|
64 | - |
|
65 | - /** |
|
66 | - * @var int |
|
67 | - * @since $VID:$ |
|
68 | - */ |
|
69 | - private $maintenance_mode = 0; |
|
70 | - |
|
71 | - |
|
72 | - /** |
|
73 | - * @throws InvalidArgumentException |
|
74 | - * @throws InvalidDataTypeException |
|
75 | - * @throws InvalidInterfaceException |
|
76 | - */ |
|
77 | - public function __construct(?LoaderInterface $loader) |
|
78 | - { |
|
79 | - $this->loader = $loader instanceof LoaderInterface ? $loader : LoaderFactory::getLoader(); |
|
80 | - $this->menu_manager = $this->loader->getShared(AdminMenuManager::class, [$this->loader]); |
|
81 | - } |
|
82 | - |
|
83 | - |
|
84 | - /** |
|
85 | - * @throws EE_Error |
|
86 | - * @throws ReflectionException |
|
87 | - * @since $VID:$ |
|
88 | - */ |
|
89 | - public function init() |
|
90 | - { |
|
91 | - $this->menu_manager->initialize(); |
|
92 | - $this->maintenance_mode = EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance; |
|
93 | - // let's do a scan and see what installed pages we have |
|
94 | - $this->findAndLoadAdminPages(); |
|
95 | - } |
|
96 | - |
|
97 | - |
|
98 | - /** |
|
99 | - * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by |
|
100 | - * files in the caffeinated folder. |
|
101 | - * |
|
102 | - * @access private |
|
103 | - * @return void |
|
104 | - */ |
|
105 | - private function defineCaffeinatedConstants() |
|
106 | - { |
|
107 | - if (! defined('EE_CORE_CAF_ADMIN')) { |
|
108 | - define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/'); |
|
109 | - define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/'); |
|
110 | - define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/'); |
|
111 | - define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/'); |
|
112 | - define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/'); |
|
113 | - define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/'); |
|
114 | - } |
|
115 | - } |
|
116 | - |
|
117 | - |
|
118 | - /** |
|
119 | - * This just gets the list of installed EE_Admin_pages. |
|
120 | - * |
|
121 | - * @access private |
|
122 | - * @return void |
|
123 | - * @throws EE_Error |
|
124 | - * @throws InvalidArgumentException |
|
125 | - * @throws InvalidDataTypeException |
|
126 | - * @throws InvalidInterfaceException |
|
127 | - * @throws ReflectionException |
|
128 | - */ |
|
129 | - private function findAndLoadAdminPages() |
|
130 | - { |
|
131 | - $admin_pages = $this->findAdminPages(); |
|
132 | - // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff. |
|
133 | - $admin_pages = $this->findCaffeinatedAdminPages($admin_pages); |
|
134 | - // then extensions and hooks, although they don't get added to the admin pages array |
|
135 | - $this->findAdminPageExtensions(); |
|
136 | - $this->findAdminPageHooks(); |
|
137 | - // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.; |
|
138 | - // loop through admin pages and setup the $_installed_pages array. |
|
139 | - $hooks_ref = []; |
|
140 | - $menu_pages = []; |
|
141 | - foreach ($admin_pages as $page => $path) { |
|
142 | - // don't load the page init class IF IT's ALREADY LOADED !!! |
|
143 | - if ( |
|
144 | - isset($this->_installed_pages[ $page ]) |
|
145 | - && $this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init |
|
146 | - ) { |
|
147 | - continue; |
|
148 | - } |
|
149 | - // build list of installed pages |
|
150 | - $admin_page_init = $this->loadAdminPageInit($page); |
|
151 | - $this->_installed_pages[ $page ] = $admin_page_init; |
|
152 | - $admin_menu = $this->menu_manager->getAdminMenu($admin_page_init); |
|
153 | - $admin_page_init->setCapability($admin_menu->capability(), $admin_menu->menuSlug()); |
|
154 | - // skip if in full maintenance mode and maintenance_mode_parent is NOT set |
|
155 | - if ($this->maintenance_mode && ! $admin_menu->maintenanceModeParent()) { |
|
156 | - unset($admin_pages[ $page ]); |
|
157 | - continue; |
|
158 | - } |
|
159 | - $menu_slug = $admin_menu->menuSlug(); |
|
160 | - $this->_menu_slugs[ $menu_slug ] = $page; |
|
161 | - $menu_pages[ $menu_slug ] = $admin_page_init; |
|
162 | - // now that we've got the admin_init objects... |
|
163 | - // lets see if there are any caffeinated pages extending the originals. |
|
164 | - // If there are then let's hook into the init admin filter and load our extend instead. |
|
165 | - // Set flag for register hooks on extended pages b/c extended pages use the default INIT. |
|
166 | - $extended_hooks = $admin_page_init->register_hooks( |
|
167 | - $this->loadCaffeinatedExtensions($admin_page_init, $page, $menu_slug) |
|
168 | - ); |
|
169 | - $hooks_ref += $extended_hooks; |
|
170 | - } |
|
171 | - // the hooks_ref is all the pages where we have $extended _Hooks files |
|
172 | - // that will extend a class in a different folder. |
|
173 | - // So we want to make sure we load the file for the parent. |
|
174 | - // first make sure we've got unique values |
|
175 | - $hooks_ref = array_unique($hooks_ref); |
|
176 | - // now let's loop and require! |
|
177 | - foreach ($hooks_ref as $path) { |
|
178 | - require_once($path); |
|
179 | - } |
|
180 | - // make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested. |
|
181 | - global $ee_menu_slugs; |
|
182 | - $ee_menu_slugs = $this->_menu_slugs; |
|
183 | - // we need to loop again to run any early code |
|
184 | - foreach ($this->_installed_pages as $page) { |
|
185 | - $page->do_initial_loads(); |
|
186 | - } |
|
187 | - $this->menu_manager->setInstalledPages($menu_pages); |
|
188 | - do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages); |
|
189 | - } |
|
190 | - |
|
191 | - |
|
192 | - /** |
|
193 | - * @return array |
|
194 | - * @throws EE_Error |
|
195 | - * @since $VID:$ |
|
196 | - */ |
|
197 | - private function findAdminPages(): array |
|
198 | - { |
|
199 | - |
|
200 | - // grab everything in the admin core directory |
|
201 | - $admin_page_folders = $this->findAdminPageFolders(EE_ADMIN_PAGES . '*'); |
|
202 | - $admin_page_folders = apply_filters( |
|
203 | - 'FHEE__EE_Admin_Page_Loader__findAdminPages__admin_page_folders', |
|
204 | - $admin_page_folders |
|
205 | - ); |
|
206 | - if (! empty($admin_page_folders)) { |
|
207 | - return $admin_page_folders; |
|
208 | - } |
|
209 | - $error_msg = esc_html__( |
|
210 | - 'There are no EE_Admin pages detected, it looks like EE did not install properly', |
|
211 | - 'event_espresso' |
|
212 | - ); |
|
213 | - $error_msg .= '||'; |
|
214 | - $error_msg .= sprintf( |
|
215 | - esc_html__( |
|
216 | - 'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.', |
|
217 | - 'event_espresso' |
|
218 | - ), |
|
219 | - EE_ADMIN_PAGES |
|
220 | - ); |
|
221 | - throw new RuntimeException($error_msg); |
|
222 | - } |
|
223 | - |
|
224 | - |
|
225 | - /** |
|
226 | - * get_admin_page_object |
|
227 | - * |
|
228 | - * @param string $page_slug |
|
229 | - * @return EE_Admin_Page |
|
230 | - */ |
|
231 | - public function get_admin_page_object(string $page_slug = ''): ?EE_Admin_Page |
|
232 | - { |
|
233 | - return isset($this->_installed_pages[ $page_slug ]) |
|
234 | - && $this->_installed_pages[ $page_slug ] instanceof EE_Admin_Page_Init |
|
235 | - ? $this->_installed_pages[ $page_slug ]->loaded_page_object() |
|
236 | - : null; |
|
237 | - } |
|
238 | - |
|
239 | - |
|
240 | - /** |
|
241 | - * generates an "Admin Page Init" class based on the directory name |
|
242 | - * |
|
243 | - * @param string $dir_name |
|
244 | - * @return string |
|
245 | - */ |
|
246 | - private function getClassnameForAdminPageInit(string $dir_name = ''): string |
|
247 | - { |
|
248 | - $class_name = str_replace('_', ' ', strtolower($dir_name)); |
|
249 | - return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init'; |
|
250 | - } |
|
251 | - |
|
252 | - |
|
253 | - /** |
|
254 | - * _load_admin_page |
|
255 | - * Loads and instantiates page_init object for a single EE_admin page. |
|
256 | - * |
|
257 | - * @param string $page page_reference |
|
258 | - * @return EE_Admin_Page_Init |
|
259 | - * @throws EE_Error |
|
260 | - */ |
|
261 | - private function loadAdminPageInit(string $page = ''): EE_Admin_Page_Init |
|
262 | - { |
|
263 | - $class_name = $this->getClassnameForAdminPageInit($page); |
|
264 | - if (class_exists($class_name)) { |
|
265 | - $admin_page_init = $this->loader->getShared($class_name); |
|
266 | - // verify returned object |
|
267 | - if ($admin_page_init instanceof EE_Admin_Page_Init) { |
|
268 | - return $admin_page_init; |
|
269 | - } |
|
270 | - } |
|
271 | - $error_msg = sprintf( |
|
272 | - esc_html__('Something went wrong with loading the %s admin page.', 'event_espresso'), |
|
273 | - $page |
|
274 | - ); |
|
275 | - $error_msg .= '||'; // separates public from developer messages |
|
276 | - $error_msg .= "\r\n"; |
|
277 | - $error_msg .= sprintf( |
|
278 | - esc_html__('There is no Init class in place for the %s admin page.', 'event_espresso'), |
|
279 | - $page |
|
280 | - ); |
|
281 | - $error_msg .= '<br />'; |
|
282 | - $error_msg .= sprintf( |
|
283 | - esc_html__( |
|
284 | - 'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
|
285 | - 'event_espresso' |
|
286 | - ), |
|
287 | - '<strong>' . $class_name . '</strong>' |
|
288 | - ); |
|
289 | - throw new EE_Error($error_msg); |
|
290 | - } |
|
291 | - |
|
292 | - |
|
293 | - /** |
|
294 | - * This method is the "workhorse" for detecting and setting up caffeinated functionality. |
|
295 | - * In this method there are three checks being done: |
|
296 | - * 1. Do we have any NEW admin page sets. If we do, lets add them into the menu setup (via the $admin_pages |
|
297 | - * array) etc. (new page sets are found in caffeinated/new/{page}) |
|
298 | - * 2. Do we have any EXTENDED page sets. Basically an extended EE_Admin Page extends the core {child}_Admin_Page |
|
299 | - * class. eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class: |
|
300 | - * Extend_Events_Admin_Page extends Events_Admin_Page. |
|
301 | - * 3. Do we have any files just for setting up hooks into other core pages. The files can be any name in |
|
302 | - * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the |
|
303 | - * classname inside. These classes are instantiated really early so that any hooks in them are run before the |
|
304 | - * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated |
|
305 | - * admin_pages) |
|
306 | - * |
|
307 | - * @param array $admin_pages the original installed_refs array that may contain our NEW EE_Admin_Pages to be |
|
308 | - * loaded. |
|
309 | - * @return array |
|
310 | - * @throws EE_Error |
|
311 | - */ |
|
312 | - private function findCaffeinatedAdminPages(array $admin_pages): array |
|
313 | - { |
|
314 | - // first let's check if there IS a caffeinated folder. If there is not then lets get out. |
|
315 | - if ((defined('EE_DECAF') && EE_DECAF) || ! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin')) { |
|
316 | - return $admin_pages; |
|
317 | - } |
|
318 | - $this->defineCaffeinatedConstants(); |
|
319 | - // okay let's setup an "New" pages first (we'll return installed refs later) |
|
320 | - $admin_pages += $this->findAdminPageFolders(EE_CORE_CAF_ADMIN . 'new/*', ['tickets']); |
|
321 | - |
|
322 | - return apply_filters( |
|
323 | - 'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs', |
|
324 | - $admin_pages |
|
325 | - ); |
|
326 | - } |
|
327 | - |
|
328 | - |
|
329 | - /** |
|
330 | - * @throws EE_Error |
|
331 | - * @since $VID:$ |
|
332 | - */ |
|
333 | - private function findAdminPageExtensions() |
|
334 | - { |
|
335 | - // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array |
|
336 | - // (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page) |
|
337 | - $extensions = $this->findAdminPageFolders(EE_CORE_CAF_ADMIN . 'extend/*'); |
|
338 | - if ($extensions) { |
|
339 | - foreach ($extensions as $folder => $extension) { |
|
340 | - // convert lowercase_snake_case to Uppercase_Snake_Case |
|
341 | - $filename = str_replace(' ', '_', ucwords(str_replace('_', ' ', $folder))); |
|
342 | - $filename = "Extend_{$filename}_Admin_Page"; |
|
343 | - $filepath = EE_CORE_CAF_ADMIN . "extend/$folder/$filename.core.php"; |
|
344 | - // save filename and filepath for later |
|
345 | - $this->_caffeinated_extends[ $folder ]['path'] = str_replace(['\\', '/'], '/', $filepath); |
|
346 | - $this->_caffeinated_extends[ $folder ]['admin_page'] = $filename; |
|
347 | - } |
|
348 | - } |
|
349 | - $this->_caffeinated_extends = apply_filters( |
|
350 | - 'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends', |
|
351 | - $this->_caffeinated_extends |
|
352 | - ); |
|
353 | - } |
|
354 | - |
|
355 | - |
|
356 | - private function loadCaffeinatedExtensions( |
|
357 | - EE_Admin_Page_Init $admin_page_init, |
|
358 | - string $page, |
|
359 | - string $menu_slug |
|
360 | - ): bool { |
|
361 | - if (! isset($this->_caffeinated_extends[ $page ])) { |
|
362 | - return false; |
|
363 | - } |
|
364 | - $admin_page_name = $admin_page_init->get_admin_page_name(); |
|
365 | - $caf_path = $this->_caffeinated_extends[ $page ]['path']; |
|
366 | - $caf_admin_page = $this->_caffeinated_extends[ $page ]['admin_page']; |
|
367 | - add_filter( |
|
368 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_$admin_page_name", |
|
369 | - static function ($path_to_file) use ($caf_path) { |
|
370 | - return $caf_path; |
|
371 | - } |
|
372 | - ); |
|
373 | - add_filter( |
|
374 | - "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_$admin_page_name", |
|
375 | - static function ($admin_page) use ($caf_admin_page) { |
|
376 | - return $caf_admin_page; |
|
377 | - } |
|
378 | - ); |
|
379 | - return true; |
|
380 | - } |
|
381 | - |
|
382 | - |
|
383 | - /** |
|
384 | - * @throws EE_Error |
|
385 | - * @since $VID:$ |
|
386 | - */ |
|
387 | - private function findAdminPageHooks() |
|
388 | - { |
|
389 | - // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!). |
|
390 | - $ee_admin_hooks = []; |
|
391 | - $admin_page_hooks = $this->findAdminPageFolders(EE_CORE_CAF_ADMIN . 'hooks/*.class.php', [], 0, false); |
|
392 | - if ($admin_page_hooks) { |
|
393 | - foreach ($admin_page_hooks as $hook) { |
|
394 | - if (is_readable($hook)) { |
|
395 | - require_once $hook; |
|
396 | - $classname = str_replace([EE_CORE_CAF_ADMIN . 'hooks/', '.class.php'], '', $hook); |
|
397 | - if (class_exists($classname)) { |
|
398 | - $ee_admin_hooks[] = $this->loader->getShared($classname); |
|
399 | - } |
|
400 | - } |
|
401 | - } |
|
402 | - } |
|
403 | - apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks); |
|
404 | - } |
|
405 | - |
|
406 | - |
|
407 | - /** |
|
408 | - * _default_header_link |
|
409 | - * This is just a dummy method to use with header submenu items |
|
410 | - * |
|
411 | - * @return bool false |
|
412 | - */ |
|
413 | - public function _default_header_link(): bool |
|
414 | - { |
|
415 | - return false; |
|
416 | - } |
|
417 | - |
|
418 | - |
|
419 | - /** |
|
420 | - * @param string $path |
|
421 | - * @param int $flags |
|
422 | - * @param array $exclude |
|
423 | - * @param bool $register_autoloaders |
|
424 | - * @return array |
|
425 | - * @throws EE_Error |
|
426 | - * @since $VID:$ |
|
427 | - */ |
|
428 | - private function findAdminPageFolders( |
|
429 | - string $path, |
|
430 | - array $exclude = [], |
|
431 | - int $flags = GLOB_ONLYDIR, |
|
432 | - bool $register_autoloaders = true |
|
433 | - ): array { |
|
434 | - $folders = []; |
|
435 | - $subfolders = glob($path, $flags); |
|
436 | - if ($subfolders) { |
|
437 | - foreach ($subfolders as $admin_screen) { |
|
438 | - $admin_screen_name = basename($admin_screen); |
|
439 | - // files and anything in the exclude array need not apply |
|
440 | - if (! in_array($admin_screen_name, $exclude, true)) { |
|
441 | - // these folders represent the different EE admin pages |
|
442 | - $folders[ $admin_screen_name ] = $admin_screen; |
|
443 | - if ($register_autoloaders) { |
|
444 | - // set autoloaders for our admin page classes based on included path information |
|
445 | - EEH_Autoloader::register_autoloaders_for_each_file_in_folder($admin_screen); |
|
446 | - } |
|
447 | - } |
|
448 | - } |
|
449 | - } |
|
450 | - return $folders; |
|
451 | - } |
|
19 | + /** |
|
20 | + * @var AdminMenuManager $menu_manager |
|
21 | + */ |
|
22 | + protected $menu_manager; |
|
23 | + |
|
24 | + /** |
|
25 | + * @var LoaderInterface $loader |
|
26 | + */ |
|
27 | + protected $loader; |
|
28 | + |
|
29 | + /** |
|
30 | + * _installed_pages |
|
31 | + * objects for page_init objects detected and loaded |
|
32 | + * |
|
33 | + * @access private |
|
34 | + * @var EE_Admin_Page_Init[] |
|
35 | + */ |
|
36 | + private $_installed_pages = []; |
|
37 | + |
|
38 | + |
|
39 | + /** |
|
40 | + * this is used to hold the registry of menu slugs for all the installed admin pages |
|
41 | + * |
|
42 | + * @var array |
|
43 | + */ |
|
44 | + private $_menu_slugs = []; |
|
45 | + |
|
46 | + |
|
47 | + /** |
|
48 | + * _caffeinated_extends |
|
49 | + * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and |
|
50 | + * pieces needed to do so). This property is defined in the _set_caffeinated method. |
|
51 | + * |
|
52 | + * @var array |
|
53 | + */ |
|
54 | + private $_caffeinated_extends = []; |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * This property will hold the hook file for setting up the filter that does all the connections between admin |
|
59 | + * pages. |
|
60 | + * |
|
61 | + * @var string |
|
62 | + */ |
|
63 | + public $hook_file; |
|
64 | + |
|
65 | + /** |
|
66 | + * @var int |
|
67 | + * @since $VID:$ |
|
68 | + */ |
|
69 | + private $maintenance_mode = 0; |
|
70 | + |
|
71 | + |
|
72 | + /** |
|
73 | + * @throws InvalidArgumentException |
|
74 | + * @throws InvalidDataTypeException |
|
75 | + * @throws InvalidInterfaceException |
|
76 | + */ |
|
77 | + public function __construct(?LoaderInterface $loader) |
|
78 | + { |
|
79 | + $this->loader = $loader instanceof LoaderInterface ? $loader : LoaderFactory::getLoader(); |
|
80 | + $this->menu_manager = $this->loader->getShared(AdminMenuManager::class, [$this->loader]); |
|
81 | + } |
|
82 | + |
|
83 | + |
|
84 | + /** |
|
85 | + * @throws EE_Error |
|
86 | + * @throws ReflectionException |
|
87 | + * @since $VID:$ |
|
88 | + */ |
|
89 | + public function init() |
|
90 | + { |
|
91 | + $this->menu_manager->initialize(); |
|
92 | + $this->maintenance_mode = EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance; |
|
93 | + // let's do a scan and see what installed pages we have |
|
94 | + $this->findAndLoadAdminPages(); |
|
95 | + } |
|
96 | + |
|
97 | + |
|
98 | + /** |
|
99 | + * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by |
|
100 | + * files in the caffeinated folder. |
|
101 | + * |
|
102 | + * @access private |
|
103 | + * @return void |
|
104 | + */ |
|
105 | + private function defineCaffeinatedConstants() |
|
106 | + { |
|
107 | + if (! defined('EE_CORE_CAF_ADMIN')) { |
|
108 | + define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/'); |
|
109 | + define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/'); |
|
110 | + define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/'); |
|
111 | + define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/'); |
|
112 | + define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/'); |
|
113 | + define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/'); |
|
114 | + } |
|
115 | + } |
|
116 | + |
|
117 | + |
|
118 | + /** |
|
119 | + * This just gets the list of installed EE_Admin_pages. |
|
120 | + * |
|
121 | + * @access private |
|
122 | + * @return void |
|
123 | + * @throws EE_Error |
|
124 | + * @throws InvalidArgumentException |
|
125 | + * @throws InvalidDataTypeException |
|
126 | + * @throws InvalidInterfaceException |
|
127 | + * @throws ReflectionException |
|
128 | + */ |
|
129 | + private function findAndLoadAdminPages() |
|
130 | + { |
|
131 | + $admin_pages = $this->findAdminPages(); |
|
132 | + // this just checks the caffeinated folder and takes care of setting up any caffeinated stuff. |
|
133 | + $admin_pages = $this->findCaffeinatedAdminPages($admin_pages); |
|
134 | + // then extensions and hooks, although they don't get added to the admin pages array |
|
135 | + $this->findAdminPageExtensions(); |
|
136 | + $this->findAdminPageHooks(); |
|
137 | + // allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.; |
|
138 | + // loop through admin pages and setup the $_installed_pages array. |
|
139 | + $hooks_ref = []; |
|
140 | + $menu_pages = []; |
|
141 | + foreach ($admin_pages as $page => $path) { |
|
142 | + // don't load the page init class IF IT's ALREADY LOADED !!! |
|
143 | + if ( |
|
144 | + isset($this->_installed_pages[ $page ]) |
|
145 | + && $this->_installed_pages[ $page ] instanceof EE_Admin_Page_Init |
|
146 | + ) { |
|
147 | + continue; |
|
148 | + } |
|
149 | + // build list of installed pages |
|
150 | + $admin_page_init = $this->loadAdminPageInit($page); |
|
151 | + $this->_installed_pages[ $page ] = $admin_page_init; |
|
152 | + $admin_menu = $this->menu_manager->getAdminMenu($admin_page_init); |
|
153 | + $admin_page_init->setCapability($admin_menu->capability(), $admin_menu->menuSlug()); |
|
154 | + // skip if in full maintenance mode and maintenance_mode_parent is NOT set |
|
155 | + if ($this->maintenance_mode && ! $admin_menu->maintenanceModeParent()) { |
|
156 | + unset($admin_pages[ $page ]); |
|
157 | + continue; |
|
158 | + } |
|
159 | + $menu_slug = $admin_menu->menuSlug(); |
|
160 | + $this->_menu_slugs[ $menu_slug ] = $page; |
|
161 | + $menu_pages[ $menu_slug ] = $admin_page_init; |
|
162 | + // now that we've got the admin_init objects... |
|
163 | + // lets see if there are any caffeinated pages extending the originals. |
|
164 | + // If there are then let's hook into the init admin filter and load our extend instead. |
|
165 | + // Set flag for register hooks on extended pages b/c extended pages use the default INIT. |
|
166 | + $extended_hooks = $admin_page_init->register_hooks( |
|
167 | + $this->loadCaffeinatedExtensions($admin_page_init, $page, $menu_slug) |
|
168 | + ); |
|
169 | + $hooks_ref += $extended_hooks; |
|
170 | + } |
|
171 | + // the hooks_ref is all the pages where we have $extended _Hooks files |
|
172 | + // that will extend a class in a different folder. |
|
173 | + // So we want to make sure we load the file for the parent. |
|
174 | + // first make sure we've got unique values |
|
175 | + $hooks_ref = array_unique($hooks_ref); |
|
176 | + // now let's loop and require! |
|
177 | + foreach ($hooks_ref as $path) { |
|
178 | + require_once($path); |
|
179 | + } |
|
180 | + // make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested. |
|
181 | + global $ee_menu_slugs; |
|
182 | + $ee_menu_slugs = $this->_menu_slugs; |
|
183 | + // we need to loop again to run any early code |
|
184 | + foreach ($this->_installed_pages as $page) { |
|
185 | + $page->do_initial_loads(); |
|
186 | + } |
|
187 | + $this->menu_manager->setInstalledPages($menu_pages); |
|
188 | + do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages); |
|
189 | + } |
|
190 | + |
|
191 | + |
|
192 | + /** |
|
193 | + * @return array |
|
194 | + * @throws EE_Error |
|
195 | + * @since $VID:$ |
|
196 | + */ |
|
197 | + private function findAdminPages(): array |
|
198 | + { |
|
199 | + |
|
200 | + // grab everything in the admin core directory |
|
201 | + $admin_page_folders = $this->findAdminPageFolders(EE_ADMIN_PAGES . '*'); |
|
202 | + $admin_page_folders = apply_filters( |
|
203 | + 'FHEE__EE_Admin_Page_Loader__findAdminPages__admin_page_folders', |
|
204 | + $admin_page_folders |
|
205 | + ); |
|
206 | + if (! empty($admin_page_folders)) { |
|
207 | + return $admin_page_folders; |
|
208 | + } |
|
209 | + $error_msg = esc_html__( |
|
210 | + 'There are no EE_Admin pages detected, it looks like EE did not install properly', |
|
211 | + 'event_espresso' |
|
212 | + ); |
|
213 | + $error_msg .= '||'; |
|
214 | + $error_msg .= sprintf( |
|
215 | + esc_html__( |
|
216 | + 'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.', |
|
217 | + 'event_espresso' |
|
218 | + ), |
|
219 | + EE_ADMIN_PAGES |
|
220 | + ); |
|
221 | + throw new RuntimeException($error_msg); |
|
222 | + } |
|
223 | + |
|
224 | + |
|
225 | + /** |
|
226 | + * get_admin_page_object |
|
227 | + * |
|
228 | + * @param string $page_slug |
|
229 | + * @return EE_Admin_Page |
|
230 | + */ |
|
231 | + public function get_admin_page_object(string $page_slug = ''): ?EE_Admin_Page |
|
232 | + { |
|
233 | + return isset($this->_installed_pages[ $page_slug ]) |
|
234 | + && $this->_installed_pages[ $page_slug ] instanceof EE_Admin_Page_Init |
|
235 | + ? $this->_installed_pages[ $page_slug ]->loaded_page_object() |
|
236 | + : null; |
|
237 | + } |
|
238 | + |
|
239 | + |
|
240 | + /** |
|
241 | + * generates an "Admin Page Init" class based on the directory name |
|
242 | + * |
|
243 | + * @param string $dir_name |
|
244 | + * @return string |
|
245 | + */ |
|
246 | + private function getClassnameForAdminPageInit(string $dir_name = ''): string |
|
247 | + { |
|
248 | + $class_name = str_replace('_', ' ', strtolower($dir_name)); |
|
249 | + return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init'; |
|
250 | + } |
|
251 | + |
|
252 | + |
|
253 | + /** |
|
254 | + * _load_admin_page |
|
255 | + * Loads and instantiates page_init object for a single EE_admin page. |
|
256 | + * |
|
257 | + * @param string $page page_reference |
|
258 | + * @return EE_Admin_Page_Init |
|
259 | + * @throws EE_Error |
|
260 | + */ |
|
261 | + private function loadAdminPageInit(string $page = ''): EE_Admin_Page_Init |
|
262 | + { |
|
263 | + $class_name = $this->getClassnameForAdminPageInit($page); |
|
264 | + if (class_exists($class_name)) { |
|
265 | + $admin_page_init = $this->loader->getShared($class_name); |
|
266 | + // verify returned object |
|
267 | + if ($admin_page_init instanceof EE_Admin_Page_Init) { |
|
268 | + return $admin_page_init; |
|
269 | + } |
|
270 | + } |
|
271 | + $error_msg = sprintf( |
|
272 | + esc_html__('Something went wrong with loading the %s admin page.', 'event_espresso'), |
|
273 | + $page |
|
274 | + ); |
|
275 | + $error_msg .= '||'; // separates public from developer messages |
|
276 | + $error_msg .= "\r\n"; |
|
277 | + $error_msg .= sprintf( |
|
278 | + esc_html__('There is no Init class in place for the %s admin page.', 'event_espresso'), |
|
279 | + $page |
|
280 | + ); |
|
281 | + $error_msg .= '<br />'; |
|
282 | + $error_msg .= sprintf( |
|
283 | + esc_html__( |
|
284 | + 'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class', |
|
285 | + 'event_espresso' |
|
286 | + ), |
|
287 | + '<strong>' . $class_name . '</strong>' |
|
288 | + ); |
|
289 | + throw new EE_Error($error_msg); |
|
290 | + } |
|
291 | + |
|
292 | + |
|
293 | + /** |
|
294 | + * This method is the "workhorse" for detecting and setting up caffeinated functionality. |
|
295 | + * In this method there are three checks being done: |
|
296 | + * 1. Do we have any NEW admin page sets. If we do, lets add them into the menu setup (via the $admin_pages |
|
297 | + * array) etc. (new page sets are found in caffeinated/new/{page}) |
|
298 | + * 2. Do we have any EXTENDED page sets. Basically an extended EE_Admin Page extends the core {child}_Admin_Page |
|
299 | + * class. eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class: |
|
300 | + * Extend_Events_Admin_Page extends Events_Admin_Page. |
|
301 | + * 3. Do we have any files just for setting up hooks into other core pages. The files can be any name in |
|
302 | + * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the |
|
303 | + * classname inside. These classes are instantiated really early so that any hooks in them are run before the |
|
304 | + * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated |
|
305 | + * admin_pages) |
|
306 | + * |
|
307 | + * @param array $admin_pages the original installed_refs array that may contain our NEW EE_Admin_Pages to be |
|
308 | + * loaded. |
|
309 | + * @return array |
|
310 | + * @throws EE_Error |
|
311 | + */ |
|
312 | + private function findCaffeinatedAdminPages(array $admin_pages): array |
|
313 | + { |
|
314 | + // first let's check if there IS a caffeinated folder. If there is not then lets get out. |
|
315 | + if ((defined('EE_DECAF') && EE_DECAF) || ! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated/admin')) { |
|
316 | + return $admin_pages; |
|
317 | + } |
|
318 | + $this->defineCaffeinatedConstants(); |
|
319 | + // okay let's setup an "New" pages first (we'll return installed refs later) |
|
320 | + $admin_pages += $this->findAdminPageFolders(EE_CORE_CAF_ADMIN . 'new/*', ['tickets']); |
|
321 | + |
|
322 | + return apply_filters( |
|
323 | + 'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs', |
|
324 | + $admin_pages |
|
325 | + ); |
|
326 | + } |
|
327 | + |
|
328 | + |
|
329 | + /** |
|
330 | + * @throws EE_Error |
|
331 | + * @since $VID:$ |
|
332 | + */ |
|
333 | + private function findAdminPageExtensions() |
|
334 | + { |
|
335 | + // let's see if there are any EXTENDS to setup in the $_caffeinated_extends array |
|
336 | + // (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page) |
|
337 | + $extensions = $this->findAdminPageFolders(EE_CORE_CAF_ADMIN . 'extend/*'); |
|
338 | + if ($extensions) { |
|
339 | + foreach ($extensions as $folder => $extension) { |
|
340 | + // convert lowercase_snake_case to Uppercase_Snake_Case |
|
341 | + $filename = str_replace(' ', '_', ucwords(str_replace('_', ' ', $folder))); |
|
342 | + $filename = "Extend_{$filename}_Admin_Page"; |
|
343 | + $filepath = EE_CORE_CAF_ADMIN . "extend/$folder/$filename.core.php"; |
|
344 | + // save filename and filepath for later |
|
345 | + $this->_caffeinated_extends[ $folder ]['path'] = str_replace(['\\', '/'], '/', $filepath); |
|
346 | + $this->_caffeinated_extends[ $folder ]['admin_page'] = $filename; |
|
347 | + } |
|
348 | + } |
|
349 | + $this->_caffeinated_extends = apply_filters( |
|
350 | + 'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends', |
|
351 | + $this->_caffeinated_extends |
|
352 | + ); |
|
353 | + } |
|
354 | + |
|
355 | + |
|
356 | + private function loadCaffeinatedExtensions( |
|
357 | + EE_Admin_Page_Init $admin_page_init, |
|
358 | + string $page, |
|
359 | + string $menu_slug |
|
360 | + ): bool { |
|
361 | + if (! isset($this->_caffeinated_extends[ $page ])) { |
|
362 | + return false; |
|
363 | + } |
|
364 | + $admin_page_name = $admin_page_init->get_admin_page_name(); |
|
365 | + $caf_path = $this->_caffeinated_extends[ $page ]['path']; |
|
366 | + $caf_admin_page = $this->_caffeinated_extends[ $page ]['admin_page']; |
|
367 | + add_filter( |
|
368 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_$admin_page_name", |
|
369 | + static function ($path_to_file) use ($caf_path) { |
|
370 | + return $caf_path; |
|
371 | + } |
|
372 | + ); |
|
373 | + add_filter( |
|
374 | + "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_$admin_page_name", |
|
375 | + static function ($admin_page) use ($caf_admin_page) { |
|
376 | + return $caf_admin_page; |
|
377 | + } |
|
378 | + ); |
|
379 | + return true; |
|
380 | + } |
|
381 | + |
|
382 | + |
|
383 | + /** |
|
384 | + * @throws EE_Error |
|
385 | + * @since $VID:$ |
|
386 | + */ |
|
387 | + private function findAdminPageHooks() |
|
388 | + { |
|
389 | + // let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!). |
|
390 | + $ee_admin_hooks = []; |
|
391 | + $admin_page_hooks = $this->findAdminPageFolders(EE_CORE_CAF_ADMIN . 'hooks/*.class.php', [], 0, false); |
|
392 | + if ($admin_page_hooks) { |
|
393 | + foreach ($admin_page_hooks as $hook) { |
|
394 | + if (is_readable($hook)) { |
|
395 | + require_once $hook; |
|
396 | + $classname = str_replace([EE_CORE_CAF_ADMIN . 'hooks/', '.class.php'], '', $hook); |
|
397 | + if (class_exists($classname)) { |
|
398 | + $ee_admin_hooks[] = $this->loader->getShared($classname); |
|
399 | + } |
|
400 | + } |
|
401 | + } |
|
402 | + } |
|
403 | + apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks); |
|
404 | + } |
|
405 | + |
|
406 | + |
|
407 | + /** |
|
408 | + * _default_header_link |
|
409 | + * This is just a dummy method to use with header submenu items |
|
410 | + * |
|
411 | + * @return bool false |
|
412 | + */ |
|
413 | + public function _default_header_link(): bool |
|
414 | + { |
|
415 | + return false; |
|
416 | + } |
|
417 | + |
|
418 | + |
|
419 | + /** |
|
420 | + * @param string $path |
|
421 | + * @param int $flags |
|
422 | + * @param array $exclude |
|
423 | + * @param bool $register_autoloaders |
|
424 | + * @return array |
|
425 | + * @throws EE_Error |
|
426 | + * @since $VID:$ |
|
427 | + */ |
|
428 | + private function findAdminPageFolders( |
|
429 | + string $path, |
|
430 | + array $exclude = [], |
|
431 | + int $flags = GLOB_ONLYDIR, |
|
432 | + bool $register_autoloaders = true |
|
433 | + ): array { |
|
434 | + $folders = []; |
|
435 | + $subfolders = glob($path, $flags); |
|
436 | + if ($subfolders) { |
|
437 | + foreach ($subfolders as $admin_screen) { |
|
438 | + $admin_screen_name = basename($admin_screen); |
|
439 | + // files and anything in the exclude array need not apply |
|
440 | + if (! in_array($admin_screen_name, $exclude, true)) { |
|
441 | + // these folders represent the different EE admin pages |
|
442 | + $folders[ $admin_screen_name ] = $admin_screen; |
|
443 | + if ($register_autoloaders) { |
|
444 | + // set autoloaders for our admin page classes based on included path information |
|
445 | + EEH_Autoloader::register_autoloaders_for_each_file_in_folder($admin_screen); |
|
446 | + } |
|
447 | + } |
|
448 | + } |
|
449 | + } |
|
450 | + return $folders; |
|
451 | + } |
|
452 | 452 | } |
@@ -24,225 +24,225 @@ |
||
24 | 24 | */ |
25 | 25 | class Event extends TypeBase |
26 | 26 | { |
27 | - /** |
|
28 | - * Event constructor. |
|
29 | - * |
|
30 | - * @param EEM_Event $event_model |
|
31 | - */ |
|
32 | - public function __construct(EEM_Event $event_model) |
|
33 | - { |
|
34 | - $this->setName($this->namespace . 'Event'); |
|
35 | - $this->setIsCustomPostType(true); |
|
36 | - parent::__construct($event_model); |
|
37 | - } |
|
27 | + /** |
|
28 | + * Event constructor. |
|
29 | + * |
|
30 | + * @param EEM_Event $event_model |
|
31 | + */ |
|
32 | + public function __construct(EEM_Event $event_model) |
|
33 | + { |
|
34 | + $this->setName($this->namespace . 'Event'); |
|
35 | + $this->setIsCustomPostType(true); |
|
36 | + parent::__construct($event_model); |
|
37 | + } |
|
38 | 38 | |
39 | 39 | |
40 | - /** |
|
41 | - * @return GraphQLFieldInterface[] |
|
42 | - */ |
|
43 | - public function getFields(): array |
|
44 | - { |
|
45 | - return apply_filters( |
|
46 | - 'FHEE__EventEspresso_core_domain_services_graphql_types__event_fields', |
|
47 | - [ |
|
48 | - new GraphQLField( |
|
49 | - 'allowDonations', |
|
50 | - 'Boolean', |
|
51 | - 'donations', |
|
52 | - esc_html__('Accept Donations?', 'event_espresso') |
|
53 | - ), |
|
54 | - new GraphQLField( |
|
55 | - 'allowOverflow', |
|
56 | - 'Boolean', |
|
57 | - 'allow_overflow', |
|
58 | - esc_html__('Enable Wait List for Event', 'event_espresso') |
|
59 | - ), |
|
60 | - new GraphQLField( |
|
61 | - 'altRegPage', |
|
62 | - 'String', |
|
63 | - 'external_url', |
|
64 | - esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso') |
|
65 | - ), |
|
66 | - new GraphQLOutputField( |
|
67 | - 'cacheId', |
|
68 | - ['non_null' => 'String'], |
|
69 | - null, |
|
70 | - esc_html__('The cache ID of the object.', 'event_espresso') |
|
71 | - ), |
|
72 | - new GraphQLField( |
|
73 | - 'created', |
|
74 | - 'String', |
|
75 | - 'created', |
|
76 | - esc_html__('Date/Time Event Created', 'event_espresso') |
|
77 | - ), |
|
78 | - new GraphQLOutputField( |
|
79 | - 'dbId', |
|
80 | - ['non_null' => 'Int'], |
|
81 | - 'ID', |
|
82 | - esc_html__('The event ID.', 'event_espresso') |
|
83 | - ), |
|
84 | - new GraphQLField( |
|
85 | - 'defaultRegStatus', |
|
86 | - $this->namespace . 'RegistrationStatusEnum', |
|
87 | - 'default_registration_status', |
|
88 | - esc_html__('Default Event Registration Status', 'event_espresso') |
|
89 | - ), |
|
90 | - new GraphQLField( |
|
91 | - 'description', |
|
92 | - 'String', |
|
93 | - 'description', |
|
94 | - esc_html__('Event Description', 'event_espresso') |
|
95 | - ), |
|
96 | - new GraphQLField( |
|
97 | - 'displayDescription', |
|
98 | - 'Boolean', |
|
99 | - 'display_description', |
|
100 | - esc_html__('Display Description Flag', 'event_espresso') |
|
101 | - ), |
|
102 | - new GraphQLField( |
|
103 | - 'displayTicketSelector', |
|
104 | - 'Boolean', |
|
105 | - 'display_ticket_selector', |
|
106 | - esc_html__('Display Ticket Selector Flag', 'event_espresso') |
|
107 | - ), |
|
108 | - new GraphQLOutputField( |
|
109 | - 'isActive', |
|
110 | - 'Boolean', |
|
111 | - 'is_active', |
|
112 | - esc_html__('Flag indicating event is active', 'event_espresso') |
|
113 | - ), |
|
114 | - new GraphQLOutputField( |
|
115 | - 'isCancelled', |
|
116 | - 'Boolean', |
|
117 | - 'is_cancelled', |
|
118 | - esc_html__('Flag indicating whether the event is marked as cancelled', 'event_espresso') |
|
119 | - ), |
|
120 | - new GraphQLOutputField( |
|
121 | - 'isExpired', |
|
122 | - 'Boolean', |
|
123 | - 'is_expired', |
|
124 | - esc_html__('Flag indicating event is expired or not', 'event_espresso') |
|
125 | - ), |
|
126 | - new GraphQLOutputField( |
|
127 | - 'isInactive', |
|
128 | - 'Boolean', |
|
129 | - 'is_inactive', |
|
130 | - esc_html__('Flag indicating event is inactive', 'event_espresso') |
|
131 | - ), |
|
132 | - new GraphQLOutputField( |
|
133 | - 'isPostponed', |
|
134 | - 'Boolean', |
|
135 | - 'is_postponed', |
|
136 | - esc_html__('Flag indicating whether the event is marked as postponed', 'event_espresso') |
|
137 | - ), |
|
138 | - new GraphQLOutputField( |
|
139 | - 'isSoldOut', |
|
140 | - 'Boolean', |
|
141 | - 'is_sold_out', |
|
142 | - esc_html__( |
|
143 | - 'Flag indicating whether the tickets sold for the event, met or exceed the registration limit', |
|
144 | - 'event_espresso' |
|
145 | - ) |
|
146 | - ), |
|
147 | - new GraphQLOutputField( |
|
148 | - 'isUpcoming', |
|
149 | - 'Boolean', |
|
150 | - 'is_upcoming', |
|
151 | - esc_html__('Whether the event is upcoming', 'event_espresso') |
|
152 | - ), |
|
153 | - new GraphQLInputField( |
|
154 | - 'manager', |
|
155 | - 'String', |
|
156 | - null, |
|
157 | - esc_html__('Globally unique event ID for the event manager', 'event_espresso') |
|
158 | - ), |
|
159 | - new GraphQLOutputField( |
|
160 | - 'manager', |
|
161 | - 'User', |
|
162 | - null, |
|
163 | - esc_html__('Event Manager', 'event_espresso') |
|
164 | - ), |
|
165 | - new GraphQLField( |
|
166 | - 'maxRegistrations', |
|
167 | - 'Int', |
|
168 | - 'additional_limit', |
|
169 | - esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso') |
|
170 | - ), |
|
171 | - new GraphQLField( |
|
172 | - 'memberOnly', |
|
173 | - 'Boolean', |
|
174 | - 'member_only', |
|
175 | - esc_html__('Member-Only Event Flag', 'event_espresso') |
|
176 | - ), |
|
177 | - new GraphQLField( |
|
178 | - 'name', |
|
179 | - 'String', |
|
180 | - 'name', |
|
181 | - esc_html__('Event Name', 'event_espresso') |
|
182 | - ), |
|
183 | - new GraphQLField( |
|
184 | - 'order', |
|
185 | - 'Int', |
|
186 | - 'order', |
|
187 | - esc_html__('Event Menu Order', 'event_espresso') |
|
188 | - ), |
|
189 | - new GraphQLField( |
|
190 | - 'phoneNumber', |
|
191 | - 'String', |
|
192 | - 'phone', |
|
193 | - esc_html__('Event Phone Number', 'event_espresso') |
|
194 | - ), |
|
195 | - new GraphQLField( |
|
196 | - 'shortDescription', |
|
197 | - 'String', |
|
198 | - 'short_description', |
|
199 | - esc_html__('Event Short Description', 'event_espresso') |
|
200 | - ), |
|
201 | - new GraphQLField( |
|
202 | - 'timezoneString', |
|
203 | - 'String', |
|
204 | - 'timezone_string', |
|
205 | - esc_html__('Timezone (name) for Event times', 'event_espresso') |
|
206 | - ), |
|
207 | - new GraphQLField( |
|
208 | - 'visibleOn', |
|
209 | - 'String', |
|
210 | - 'visible_on', |
|
211 | - esc_html__('Event Visible Date', 'event_espresso') |
|
212 | - ), |
|
213 | - new GraphQLField( |
|
214 | - 'venue', |
|
215 | - 'String', |
|
216 | - null, |
|
217 | - esc_html__('Event venue ID', 'event_espresso'), |
|
218 | - null, |
|
219 | - function (EE_Event $source) { |
|
220 | - $venue_ID = $source->venue_ID(); |
|
221 | - return $venue_ID |
|
222 | - // Since venue is a CPT, $type will be 'post' |
|
223 | - ? Relay::toGlobalId('post', $venue_ID) |
|
224 | - : null; |
|
225 | - } |
|
226 | - ), |
|
227 | - ], |
|
228 | - $this->name, |
|
229 | - $this->model |
|
230 | - ); |
|
231 | - } |
|
40 | + /** |
|
41 | + * @return GraphQLFieldInterface[] |
|
42 | + */ |
|
43 | + public function getFields(): array |
|
44 | + { |
|
45 | + return apply_filters( |
|
46 | + 'FHEE__EventEspresso_core_domain_services_graphql_types__event_fields', |
|
47 | + [ |
|
48 | + new GraphQLField( |
|
49 | + 'allowDonations', |
|
50 | + 'Boolean', |
|
51 | + 'donations', |
|
52 | + esc_html__('Accept Donations?', 'event_espresso') |
|
53 | + ), |
|
54 | + new GraphQLField( |
|
55 | + 'allowOverflow', |
|
56 | + 'Boolean', |
|
57 | + 'allow_overflow', |
|
58 | + esc_html__('Enable Wait List for Event', 'event_espresso') |
|
59 | + ), |
|
60 | + new GraphQLField( |
|
61 | + 'altRegPage', |
|
62 | + 'String', |
|
63 | + 'external_url', |
|
64 | + esc_html__('URL of Event Page if hosted elsewhere', 'event_espresso') |
|
65 | + ), |
|
66 | + new GraphQLOutputField( |
|
67 | + 'cacheId', |
|
68 | + ['non_null' => 'String'], |
|
69 | + null, |
|
70 | + esc_html__('The cache ID of the object.', 'event_espresso') |
|
71 | + ), |
|
72 | + new GraphQLField( |
|
73 | + 'created', |
|
74 | + 'String', |
|
75 | + 'created', |
|
76 | + esc_html__('Date/Time Event Created', 'event_espresso') |
|
77 | + ), |
|
78 | + new GraphQLOutputField( |
|
79 | + 'dbId', |
|
80 | + ['non_null' => 'Int'], |
|
81 | + 'ID', |
|
82 | + esc_html__('The event ID.', 'event_espresso') |
|
83 | + ), |
|
84 | + new GraphQLField( |
|
85 | + 'defaultRegStatus', |
|
86 | + $this->namespace . 'RegistrationStatusEnum', |
|
87 | + 'default_registration_status', |
|
88 | + esc_html__('Default Event Registration Status', 'event_espresso') |
|
89 | + ), |
|
90 | + new GraphQLField( |
|
91 | + 'description', |
|
92 | + 'String', |
|
93 | + 'description', |
|
94 | + esc_html__('Event Description', 'event_espresso') |
|
95 | + ), |
|
96 | + new GraphQLField( |
|
97 | + 'displayDescription', |
|
98 | + 'Boolean', |
|
99 | + 'display_description', |
|
100 | + esc_html__('Display Description Flag', 'event_espresso') |
|
101 | + ), |
|
102 | + new GraphQLField( |
|
103 | + 'displayTicketSelector', |
|
104 | + 'Boolean', |
|
105 | + 'display_ticket_selector', |
|
106 | + esc_html__('Display Ticket Selector Flag', 'event_espresso') |
|
107 | + ), |
|
108 | + new GraphQLOutputField( |
|
109 | + 'isActive', |
|
110 | + 'Boolean', |
|
111 | + 'is_active', |
|
112 | + esc_html__('Flag indicating event is active', 'event_espresso') |
|
113 | + ), |
|
114 | + new GraphQLOutputField( |
|
115 | + 'isCancelled', |
|
116 | + 'Boolean', |
|
117 | + 'is_cancelled', |
|
118 | + esc_html__('Flag indicating whether the event is marked as cancelled', 'event_espresso') |
|
119 | + ), |
|
120 | + new GraphQLOutputField( |
|
121 | + 'isExpired', |
|
122 | + 'Boolean', |
|
123 | + 'is_expired', |
|
124 | + esc_html__('Flag indicating event is expired or not', 'event_espresso') |
|
125 | + ), |
|
126 | + new GraphQLOutputField( |
|
127 | + 'isInactive', |
|
128 | + 'Boolean', |
|
129 | + 'is_inactive', |
|
130 | + esc_html__('Flag indicating event is inactive', 'event_espresso') |
|
131 | + ), |
|
132 | + new GraphQLOutputField( |
|
133 | + 'isPostponed', |
|
134 | + 'Boolean', |
|
135 | + 'is_postponed', |
|
136 | + esc_html__('Flag indicating whether the event is marked as postponed', 'event_espresso') |
|
137 | + ), |
|
138 | + new GraphQLOutputField( |
|
139 | + 'isSoldOut', |
|
140 | + 'Boolean', |
|
141 | + 'is_sold_out', |
|
142 | + esc_html__( |
|
143 | + 'Flag indicating whether the tickets sold for the event, met or exceed the registration limit', |
|
144 | + 'event_espresso' |
|
145 | + ) |
|
146 | + ), |
|
147 | + new GraphQLOutputField( |
|
148 | + 'isUpcoming', |
|
149 | + 'Boolean', |
|
150 | + 'is_upcoming', |
|
151 | + esc_html__('Whether the event is upcoming', 'event_espresso') |
|
152 | + ), |
|
153 | + new GraphQLInputField( |
|
154 | + 'manager', |
|
155 | + 'String', |
|
156 | + null, |
|
157 | + esc_html__('Globally unique event ID for the event manager', 'event_espresso') |
|
158 | + ), |
|
159 | + new GraphQLOutputField( |
|
160 | + 'manager', |
|
161 | + 'User', |
|
162 | + null, |
|
163 | + esc_html__('Event Manager', 'event_espresso') |
|
164 | + ), |
|
165 | + new GraphQLField( |
|
166 | + 'maxRegistrations', |
|
167 | + 'Int', |
|
168 | + 'additional_limit', |
|
169 | + esc_html__('Limit of Additional Registrations on Same Transaction', 'event_espresso') |
|
170 | + ), |
|
171 | + new GraphQLField( |
|
172 | + 'memberOnly', |
|
173 | + 'Boolean', |
|
174 | + 'member_only', |
|
175 | + esc_html__('Member-Only Event Flag', 'event_espresso') |
|
176 | + ), |
|
177 | + new GraphQLField( |
|
178 | + 'name', |
|
179 | + 'String', |
|
180 | + 'name', |
|
181 | + esc_html__('Event Name', 'event_espresso') |
|
182 | + ), |
|
183 | + new GraphQLField( |
|
184 | + 'order', |
|
185 | + 'Int', |
|
186 | + 'order', |
|
187 | + esc_html__('Event Menu Order', 'event_espresso') |
|
188 | + ), |
|
189 | + new GraphQLField( |
|
190 | + 'phoneNumber', |
|
191 | + 'String', |
|
192 | + 'phone', |
|
193 | + esc_html__('Event Phone Number', 'event_espresso') |
|
194 | + ), |
|
195 | + new GraphQLField( |
|
196 | + 'shortDescription', |
|
197 | + 'String', |
|
198 | + 'short_description', |
|
199 | + esc_html__('Event Short Description', 'event_espresso') |
|
200 | + ), |
|
201 | + new GraphQLField( |
|
202 | + 'timezoneString', |
|
203 | + 'String', |
|
204 | + 'timezone_string', |
|
205 | + esc_html__('Timezone (name) for Event times', 'event_espresso') |
|
206 | + ), |
|
207 | + new GraphQLField( |
|
208 | + 'visibleOn', |
|
209 | + 'String', |
|
210 | + 'visible_on', |
|
211 | + esc_html__('Event Visible Date', 'event_espresso') |
|
212 | + ), |
|
213 | + new GraphQLField( |
|
214 | + 'venue', |
|
215 | + 'String', |
|
216 | + null, |
|
217 | + esc_html__('Event venue ID', 'event_espresso'), |
|
218 | + null, |
|
219 | + function (EE_Event $source) { |
|
220 | + $venue_ID = $source->venue_ID(); |
|
221 | + return $venue_ID |
|
222 | + // Since venue is a CPT, $type will be 'post' |
|
223 | + ? Relay::toGlobalId('post', $venue_ID) |
|
224 | + : null; |
|
225 | + } |
|
226 | + ), |
|
227 | + ], |
|
228 | + $this->name, |
|
229 | + $this->model |
|
230 | + ); |
|
231 | + } |
|
232 | 232 | |
233 | 233 | |
234 | - /** |
|
235 | - * Extends the existing WP GraphQL mutations. |
|
236 | - * |
|
237 | - * @since $VID:$ |
|
238 | - */ |
|
239 | - public function extendMutations() |
|
240 | - { |
|
241 | - add_action( |
|
242 | - 'graphql_post_object_mutation_update_additional_data', |
|
243 | - EventUpdate::mutateFields($this->model, $this), |
|
244 | - 10, |
|
245 | - 6 |
|
246 | - ); |
|
247 | - } |
|
234 | + /** |
|
235 | + * Extends the existing WP GraphQL mutations. |
|
236 | + * |
|
237 | + * @since $VID:$ |
|
238 | + */ |
|
239 | + public function extendMutations() |
|
240 | + { |
|
241 | + add_action( |
|
242 | + 'graphql_post_object_mutation_update_additional_data', |
|
243 | + EventUpdate::mutateFields($this->model, $this), |
|
244 | + 10, |
|
245 | + 6 |
|
246 | + ); |
|
247 | + } |
|
248 | 248 | } |
@@ -12,1560 +12,1560 @@ |
||
12 | 12 | */ |
13 | 13 | class EE_Datetime extends EE_Soft_Delete_Base_Class |
14 | 14 | { |
15 | - /** |
|
16 | - * constant used by get_active_status, indicates datetime has no more available spaces |
|
17 | - */ |
|
18 | - const sold_out = 'DTS'; |
|
19 | - |
|
20 | - /** |
|
21 | - * constant used by get_active_status, indicating datetime is still active (even is not over, can be registered-for) |
|
22 | - */ |
|
23 | - const active = 'DTA'; |
|
24 | - |
|
25 | - /** |
|
26 | - * constant used by get_active_status, indicating the datetime cannot be used for registrations yet, but has not |
|
27 | - * expired |
|
28 | - */ |
|
29 | - const upcoming = 'DTU'; |
|
30 | - |
|
31 | - /** |
|
32 | - * Datetime is postponed |
|
33 | - */ |
|
34 | - const postponed = 'DTP'; |
|
35 | - |
|
36 | - /** |
|
37 | - * Datetime is cancelled |
|
38 | - */ |
|
39 | - const cancelled = 'DTC'; |
|
40 | - |
|
41 | - /** |
|
42 | - * constant used by get_active_status, indicates datetime has expired (event is over) |
|
43 | - */ |
|
44 | - const expired = 'DTE'; |
|
45 | - |
|
46 | - /** |
|
47 | - * constant used in various places indicating that an event is INACTIVE (not yet ready to be published) |
|
48 | - */ |
|
49 | - const inactive = 'DTI'; |
|
50 | - |
|
51 | - |
|
52 | - /** |
|
53 | - * @param array $props_n_values incoming values |
|
54 | - * @param string $timezone incoming timezone (if not set the timezone set for the website will be used.) |
|
55 | - * @param array $date_formats incoming date_formats in an array where the first value is the date_format |
|
56 | - * and the second value is the time format |
|
57 | - * @return EE_Datetime |
|
58 | - * @throws ReflectionException |
|
59 | - * @throws InvalidArgumentException |
|
60 | - * @throws InvalidInterfaceException |
|
61 | - * @throws InvalidDataTypeException |
|
62 | - * @throws EE_Error |
|
63 | - */ |
|
64 | - public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
65 | - { |
|
66 | - $has_object = parent::_check_for_object( |
|
67 | - $props_n_values, |
|
68 | - __CLASS__, |
|
69 | - $timezone, |
|
70 | - $date_formats |
|
71 | - ); |
|
72 | - return $has_object |
|
73 | - ? $has_object |
|
74 | - : new self($props_n_values, false, $timezone, $date_formats); |
|
75 | - } |
|
76 | - |
|
77 | - |
|
78 | - /** |
|
79 | - * @param array $props_n_values incoming values from the database |
|
80 | - * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
81 | - * the website will be used. |
|
82 | - * @return EE_Datetime |
|
83 | - * @throws ReflectionException |
|
84 | - * @throws InvalidArgumentException |
|
85 | - * @throws InvalidInterfaceException |
|
86 | - * @throws InvalidDataTypeException |
|
87 | - * @throws EE_Error |
|
88 | - */ |
|
89 | - public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
90 | - { |
|
91 | - return new self($props_n_values, true, $timezone); |
|
92 | - } |
|
93 | - |
|
94 | - |
|
95 | - /** |
|
96 | - * @param $name |
|
97 | - * @throws ReflectionException |
|
98 | - * @throws InvalidArgumentException |
|
99 | - * @throws InvalidInterfaceException |
|
100 | - * @throws InvalidDataTypeException |
|
101 | - * @throws EE_Error |
|
102 | - */ |
|
103 | - public function set_name($name) |
|
104 | - { |
|
105 | - $this->set('DTT_name', $name); |
|
106 | - } |
|
107 | - |
|
108 | - |
|
109 | - /** |
|
110 | - * @param $description |
|
111 | - * @throws ReflectionException |
|
112 | - * @throws InvalidArgumentException |
|
113 | - * @throws InvalidInterfaceException |
|
114 | - * @throws InvalidDataTypeException |
|
115 | - * @throws EE_Error |
|
116 | - */ |
|
117 | - public function set_description($description) |
|
118 | - { |
|
119 | - $this->set('DTT_description', $description); |
|
120 | - } |
|
121 | - |
|
122 | - |
|
123 | - /** |
|
124 | - * Set event start date |
|
125 | - * set the start date for an event |
|
126 | - * |
|
127 | - * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
128 | - * @throws ReflectionException |
|
129 | - * @throws InvalidArgumentException |
|
130 | - * @throws InvalidInterfaceException |
|
131 | - * @throws InvalidDataTypeException |
|
132 | - * @throws EE_Error |
|
133 | - */ |
|
134 | - public function set_start_date($date) |
|
135 | - { |
|
136 | - $this->_set_date_for($date, 'DTT_EVT_start'); |
|
137 | - } |
|
138 | - |
|
139 | - |
|
140 | - /** |
|
141 | - * Set event start time |
|
142 | - * set the start time for an event |
|
143 | - * |
|
144 | - * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
145 | - * @throws ReflectionException |
|
146 | - * @throws InvalidArgumentException |
|
147 | - * @throws InvalidInterfaceException |
|
148 | - * @throws InvalidDataTypeException |
|
149 | - * @throws EE_Error |
|
150 | - */ |
|
151 | - public function set_start_time($time) |
|
152 | - { |
|
153 | - $this->_set_time_for($time, 'DTT_EVT_start'); |
|
154 | - } |
|
155 | - |
|
156 | - |
|
157 | - /** |
|
158 | - * Set event end date |
|
159 | - * set the end date for an event |
|
160 | - * |
|
161 | - * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
162 | - * @throws ReflectionException |
|
163 | - * @throws InvalidArgumentException |
|
164 | - * @throws InvalidInterfaceException |
|
165 | - * @throws InvalidDataTypeException |
|
166 | - * @throws EE_Error |
|
167 | - */ |
|
168 | - public function set_end_date($date) |
|
169 | - { |
|
170 | - $this->_set_date_for($date, 'DTT_EVT_end'); |
|
171 | - } |
|
172 | - |
|
173 | - |
|
174 | - /** |
|
175 | - * Set event end time |
|
176 | - * set the end time for an event |
|
177 | - * |
|
178 | - * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
179 | - * @throws ReflectionException |
|
180 | - * @throws InvalidArgumentException |
|
181 | - * @throws InvalidInterfaceException |
|
182 | - * @throws InvalidDataTypeException |
|
183 | - * @throws EE_Error |
|
184 | - */ |
|
185 | - public function set_end_time($time) |
|
186 | - { |
|
187 | - $this->_set_time_for($time, 'DTT_EVT_end'); |
|
188 | - } |
|
189 | - |
|
190 | - |
|
191 | - /** |
|
192 | - * Set registration limit |
|
193 | - * set the maximum number of attendees that can be registered for this datetime slot |
|
194 | - * |
|
195 | - * @param int|float $reg_limit |
|
196 | - * @throws ReflectionException |
|
197 | - * @throws InvalidArgumentException |
|
198 | - * @throws InvalidInterfaceException |
|
199 | - * @throws InvalidDataTypeException |
|
200 | - * @throws EE_Error |
|
201 | - */ |
|
202 | - public function set_reg_limit($reg_limit) |
|
203 | - { |
|
204 | - $this->set('DTT_reg_limit', $reg_limit); |
|
205 | - } |
|
206 | - |
|
207 | - |
|
208 | - /** |
|
209 | - * get the number of tickets sold for this datetime slot |
|
210 | - * |
|
211 | - * @return mixed int on success, FALSE on fail |
|
212 | - * @throws ReflectionException |
|
213 | - * @throws InvalidArgumentException |
|
214 | - * @throws InvalidInterfaceException |
|
215 | - * @throws InvalidDataTypeException |
|
216 | - * @throws EE_Error |
|
217 | - */ |
|
218 | - public function sold() |
|
219 | - { |
|
220 | - return $this->get_raw('DTT_sold'); |
|
221 | - } |
|
222 | - |
|
223 | - |
|
224 | - /** |
|
225 | - * @param int $sold |
|
226 | - * @throws ReflectionException |
|
227 | - * @throws InvalidArgumentException |
|
228 | - * @throws InvalidInterfaceException |
|
229 | - * @throws InvalidDataTypeException |
|
230 | - * @throws EE_Error |
|
231 | - */ |
|
232 | - public function set_sold($sold) |
|
233 | - { |
|
234 | - // sold can not go below zero |
|
235 | - $sold = max(0, $sold); |
|
236 | - $this->set('DTT_sold', $sold); |
|
237 | - } |
|
238 | - |
|
239 | - |
|
240 | - /** |
|
241 | - * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
242 | - * Simultaneously decreases the reserved count, unless $also_decrease_reserved is false. |
|
243 | - * |
|
244 | - * @param int $qty |
|
245 | - * @param boolean $also_decrease_reserved |
|
246 | - * @return boolean indicating success |
|
247 | - * @throws ReflectionException |
|
248 | - * @throws InvalidArgumentException |
|
249 | - * @throws InvalidInterfaceException |
|
250 | - * @throws InvalidDataTypeException |
|
251 | - * @throws EE_Error |
|
252 | - */ |
|
253 | - public function increaseSold(int $qty = 1, bool $also_decrease_reserved = true): bool |
|
254 | - { |
|
255 | - $qty = absint($qty); |
|
256 | - if ($also_decrease_reserved) { |
|
257 | - $success = $this->adjustNumericFieldsInDb( |
|
258 | - [ |
|
259 | - 'DTT_reserved' => $qty * -1, |
|
260 | - 'DTT_sold' => $qty |
|
261 | - ] |
|
262 | - ); |
|
263 | - } else { |
|
264 | - $success = $this->adjustNumericFieldsInDb( |
|
265 | - [ |
|
266 | - 'DTT_sold' => $qty |
|
267 | - ] |
|
268 | - ); |
|
269 | - } |
|
270 | - |
|
271 | - do_action( |
|
272 | - 'AHEE__EE_Datetime__increase_sold', |
|
273 | - $this, |
|
274 | - $qty, |
|
275 | - $this->sold(), |
|
276 | - $success |
|
277 | - ); |
|
278 | - return $success; |
|
279 | - } |
|
280 | - |
|
281 | - |
|
282 | - /** |
|
283 | - * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
284 | - * to save afterwards.) |
|
285 | - * |
|
286 | - * @param int $qty |
|
287 | - * @return boolean indicating success |
|
288 | - * @throws ReflectionException |
|
289 | - * @throws InvalidArgumentException |
|
290 | - * @throws InvalidInterfaceException |
|
291 | - * @throws InvalidDataTypeException |
|
292 | - * @throws EE_Error |
|
293 | - */ |
|
294 | - public function decreaseSold(int $qty = 1): bool |
|
295 | - { |
|
296 | - $qty = absint($qty); |
|
297 | - $success = $this->adjustNumericFieldsInDb( |
|
298 | - [ |
|
299 | - 'DTT_sold' => $qty * -1 |
|
300 | - ] |
|
301 | - ); |
|
302 | - do_action( |
|
303 | - 'AHEE__EE_Datetime__decrease_sold', |
|
304 | - $this, |
|
305 | - $qty, |
|
306 | - $this->sold(), |
|
307 | - $success |
|
308 | - ); |
|
309 | - return $success; |
|
310 | - } |
|
311 | - |
|
312 | - |
|
313 | - /** |
|
314 | - * Gets qty of reserved tickets for this datetime |
|
315 | - * |
|
316 | - * @return int |
|
317 | - * @throws ReflectionException |
|
318 | - * @throws InvalidArgumentException |
|
319 | - * @throws InvalidInterfaceException |
|
320 | - * @throws InvalidDataTypeException |
|
321 | - * @throws EE_Error |
|
322 | - */ |
|
323 | - public function reserved(): int |
|
324 | - { |
|
325 | - return $this->get_raw('DTT_reserved'); |
|
326 | - } |
|
327 | - |
|
328 | - |
|
329 | - /** |
|
330 | - * Sets qty of reserved tickets for this datetime |
|
331 | - * |
|
332 | - * @param int $reserved |
|
333 | - * @throws ReflectionException |
|
334 | - * @throws InvalidArgumentException |
|
335 | - * @throws InvalidInterfaceException |
|
336 | - * @throws InvalidDataTypeException |
|
337 | - * @throws EE_Error |
|
338 | - */ |
|
339 | - public function set_reserved(int $reserved) |
|
340 | - { |
|
341 | - // reserved can not go below zero |
|
342 | - $reserved = max(0, $reserved); |
|
343 | - $this->set('DTT_reserved', $reserved); |
|
344 | - } |
|
345 | - |
|
346 | - |
|
347 | - /** |
|
348 | - * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
349 | - * |
|
350 | - * @param int $qty |
|
351 | - * @return boolean indicating success |
|
352 | - * @throws ReflectionException |
|
353 | - * @throws InvalidArgumentException |
|
354 | - * @throws InvalidInterfaceException |
|
355 | - * @throws InvalidDataTypeException |
|
356 | - * @throws EE_Error |
|
357 | - */ |
|
358 | - public function increaseReserved(int $qty = 1): bool |
|
359 | - { |
|
360 | - $qty = absint($qty); |
|
361 | - $success = $this->incrementFieldConditionallyInDb( |
|
362 | - 'DTT_reserved', |
|
363 | - 'DTT_sold', |
|
364 | - 'DTT_reg_limit', |
|
365 | - $qty |
|
366 | - ); |
|
367 | - do_action( |
|
368 | - 'AHEE__EE_Datetime__increase_reserved', |
|
369 | - $this, |
|
370 | - $qty, |
|
371 | - $this->reserved(), |
|
372 | - $success |
|
373 | - ); |
|
374 | - return $success; |
|
375 | - } |
|
376 | - |
|
377 | - |
|
378 | - /** |
|
379 | - * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
380 | - * |
|
381 | - * @param int $qty |
|
382 | - * @return boolean indicating success |
|
383 | - * @throws ReflectionException |
|
384 | - * @throws InvalidArgumentException |
|
385 | - * @throws InvalidInterfaceException |
|
386 | - * @throws InvalidDataTypeException |
|
387 | - * @throws EE_Error |
|
388 | - */ |
|
389 | - public function decreaseReserved(int $qty = 1): bool |
|
390 | - { |
|
391 | - $qty = absint($qty); |
|
392 | - $success = $this->adjustNumericFieldsInDb( |
|
393 | - [ |
|
394 | - 'DTT_reserved' => $qty * -1 |
|
395 | - ] |
|
396 | - ); |
|
397 | - do_action( |
|
398 | - 'AHEE__EE_Datetime__decrease_reserved', |
|
399 | - $this, |
|
400 | - $qty, |
|
401 | - $this->reserved(), |
|
402 | - $success |
|
403 | - ); |
|
404 | - return $success; |
|
405 | - } |
|
406 | - |
|
407 | - |
|
408 | - /** |
|
409 | - * total sold and reserved tickets |
|
410 | - * |
|
411 | - * @return int |
|
412 | - * @throws ReflectionException |
|
413 | - * @throws InvalidArgumentException |
|
414 | - * @throws InvalidInterfaceException |
|
415 | - * @throws InvalidDataTypeException |
|
416 | - * @throws EE_Error |
|
417 | - */ |
|
418 | - public function sold_and_reserved(): int |
|
419 | - { |
|
420 | - return $this->sold() + $this->reserved(); |
|
421 | - } |
|
422 | - |
|
423 | - |
|
424 | - /** |
|
425 | - * returns the datetime name |
|
426 | - * |
|
427 | - * @return string |
|
428 | - * @throws ReflectionException |
|
429 | - * @throws InvalidArgumentException |
|
430 | - * @throws InvalidInterfaceException |
|
431 | - * @throws InvalidDataTypeException |
|
432 | - * @throws EE_Error |
|
433 | - */ |
|
434 | - public function name(): string |
|
435 | - { |
|
436 | - return $this->get('DTT_name'); |
|
437 | - } |
|
438 | - |
|
439 | - |
|
440 | - /** |
|
441 | - * returns the datetime description |
|
442 | - * |
|
443 | - * @return string |
|
444 | - * @throws ReflectionException |
|
445 | - * @throws InvalidArgumentException |
|
446 | - * @throws InvalidInterfaceException |
|
447 | - * @throws InvalidDataTypeException |
|
448 | - * @throws EE_Error |
|
449 | - */ |
|
450 | - public function description(): string |
|
451 | - { |
|
452 | - return $this->get('DTT_description'); |
|
453 | - } |
|
454 | - |
|
455 | - |
|
456 | - /** |
|
457 | - * This helper simply returns whether the event_datetime for the current datetime is a primary datetime |
|
458 | - * |
|
459 | - * @return boolean TRUE if is primary, FALSE if not. |
|
460 | - * @throws ReflectionException |
|
461 | - * @throws InvalidArgumentException |
|
462 | - * @throws InvalidInterfaceException |
|
463 | - * @throws InvalidDataTypeException |
|
464 | - * @throws EE_Error |
|
465 | - */ |
|
466 | - public function is_primary(): bool |
|
467 | - { |
|
468 | - return $this->get('DTT_is_primary'); |
|
469 | - } |
|
470 | - |
|
471 | - |
|
472 | - /** |
|
473 | - * This helper simply returns the order for the datetime |
|
474 | - * |
|
475 | - * @return int The order of the datetime for this event. |
|
476 | - * @throws ReflectionException |
|
477 | - * @throws InvalidArgumentException |
|
478 | - * @throws InvalidInterfaceException |
|
479 | - * @throws InvalidDataTypeException |
|
480 | - * @throws EE_Error |
|
481 | - */ |
|
482 | - public function order(): int |
|
483 | - { |
|
484 | - return $this->get('DTT_order'); |
|
485 | - } |
|
486 | - |
|
487 | - |
|
488 | - /** |
|
489 | - * This helper simply returns the parent id for the datetime |
|
490 | - * |
|
491 | - * @return int |
|
492 | - * @throws ReflectionException |
|
493 | - * @throws InvalidArgumentException |
|
494 | - * @throws InvalidInterfaceException |
|
495 | - * @throws InvalidDataTypeException |
|
496 | - * @throws EE_Error |
|
497 | - */ |
|
498 | - public function parent(): int |
|
499 | - { |
|
500 | - return $this->get('DTT_parent'); |
|
501 | - } |
|
502 | - |
|
503 | - |
|
504 | - /** |
|
505 | - * show date and/or time |
|
506 | - * |
|
507 | - * @param string $date_or_time whether to display a date or time or both |
|
508 | - * @param string $start_or_end whether to display start or end datetimes |
|
509 | - * @param string $dt_frmt |
|
510 | - * @param string $tm_frmt |
|
511 | - * @param bool $echo whether we echo or return (note echoing uses "pretty" formats, |
|
512 | - * otherwise we use the standard formats) |
|
513 | - * @return string|bool string on success, FALSE on fail |
|
514 | - * @throws ReflectionException |
|
515 | - * @throws InvalidArgumentException |
|
516 | - * @throws InvalidInterfaceException |
|
517 | - * @throws InvalidDataTypeException |
|
518 | - * @throws EE_Error |
|
519 | - */ |
|
520 | - private function _show_datetime( |
|
521 | - $date_or_time = null, |
|
522 | - $start_or_end = 'start', |
|
523 | - $dt_frmt = '', |
|
524 | - $tm_frmt = '', |
|
525 | - $echo = false |
|
526 | - ) { |
|
527 | - $field_name = "DTT_EVT_{$start_or_end}"; |
|
528 | - $dtt = $this->_get_datetime( |
|
529 | - $field_name, |
|
530 | - $dt_frmt, |
|
531 | - $tm_frmt, |
|
532 | - $date_or_time, |
|
533 | - $echo |
|
534 | - ); |
|
535 | - if (! $echo) { |
|
536 | - return $dtt; |
|
537 | - } |
|
538 | - return ''; |
|
539 | - } |
|
540 | - |
|
541 | - |
|
542 | - /** |
|
543 | - * get event start date. Provide either the date format, or NULL to re-use the |
|
544 | - * last-used format, or '' to use the default date format |
|
545 | - * |
|
546 | - * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
547 | - * @return mixed string on success, FALSE on fail |
|
548 | - * @throws ReflectionException |
|
549 | - * @throws InvalidArgumentException |
|
550 | - * @throws InvalidInterfaceException |
|
551 | - * @throws InvalidDataTypeException |
|
552 | - * @throws EE_Error |
|
553 | - */ |
|
554 | - public function start_date($dt_frmt = '') |
|
555 | - { |
|
556 | - return $this->_show_datetime('D', 'start', $dt_frmt); |
|
557 | - } |
|
558 | - |
|
559 | - |
|
560 | - /** |
|
561 | - * Echoes start_date() |
|
562 | - * |
|
563 | - * @param string $dt_frmt |
|
564 | - * @throws ReflectionException |
|
565 | - * @throws InvalidArgumentException |
|
566 | - * @throws InvalidInterfaceException |
|
567 | - * @throws InvalidDataTypeException |
|
568 | - * @throws EE_Error |
|
569 | - */ |
|
570 | - public function e_start_date($dt_frmt = '') |
|
571 | - { |
|
572 | - $this->_show_datetime('D', 'start', $dt_frmt, null, true); |
|
573 | - } |
|
574 | - |
|
575 | - |
|
576 | - /** |
|
577 | - * get end date. Provide either the date format, or NULL to re-use the |
|
578 | - * last-used format, or '' to use the default date format |
|
579 | - * |
|
580 | - * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
581 | - * @return mixed string on success, FALSE on fail |
|
582 | - * @throws ReflectionException |
|
583 | - * @throws InvalidArgumentException |
|
584 | - * @throws InvalidInterfaceException |
|
585 | - * @throws InvalidDataTypeException |
|
586 | - * @throws EE_Error |
|
587 | - */ |
|
588 | - public function end_date($dt_frmt = '') |
|
589 | - { |
|
590 | - return $this->_show_datetime('D', 'end', $dt_frmt); |
|
591 | - } |
|
592 | - |
|
593 | - |
|
594 | - /** |
|
595 | - * Echoes the end date. See end_date() |
|
596 | - * |
|
597 | - * @param string $dt_frmt |
|
598 | - * @throws ReflectionException |
|
599 | - * @throws InvalidArgumentException |
|
600 | - * @throws InvalidInterfaceException |
|
601 | - * @throws InvalidDataTypeException |
|
602 | - * @throws EE_Error |
|
603 | - */ |
|
604 | - public function e_end_date($dt_frmt = '') |
|
605 | - { |
|
606 | - $this->_show_datetime('D', 'end', $dt_frmt, null, true); |
|
607 | - } |
|
608 | - |
|
609 | - |
|
610 | - /** |
|
611 | - * get date_range - meaning the start AND end date |
|
612 | - * |
|
613 | - * @access public |
|
614 | - * @param string $dt_frmt string representation of date format defaults to WP settings |
|
615 | - * @param string $conjunction conjunction junction what's your function ? |
|
616 | - * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
617 | - * @return mixed string on success, FALSE on fail |
|
618 | - * @throws ReflectionException |
|
619 | - * @throws InvalidArgumentException |
|
620 | - * @throws InvalidInterfaceException |
|
621 | - * @throws InvalidDataTypeException |
|
622 | - * @throws EE_Error |
|
623 | - */ |
|
624 | - public function date_range($dt_frmt = '', $conjunction = ' - ') |
|
625 | - { |
|
626 | - $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt; |
|
627 | - $start = str_replace( |
|
628 | - ' ', |
|
629 | - ' ', |
|
630 | - $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt) |
|
631 | - ); |
|
632 | - $end = str_replace( |
|
633 | - ' ', |
|
634 | - ' ', |
|
635 | - $this->get_i18n_datetime('DTT_EVT_end', $dt_frmt) |
|
636 | - ); |
|
637 | - return $start !== $end ? $start . $conjunction . $end : $start; |
|
638 | - } |
|
639 | - |
|
640 | - |
|
641 | - /** |
|
642 | - * @param string $dt_frmt |
|
643 | - * @param string $conjunction |
|
644 | - * @throws ReflectionException |
|
645 | - * @throws InvalidArgumentException |
|
646 | - * @throws InvalidInterfaceException |
|
647 | - * @throws InvalidDataTypeException |
|
648 | - * @throws EE_Error |
|
649 | - */ |
|
650 | - public function e_date_range($dt_frmt = '', $conjunction = ' - ') |
|
651 | - { |
|
652 | - echo esc_html($this->date_range($dt_frmt, $conjunction)); |
|
653 | - } |
|
654 | - |
|
655 | - |
|
656 | - /** |
|
657 | - * get start time |
|
658 | - * |
|
659 | - * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
660 | - * @return mixed string on success, FALSE on fail |
|
661 | - * @throws ReflectionException |
|
662 | - * @throws InvalidArgumentException |
|
663 | - * @throws InvalidInterfaceException |
|
664 | - * @throws InvalidDataTypeException |
|
665 | - * @throws EE_Error |
|
666 | - */ |
|
667 | - public function start_time($tm_format = '') |
|
668 | - { |
|
669 | - return $this->_show_datetime('T', 'start', null, $tm_format); |
|
670 | - } |
|
671 | - |
|
672 | - |
|
673 | - /** |
|
674 | - * @param string $tm_format |
|
675 | - * @throws ReflectionException |
|
676 | - * @throws InvalidArgumentException |
|
677 | - * @throws InvalidInterfaceException |
|
678 | - * @throws InvalidDataTypeException |
|
679 | - * @throws EE_Error |
|
680 | - */ |
|
681 | - public function e_start_time($tm_format = '') |
|
682 | - { |
|
683 | - $this->_show_datetime('T', 'start', null, $tm_format, true); |
|
684 | - } |
|
685 | - |
|
686 | - |
|
687 | - /** |
|
688 | - * get end time |
|
689 | - * |
|
690 | - * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
691 | - * @return mixed string on success, FALSE on fail |
|
692 | - * @throws ReflectionException |
|
693 | - * @throws InvalidArgumentException |
|
694 | - * @throws InvalidInterfaceException |
|
695 | - * @throws InvalidDataTypeException |
|
696 | - * @throws EE_Error |
|
697 | - */ |
|
698 | - public function end_time($tm_format = '') |
|
699 | - { |
|
700 | - return $this->_show_datetime('T', 'end', null, $tm_format); |
|
701 | - } |
|
702 | - |
|
703 | - |
|
704 | - /** |
|
705 | - * @param string $tm_format |
|
706 | - * @throws ReflectionException |
|
707 | - * @throws InvalidArgumentException |
|
708 | - * @throws InvalidInterfaceException |
|
709 | - * @throws InvalidDataTypeException |
|
710 | - * @throws EE_Error |
|
711 | - */ |
|
712 | - public function e_end_time($tm_format = '') |
|
713 | - { |
|
714 | - $this->_show_datetime('T', 'end', null, $tm_format, true); |
|
715 | - } |
|
716 | - |
|
717 | - |
|
718 | - /** |
|
719 | - * get time_range |
|
720 | - * |
|
721 | - * @access public |
|
722 | - * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
723 | - * @param string $conjunction conjunction junction what's your function ? |
|
724 | - * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
725 | - * @return mixed string on success, FALSE on fail |
|
726 | - * @throws ReflectionException |
|
727 | - * @throws InvalidArgumentException |
|
728 | - * @throws InvalidInterfaceException |
|
729 | - * @throws InvalidDataTypeException |
|
730 | - * @throws EE_Error |
|
731 | - */ |
|
732 | - public function time_range($tm_format = '', $conjunction = ' - ') |
|
733 | - { |
|
734 | - $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
735 | - $start = str_replace( |
|
736 | - ' ', |
|
737 | - ' ', |
|
738 | - $this->get_i18n_datetime('DTT_EVT_start', $tm_format) |
|
739 | - ); |
|
740 | - $end = str_replace( |
|
741 | - ' ', |
|
742 | - ' ', |
|
743 | - $this->get_i18n_datetime('DTT_EVT_end', $tm_format) |
|
744 | - ); |
|
745 | - return $start !== $end ? $start . $conjunction . $end : $start; |
|
746 | - } |
|
747 | - |
|
748 | - |
|
749 | - /** |
|
750 | - * @param string $tm_format |
|
751 | - * @param string $conjunction |
|
752 | - * @throws ReflectionException |
|
753 | - * @throws InvalidArgumentException |
|
754 | - * @throws InvalidInterfaceException |
|
755 | - * @throws InvalidDataTypeException |
|
756 | - * @throws EE_Error |
|
757 | - */ |
|
758 | - public function e_time_range($tm_format = '', $conjunction = ' - ') |
|
759 | - { |
|
760 | - echo esc_html($this->time_range($tm_format, $conjunction)); |
|
761 | - } |
|
762 | - |
|
763 | - |
|
764 | - /** |
|
765 | - * This returns a range representation of the date and times. |
|
766 | - * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end. |
|
767 | - * Also, the return value is localized. |
|
768 | - * |
|
769 | - * @param string $dt_format |
|
770 | - * @param string $tm_format |
|
771 | - * @param string $conjunction used between two different dates or times. |
|
772 | - * ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm |
|
773 | - * @param string $separator used between the date and time formats. |
|
774 | - * ex: Dec 1, 2016{$separator}2pm |
|
775 | - * @return string |
|
776 | - * @throws ReflectionException |
|
777 | - * @throws InvalidArgumentException |
|
778 | - * @throws InvalidInterfaceException |
|
779 | - * @throws InvalidDataTypeException |
|
780 | - * @throws EE_Error |
|
781 | - */ |
|
782 | - public function date_and_time_range( |
|
783 | - $dt_format = '', |
|
784 | - $tm_format = '', |
|
785 | - $conjunction = ' - ', |
|
786 | - $separator = ' ' |
|
787 | - ) { |
|
788 | - $dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt; |
|
789 | - $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
790 | - $full_format = $dt_format . $separator . $tm_format; |
|
791 | - // the range output depends on various conditions |
|
792 | - switch (true) { |
|
793 | - // start date timestamp and end date timestamp are the same. |
|
794 | - case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')): |
|
795 | - $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format); |
|
796 | - break; |
|
797 | - // start and end date are the same but times are different |
|
798 | - case ($this->start_date() === $this->end_date()): |
|
799 | - $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
800 | - . $conjunction |
|
801 | - . $this->get_i18n_datetime('DTT_EVT_end', $tm_format); |
|
802 | - break; |
|
803 | - // all other conditions |
|
804 | - default: |
|
805 | - $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
806 | - . $conjunction |
|
807 | - . $this->get_i18n_datetime('DTT_EVT_end', $full_format); |
|
808 | - break; |
|
809 | - } |
|
810 | - return $output; |
|
811 | - } |
|
812 | - |
|
813 | - |
|
814 | - /** |
|
815 | - * This echos the results of date and time range. |
|
816 | - * |
|
817 | - * @see date_and_time_range() for more details on purpose. |
|
818 | - * @param string $dt_format |
|
819 | - * @param string $tm_format |
|
820 | - * @param string $conjunction |
|
821 | - * @return void |
|
822 | - * @throws ReflectionException |
|
823 | - * @throws InvalidArgumentException |
|
824 | - * @throws InvalidInterfaceException |
|
825 | - * @throws InvalidDataTypeException |
|
826 | - * @throws EE_Error |
|
827 | - */ |
|
828 | - public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ') |
|
829 | - { |
|
830 | - echo esc_html($this->date_and_time_range($dt_format, $tm_format, $conjunction)); |
|
831 | - } |
|
832 | - |
|
833 | - |
|
834 | - /** |
|
835 | - * get start date and start time |
|
836 | - * |
|
837 | - * @param string $dt_format - string representation of date format defaults to 'F j, Y' |
|
838 | - * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
839 | - * @return mixed string on success, FALSE on fail |
|
840 | - * @throws ReflectionException |
|
841 | - * @throws InvalidArgumentException |
|
842 | - * @throws InvalidInterfaceException |
|
843 | - * @throws InvalidDataTypeException |
|
844 | - * @throws EE_Error |
|
845 | - */ |
|
846 | - public function start_date_and_time($dt_format = '', $tm_format = '') |
|
847 | - { |
|
848 | - return $this->_show_datetime('', 'start', $dt_format, $tm_format); |
|
849 | - } |
|
850 | - |
|
851 | - |
|
852 | - /** |
|
853 | - * @param string $dt_frmt |
|
854 | - * @param string $tm_format |
|
855 | - * @throws ReflectionException |
|
856 | - * @throws InvalidArgumentException |
|
857 | - * @throws InvalidInterfaceException |
|
858 | - * @throws InvalidDataTypeException |
|
859 | - * @throws EE_Error |
|
860 | - */ |
|
861 | - public function e_start_date_and_time($dt_frmt = '', $tm_format = '') |
|
862 | - { |
|
863 | - $this->_show_datetime('', 'start', $dt_frmt, $tm_format, true); |
|
864 | - } |
|
865 | - |
|
866 | - |
|
867 | - /** |
|
868 | - * Shows the length of the event (start to end time). |
|
869 | - * Can be shown in 'seconds','minutes','hours', or 'days'. |
|
870 | - * By default, rounds up. (So if you use 'days', and then event |
|
871 | - * only occurs for 1 hour, it will return 1 day). |
|
872 | - * |
|
873 | - * @param string $units 'seconds','minutes','hours','days' |
|
874 | - * @param bool $round_up |
|
875 | - * @return float|int|mixed |
|
876 | - * @throws ReflectionException |
|
877 | - * @throws InvalidArgumentException |
|
878 | - * @throws InvalidInterfaceException |
|
879 | - * @throws InvalidDataTypeException |
|
880 | - * @throws EE_Error |
|
881 | - */ |
|
882 | - public function length($units = 'seconds', $round_up = false) |
|
883 | - { |
|
884 | - $start = $this->get_raw('DTT_EVT_start'); |
|
885 | - $end = $this->get_raw('DTT_EVT_end'); |
|
886 | - $length_in_units = $end - $start; |
|
887 | - switch ($units) { |
|
888 | - // NOTE: We purposefully don't use "break;" in order to chain the divisions |
|
889 | - /** @noinspection PhpMissingBreakStatementInspection */ |
|
890 | - // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment |
|
891 | - case 'days': |
|
892 | - $length_in_units /= 24; |
|
893 | - /** @noinspection PhpMissingBreakStatementInspection */ |
|
894 | - case 'hours': |
|
895 | - // fall through is intentional |
|
896 | - $length_in_units /= 60; |
|
897 | - /** @noinspection PhpMissingBreakStatementInspection */ |
|
898 | - case 'minutes': |
|
899 | - // fall through is intentional |
|
900 | - $length_in_units /= 60; |
|
901 | - case 'seconds': |
|
902 | - default: |
|
903 | - $length_in_units = ceil($length_in_units); |
|
904 | - } |
|
905 | - // phpcs:enable |
|
906 | - if ($round_up) { |
|
907 | - $length_in_units = max($length_in_units, 1); |
|
908 | - } |
|
909 | - return $length_in_units; |
|
910 | - } |
|
911 | - |
|
912 | - |
|
913 | - /** |
|
914 | - * get end date and time |
|
915 | - * |
|
916 | - * @param string $dt_frmt - string representation of date format defaults to 'F j, Y' |
|
917 | - * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
918 | - * @return mixed string on success, FALSE on fail |
|
919 | - * @throws ReflectionException |
|
920 | - * @throws InvalidArgumentException |
|
921 | - * @throws InvalidInterfaceException |
|
922 | - * @throws InvalidDataTypeException |
|
923 | - * @throws EE_Error |
|
924 | - */ |
|
925 | - public function end_date_and_time($dt_frmt = '', $tm_format = '') |
|
926 | - { |
|
927 | - return $this->_show_datetime('', 'end', $dt_frmt, $tm_format); |
|
928 | - } |
|
929 | - |
|
930 | - |
|
931 | - /** |
|
932 | - * @param string $dt_frmt |
|
933 | - * @param string $tm_format |
|
934 | - * @throws ReflectionException |
|
935 | - * @throws InvalidArgumentException |
|
936 | - * @throws InvalidInterfaceException |
|
937 | - * @throws InvalidDataTypeException |
|
938 | - * @throws EE_Error |
|
939 | - */ |
|
940 | - public function e_end_date_and_time($dt_frmt = '', $tm_format = '') |
|
941 | - { |
|
942 | - $this->_show_datetime('', 'end', $dt_frmt, $tm_format, true); |
|
943 | - } |
|
944 | - |
|
945 | - |
|
946 | - /** |
|
947 | - * get start timestamp |
|
948 | - * |
|
949 | - * @return int |
|
950 | - * @throws ReflectionException |
|
951 | - * @throws InvalidArgumentException |
|
952 | - * @throws InvalidInterfaceException |
|
953 | - * @throws InvalidDataTypeException |
|
954 | - * @throws EE_Error |
|
955 | - */ |
|
956 | - public function start() |
|
957 | - { |
|
958 | - return $this->get_raw('DTT_EVT_start'); |
|
959 | - } |
|
960 | - |
|
961 | - |
|
962 | - /** |
|
963 | - * get end timestamp |
|
964 | - * |
|
965 | - * @return int |
|
966 | - * @throws ReflectionException |
|
967 | - * @throws InvalidArgumentException |
|
968 | - * @throws InvalidInterfaceException |
|
969 | - * @throws InvalidDataTypeException |
|
970 | - * @throws EE_Error |
|
971 | - */ |
|
972 | - public function end() |
|
973 | - { |
|
974 | - return $this->get_raw('DTT_EVT_end'); |
|
975 | - } |
|
976 | - |
|
977 | - |
|
978 | - /** |
|
979 | - * get the registration limit for this datetime slot |
|
980 | - * |
|
981 | - * @return int|float int = finite limit EE_INF(float) = unlimited |
|
982 | - * @throws ReflectionException |
|
983 | - * @throws InvalidArgumentException |
|
984 | - * @throws InvalidInterfaceException |
|
985 | - * @throws InvalidDataTypeException |
|
986 | - * @throws EE_Error |
|
987 | - */ |
|
988 | - public function reg_limit() |
|
989 | - { |
|
990 | - return $this->get_raw('DTT_reg_limit'); |
|
991 | - } |
|
992 | - |
|
993 | - |
|
994 | - /** |
|
995 | - * have the tickets sold for this datetime, met or exceed the registration limit ? |
|
996 | - * |
|
997 | - * @return boolean |
|
998 | - * @throws ReflectionException |
|
999 | - * @throws InvalidArgumentException |
|
1000 | - * @throws InvalidInterfaceException |
|
1001 | - * @throws InvalidDataTypeException |
|
1002 | - * @throws EE_Error |
|
1003 | - */ |
|
1004 | - public function sold_out() |
|
1005 | - { |
|
1006 | - return $this->reg_limit() > 0 && $this->sold() >= $this->reg_limit(); |
|
1007 | - } |
|
1008 | - |
|
1009 | - |
|
1010 | - /** |
|
1011 | - * return the total number of spaces remaining at this venue. |
|
1012 | - * This only takes the venue's capacity into account, NOT the tickets available for sale |
|
1013 | - * |
|
1014 | - * @param bool $consider_tickets Whether to consider tickets remaining when determining if there are any spaces left |
|
1015 | - * Because if all tickets attached to this datetime have no spaces left, |
|
1016 | - * then this datetime IS effectively sold out. |
|
1017 | - * However, there are cases where we just want to know the spaces |
|
1018 | - * remaining for this particular datetime, hence the flag. |
|
1019 | - * @return int|float |
|
1020 | - * @throws ReflectionException |
|
1021 | - * @throws InvalidArgumentException |
|
1022 | - * @throws InvalidInterfaceException |
|
1023 | - * @throws InvalidDataTypeException |
|
1024 | - * @throws EE_Error |
|
1025 | - */ |
|
1026 | - public function spaces_remaining($consider_tickets = false) |
|
1027 | - { |
|
1028 | - // tickets remaining available for purchase |
|
1029 | - // no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF |
|
1030 | - $dtt_remaining = $this->reg_limit() - $this->sold_and_reserved(); |
|
1031 | - if (! $consider_tickets) { |
|
1032 | - return $dtt_remaining; |
|
1033 | - } |
|
1034 | - $tickets_remaining = $this->tickets_remaining(); |
|
1035 | - return min($dtt_remaining, $tickets_remaining); |
|
1036 | - } |
|
1037 | - |
|
1038 | - |
|
1039 | - /** |
|
1040 | - * Counts the total tickets available |
|
1041 | - * (from all the different types of tickets which are available for this datetime). |
|
1042 | - * |
|
1043 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1044 | - * @return int |
|
1045 | - * @throws ReflectionException |
|
1046 | - * @throws InvalidArgumentException |
|
1047 | - * @throws InvalidInterfaceException |
|
1048 | - * @throws InvalidDataTypeException |
|
1049 | - * @throws EE_Error |
|
1050 | - */ |
|
1051 | - public function tickets_remaining($query_params = array()) |
|
1052 | - { |
|
1053 | - $sum = 0; |
|
1054 | - $tickets = $this->tickets($query_params); |
|
1055 | - if (! empty($tickets)) { |
|
1056 | - foreach ($tickets as $ticket) { |
|
1057 | - if ($ticket instanceof EE_Ticket) { |
|
1058 | - // get the actual amount of tickets that can be sold |
|
1059 | - $qty = $ticket->qty('saleable'); |
|
1060 | - if ($qty === EE_INF) { |
|
1061 | - return EE_INF; |
|
1062 | - } |
|
1063 | - // no negative ticket quantities plz |
|
1064 | - if ($qty > 0) { |
|
1065 | - $sum += $qty; |
|
1066 | - } |
|
1067 | - } |
|
1068 | - } |
|
1069 | - } |
|
1070 | - return $sum; |
|
1071 | - } |
|
1072 | - |
|
1073 | - |
|
1074 | - /** |
|
1075 | - * Gets the count of all the tickets available at this datetime (not ticket types) |
|
1076 | - * before any were sold |
|
1077 | - * |
|
1078 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1079 | - * @return int |
|
1080 | - * @throws ReflectionException |
|
1081 | - * @throws InvalidArgumentException |
|
1082 | - * @throws InvalidInterfaceException |
|
1083 | - * @throws InvalidDataTypeException |
|
1084 | - * @throws EE_Error |
|
1085 | - */ |
|
1086 | - public function sum_tickets_initially_available($query_params = array()) |
|
1087 | - { |
|
1088 | - return $this->sum_related('Ticket', $query_params, 'TKT_qty'); |
|
1089 | - } |
|
1090 | - |
|
1091 | - |
|
1092 | - /** |
|
1093 | - * Returns the lesser-of-the two: spaces remaining at this datetime, or |
|
1094 | - * the total tickets remaining (a sum of the tickets remaining for each ticket type |
|
1095 | - * that is available for this datetime). |
|
1096 | - * |
|
1097 | - * @return int |
|
1098 | - * @throws ReflectionException |
|
1099 | - * @throws InvalidArgumentException |
|
1100 | - * @throws InvalidInterfaceException |
|
1101 | - * @throws InvalidDataTypeException |
|
1102 | - * @throws EE_Error |
|
1103 | - */ |
|
1104 | - public function total_tickets_available_at_this_datetime() |
|
1105 | - { |
|
1106 | - return $this->spaces_remaining(true); |
|
1107 | - } |
|
1108 | - |
|
1109 | - |
|
1110 | - /** |
|
1111 | - * This simply compares the internal dtt for the given string with NOW |
|
1112 | - * and determines if the date is upcoming or not. |
|
1113 | - * |
|
1114 | - * @access public |
|
1115 | - * @return boolean |
|
1116 | - * @throws ReflectionException |
|
1117 | - * @throws InvalidArgumentException |
|
1118 | - * @throws InvalidInterfaceException |
|
1119 | - * @throws InvalidDataTypeException |
|
1120 | - * @throws EE_Error |
|
1121 | - */ |
|
1122 | - public function is_upcoming() |
|
1123 | - { |
|
1124 | - return ($this->get_raw('DTT_EVT_start') > time()); |
|
1125 | - } |
|
1126 | - |
|
1127 | - |
|
1128 | - /** |
|
1129 | - * This simply compares the internal datetime for the given string with NOW |
|
1130 | - * and returns if the date is active (i.e. start and end time) |
|
1131 | - * |
|
1132 | - * @return boolean |
|
1133 | - * @throws ReflectionException |
|
1134 | - * @throws InvalidArgumentException |
|
1135 | - * @throws InvalidInterfaceException |
|
1136 | - * @throws InvalidDataTypeException |
|
1137 | - * @throws EE_Error |
|
1138 | - */ |
|
1139 | - public function is_active() |
|
1140 | - { |
|
1141 | - return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time()); |
|
1142 | - } |
|
1143 | - |
|
1144 | - |
|
1145 | - /** |
|
1146 | - * This simply compares the internal dtt for the given string with NOW |
|
1147 | - * and determines if the date is expired or not. |
|
1148 | - * |
|
1149 | - * @return boolean |
|
1150 | - * @throws ReflectionException |
|
1151 | - * @throws InvalidArgumentException |
|
1152 | - * @throws InvalidInterfaceException |
|
1153 | - * @throws InvalidDataTypeException |
|
1154 | - * @throws EE_Error |
|
1155 | - */ |
|
1156 | - public function is_expired() |
|
1157 | - { |
|
1158 | - return ($this->get_raw('DTT_EVT_end') < time()); |
|
1159 | - } |
|
1160 | - |
|
1161 | - |
|
1162 | - /** |
|
1163 | - * This returns the active status for whether an event is active, upcoming, or expired |
|
1164 | - * |
|
1165 | - * @return int return value will be one of the EE_Datetime status constants. |
|
1166 | - * @throws ReflectionException |
|
1167 | - * @throws InvalidArgumentException |
|
1168 | - * @throws InvalidInterfaceException |
|
1169 | - * @throws InvalidDataTypeException |
|
1170 | - * @throws EE_Error |
|
1171 | - */ |
|
1172 | - public function get_active_status() |
|
1173 | - { |
|
1174 | - $total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime(); |
|
1175 | - if ($total_tickets_for_this_dtt !== false && $total_tickets_for_this_dtt < 1) { |
|
1176 | - return EE_Datetime::sold_out; |
|
1177 | - } |
|
1178 | - if ($this->is_expired()) { |
|
1179 | - return EE_Datetime::expired; |
|
1180 | - } |
|
1181 | - if ($this->is_upcoming()) { |
|
1182 | - return EE_Datetime::upcoming; |
|
1183 | - } |
|
1184 | - if ($this->is_active()) { |
|
1185 | - return EE_Datetime::active; |
|
1186 | - } |
|
1187 | - return null; |
|
1188 | - } |
|
1189 | - |
|
1190 | - |
|
1191 | - /** |
|
1192 | - * This returns a nice display name for the datetime that is contingent on the span between the dates and times. |
|
1193 | - * |
|
1194 | - * @param boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty. |
|
1195 | - * @return string |
|
1196 | - * @throws ReflectionException |
|
1197 | - * @throws InvalidArgumentException |
|
1198 | - * @throws InvalidInterfaceException |
|
1199 | - * @throws InvalidDataTypeException |
|
1200 | - * @throws EE_Error |
|
1201 | - */ |
|
1202 | - public function get_dtt_display_name($use_dtt_name = false) |
|
1203 | - { |
|
1204 | - if ($use_dtt_name) { |
|
1205 | - $dtt_name = $this->name(); |
|
1206 | - if (! empty($dtt_name)) { |
|
1207 | - return $dtt_name; |
|
1208 | - } |
|
1209 | - } |
|
1210 | - // first condition is to see if the months are different |
|
1211 | - if ( |
|
1212 | - date('m', $this->get_raw('DTT_EVT_start')) !== date('m', $this->get_raw('DTT_EVT_end')) |
|
1213 | - ) { |
|
1214 | - $display_date = $this->start_date('M j\, Y g:i a') . ' - ' . $this->end_date('M j\, Y g:i a'); |
|
1215 | - // next condition is if its the same month but different day |
|
1216 | - } else { |
|
1217 | - if ( |
|
1218 | - date('m', $this->get_raw('DTT_EVT_start')) === date('m', $this->get_raw('DTT_EVT_end')) |
|
1219 | - && date('d', $this->get_raw('DTT_EVT_start')) !== date('d', $this->get_raw('DTT_EVT_end')) |
|
1220 | - ) { |
|
1221 | - $display_date = $this->start_date('M j\, g:i a') . ' - ' . $this->end_date('M j\, g:i a Y'); |
|
1222 | - } else { |
|
1223 | - $display_date = $this->start_date('F j\, Y') |
|
1224 | - . ' @ ' |
|
1225 | - . $this->start_date('g:i a') |
|
1226 | - . ' - ' |
|
1227 | - . $this->end_date('g:i a'); |
|
1228 | - } |
|
1229 | - } |
|
1230 | - return $display_date; |
|
1231 | - } |
|
1232 | - |
|
1233 | - |
|
1234 | - /** |
|
1235 | - * Gets all the tickets for this datetime |
|
1236 | - * |
|
1237 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1238 | - * @return EE_Base_Class[]|EE_Ticket[] |
|
1239 | - * @throws ReflectionException |
|
1240 | - * @throws InvalidArgumentException |
|
1241 | - * @throws InvalidInterfaceException |
|
1242 | - * @throws InvalidDataTypeException |
|
1243 | - * @throws EE_Error |
|
1244 | - */ |
|
1245 | - public function tickets($query_params = array()) |
|
1246 | - { |
|
1247 | - return $this->get_many_related('Ticket', $query_params); |
|
1248 | - } |
|
1249 | - |
|
1250 | - |
|
1251 | - /** |
|
1252 | - * Gets all the ticket types currently available for purchase |
|
1253 | - * |
|
1254 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1255 | - * @return EE_Ticket[] |
|
1256 | - * @throws ReflectionException |
|
1257 | - * @throws InvalidArgumentException |
|
1258 | - * @throws InvalidInterfaceException |
|
1259 | - * @throws InvalidDataTypeException |
|
1260 | - * @throws EE_Error |
|
1261 | - */ |
|
1262 | - public function ticket_types_available_for_purchase($query_params = array()) |
|
1263 | - { |
|
1264 | - // first check if datetime is valid |
|
1265 | - if ($this->sold_out() || ! ($this->is_upcoming() || $this->is_active())) { |
|
1266 | - return array(); |
|
1267 | - } |
|
1268 | - if (empty($query_params)) { |
|
1269 | - $query_params = array( |
|
1270 | - array( |
|
1271 | - 'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')), |
|
1272 | - 'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')), |
|
1273 | - 'TKT_deleted' => false, |
|
1274 | - ), |
|
1275 | - ); |
|
1276 | - } |
|
1277 | - return $this->tickets($query_params); |
|
1278 | - } |
|
1279 | - |
|
1280 | - |
|
1281 | - /** |
|
1282 | - * @return EE_Base_Class|EE_Event |
|
1283 | - * @throws ReflectionException |
|
1284 | - * @throws InvalidArgumentException |
|
1285 | - * @throws InvalidInterfaceException |
|
1286 | - * @throws InvalidDataTypeException |
|
1287 | - * @throws EE_Error |
|
1288 | - */ |
|
1289 | - public function event() |
|
1290 | - { |
|
1291 | - return $this->get_first_related('Event'); |
|
1292 | - } |
|
1293 | - |
|
1294 | - |
|
1295 | - /** |
|
1296 | - * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime |
|
1297 | - * (via the tickets). |
|
1298 | - * |
|
1299 | - * @return int |
|
1300 | - * @throws ReflectionException |
|
1301 | - * @throws InvalidArgumentException |
|
1302 | - * @throws InvalidInterfaceException |
|
1303 | - * @throws InvalidDataTypeException |
|
1304 | - * @throws EE_Error |
|
1305 | - */ |
|
1306 | - public function update_sold() |
|
1307 | - { |
|
1308 | - $count_regs_for_this_datetime = EEM_Registration::instance()->count( |
|
1309 | - array( |
|
1310 | - array( |
|
1311 | - 'STS_ID' => EEM_Registration::status_id_approved, |
|
1312 | - 'REG_deleted' => 0, |
|
1313 | - 'Ticket.Datetime.DTT_ID' => $this->ID(), |
|
1314 | - ), |
|
1315 | - ) |
|
1316 | - ); |
|
1317 | - $this->set_sold($count_regs_for_this_datetime); |
|
1318 | - $this->save(); |
|
1319 | - return $count_regs_for_this_datetime; |
|
1320 | - } |
|
1321 | - |
|
1322 | - |
|
1323 | - /** |
|
1324 | - * Adds a venue to this event |
|
1325 | - * |
|
1326 | - * @param int|EE_Venue /int $venue_id_or_obj |
|
1327 | - * @return EE_Base_Class|EE_Venue |
|
1328 | - * @throws EE_Error |
|
1329 | - * @throws ReflectionException |
|
1330 | - */ |
|
1331 | - public function add_venue($venue_id_or_obj): EE_Venue |
|
1332 | - { |
|
1333 | - return $this->_add_relation_to($venue_id_or_obj, 'Venue'); |
|
1334 | - } |
|
1335 | - |
|
1336 | - |
|
1337 | - /** |
|
1338 | - * Removes a venue from the event |
|
1339 | - * |
|
1340 | - * @param EE_Venue /int $venue_id_or_obj |
|
1341 | - * @return EE_Base_Class|EE_Venue |
|
1342 | - * @throws EE_Error |
|
1343 | - * @throws ReflectionException |
|
1344 | - */ |
|
1345 | - public function remove_venue($venue_id_or_obj): EE_Venue |
|
1346 | - { |
|
1347 | - $venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue(); |
|
1348 | - return $this->_remove_relation_to($venue_id_or_obj, 'Venue'); |
|
1349 | - } |
|
1350 | - |
|
1351 | - |
|
1352 | - /** |
|
1353 | - * Gets the venue related to the event. May provide additional $query_params if desired |
|
1354 | - * |
|
1355 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1356 | - * @return int |
|
1357 | - * @throws EE_Error |
|
1358 | - * @throws ReflectionException |
|
1359 | - */ |
|
1360 | - public function venue_ID(array $query_params = []): int |
|
1361 | - { |
|
1362 | - $venue = $this->get_first_related('Venue', $query_params); |
|
1363 | - return $venue instanceof EE_Venue |
|
1364 | - ? $venue->ID() |
|
1365 | - : 0; |
|
1366 | - } |
|
1367 | - |
|
1368 | - |
|
1369 | - /** |
|
1370 | - * Gets the venue related to the event. May provide additional $query_params if desired |
|
1371 | - * |
|
1372 | - * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1373 | - * @return EE_Base_Class|EE_Venue |
|
1374 | - * @throws EE_Error |
|
1375 | - * @throws ReflectionException |
|
1376 | - */ |
|
1377 | - public function venue(array $query_params = []) |
|
1378 | - { |
|
1379 | - return $this->get_first_related('Venue', $query_params); |
|
1380 | - } |
|
1381 | - |
|
1382 | - |
|
1383 | - /** |
|
1384 | - * @param EE_Base_Class|int|string $otherObjectModelObjectOrID |
|
1385 | - * @param string $relationName |
|
1386 | - * @param array $extra_join_model_fields_n_values |
|
1387 | - * @param string|null $cache_id |
|
1388 | - * @return EE_Base_Class |
|
1389 | - * @throws EE_Error |
|
1390 | - * @throws ReflectionException |
|
1391 | - * @since $VID:$ |
|
1392 | - */ |
|
1393 | - public function _add_relation_to( |
|
1394 | - $otherObjectModelObjectOrID, |
|
1395 | - $relationName, |
|
1396 | - $extra_join_model_fields_n_values = [], |
|
1397 | - $cache_id = null |
|
1398 | - ) { |
|
1399 | - // if we're adding a new relation to a ticket |
|
1400 | - if ($relationName === 'Ticket' && ! $this->hasRelation($otherObjectModelObjectOrID, $relationName)) { |
|
1401 | - /** @var EE_Ticket $ticket */ |
|
1402 | - $ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID); |
|
1403 | - $this->increaseSold($ticket->sold(), false); |
|
1404 | - $this->increaseReserved($ticket->reserved()); |
|
1405 | - $this->save(); |
|
1406 | - $otherObjectModelObjectOrID = $ticket; |
|
1407 | - } |
|
1408 | - return parent::_add_relation_to( |
|
1409 | - $otherObjectModelObjectOrID, |
|
1410 | - $relationName, |
|
1411 | - $extra_join_model_fields_n_values, |
|
1412 | - $cache_id |
|
1413 | - ); |
|
1414 | - } |
|
1415 | - |
|
1416 | - |
|
1417 | - /** |
|
1418 | - * @param EE_Base_Class|int|string $otherObjectModelObjectOrID |
|
1419 | - * @param string $relationName |
|
1420 | - * @param array $where_query |
|
1421 | - * @return bool|EE_Base_Class|null |
|
1422 | - * @throws EE_Error |
|
1423 | - * @throws ReflectionException |
|
1424 | - * @since $VID:$ |
|
1425 | - */ |
|
1426 | - public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = []) |
|
1427 | - { |
|
1428 | - if ($relationName === 'Ticket' && $this->hasRelation($otherObjectModelObjectOrID, $relationName)) { |
|
1429 | - /** @var EE_Ticket $ticket */ |
|
1430 | - $ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID); |
|
1431 | - $this->decreaseSold($ticket->sold()); |
|
1432 | - $this->decreaseReserved($ticket->reserved()); |
|
1433 | - $this->save(); |
|
1434 | - $otherObjectModelObjectOrID = $ticket; |
|
1435 | - } |
|
1436 | - return parent::_remove_relation_to( |
|
1437 | - $otherObjectModelObjectOrID, |
|
1438 | - $relationName, |
|
1439 | - $where_query |
|
1440 | - ); |
|
1441 | - } |
|
1442 | - |
|
1443 | - |
|
1444 | - /** |
|
1445 | - * Removes ALL the related things for the $relationName. |
|
1446 | - * |
|
1447 | - * @param string $relationName |
|
1448 | - * @param array $where_query_params |
|
1449 | - * @return EE_Base_Class |
|
1450 | - * @throws ReflectionException |
|
1451 | - * @throws InvalidArgumentException |
|
1452 | - * @throws InvalidInterfaceException |
|
1453 | - * @throws InvalidDataTypeException |
|
1454 | - * @throws EE_Error |
|
1455 | - * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
1456 | - */ |
|
1457 | - public function _remove_relations($relationName, $where_query_params = []) |
|
1458 | - { |
|
1459 | - if ($relationName === 'Ticket') { |
|
1460 | - $tickets = $this->tickets(); |
|
1461 | - foreach ($tickets as $ticket) { |
|
1462 | - $this->decreaseSold($ticket->sold()); |
|
1463 | - $this->decreaseReserved($ticket->reserved()); |
|
1464 | - $this->save(); |
|
1465 | - } |
|
1466 | - } |
|
1467 | - return parent::_remove_relations($relationName, $where_query_params); |
|
1468 | - } |
|
1469 | - |
|
1470 | - |
|
1471 | - /******************************************************************* |
|
15 | + /** |
|
16 | + * constant used by get_active_status, indicates datetime has no more available spaces |
|
17 | + */ |
|
18 | + const sold_out = 'DTS'; |
|
19 | + |
|
20 | + /** |
|
21 | + * constant used by get_active_status, indicating datetime is still active (even is not over, can be registered-for) |
|
22 | + */ |
|
23 | + const active = 'DTA'; |
|
24 | + |
|
25 | + /** |
|
26 | + * constant used by get_active_status, indicating the datetime cannot be used for registrations yet, but has not |
|
27 | + * expired |
|
28 | + */ |
|
29 | + const upcoming = 'DTU'; |
|
30 | + |
|
31 | + /** |
|
32 | + * Datetime is postponed |
|
33 | + */ |
|
34 | + const postponed = 'DTP'; |
|
35 | + |
|
36 | + /** |
|
37 | + * Datetime is cancelled |
|
38 | + */ |
|
39 | + const cancelled = 'DTC'; |
|
40 | + |
|
41 | + /** |
|
42 | + * constant used by get_active_status, indicates datetime has expired (event is over) |
|
43 | + */ |
|
44 | + const expired = 'DTE'; |
|
45 | + |
|
46 | + /** |
|
47 | + * constant used in various places indicating that an event is INACTIVE (not yet ready to be published) |
|
48 | + */ |
|
49 | + const inactive = 'DTI'; |
|
50 | + |
|
51 | + |
|
52 | + /** |
|
53 | + * @param array $props_n_values incoming values |
|
54 | + * @param string $timezone incoming timezone (if not set the timezone set for the website will be used.) |
|
55 | + * @param array $date_formats incoming date_formats in an array where the first value is the date_format |
|
56 | + * and the second value is the time format |
|
57 | + * @return EE_Datetime |
|
58 | + * @throws ReflectionException |
|
59 | + * @throws InvalidArgumentException |
|
60 | + * @throws InvalidInterfaceException |
|
61 | + * @throws InvalidDataTypeException |
|
62 | + * @throws EE_Error |
|
63 | + */ |
|
64 | + public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) |
|
65 | + { |
|
66 | + $has_object = parent::_check_for_object( |
|
67 | + $props_n_values, |
|
68 | + __CLASS__, |
|
69 | + $timezone, |
|
70 | + $date_formats |
|
71 | + ); |
|
72 | + return $has_object |
|
73 | + ? $has_object |
|
74 | + : new self($props_n_values, false, $timezone, $date_formats); |
|
75 | + } |
|
76 | + |
|
77 | + |
|
78 | + /** |
|
79 | + * @param array $props_n_values incoming values from the database |
|
80 | + * @param string $timezone incoming timezone as set by the model. If not set the timezone for |
|
81 | + * the website will be used. |
|
82 | + * @return EE_Datetime |
|
83 | + * @throws ReflectionException |
|
84 | + * @throws InvalidArgumentException |
|
85 | + * @throws InvalidInterfaceException |
|
86 | + * @throws InvalidDataTypeException |
|
87 | + * @throws EE_Error |
|
88 | + */ |
|
89 | + public static function new_instance_from_db($props_n_values = array(), $timezone = null) |
|
90 | + { |
|
91 | + return new self($props_n_values, true, $timezone); |
|
92 | + } |
|
93 | + |
|
94 | + |
|
95 | + /** |
|
96 | + * @param $name |
|
97 | + * @throws ReflectionException |
|
98 | + * @throws InvalidArgumentException |
|
99 | + * @throws InvalidInterfaceException |
|
100 | + * @throws InvalidDataTypeException |
|
101 | + * @throws EE_Error |
|
102 | + */ |
|
103 | + public function set_name($name) |
|
104 | + { |
|
105 | + $this->set('DTT_name', $name); |
|
106 | + } |
|
107 | + |
|
108 | + |
|
109 | + /** |
|
110 | + * @param $description |
|
111 | + * @throws ReflectionException |
|
112 | + * @throws InvalidArgumentException |
|
113 | + * @throws InvalidInterfaceException |
|
114 | + * @throws InvalidDataTypeException |
|
115 | + * @throws EE_Error |
|
116 | + */ |
|
117 | + public function set_description($description) |
|
118 | + { |
|
119 | + $this->set('DTT_description', $description); |
|
120 | + } |
|
121 | + |
|
122 | + |
|
123 | + /** |
|
124 | + * Set event start date |
|
125 | + * set the start date for an event |
|
126 | + * |
|
127 | + * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
128 | + * @throws ReflectionException |
|
129 | + * @throws InvalidArgumentException |
|
130 | + * @throws InvalidInterfaceException |
|
131 | + * @throws InvalidDataTypeException |
|
132 | + * @throws EE_Error |
|
133 | + */ |
|
134 | + public function set_start_date($date) |
|
135 | + { |
|
136 | + $this->_set_date_for($date, 'DTT_EVT_start'); |
|
137 | + } |
|
138 | + |
|
139 | + |
|
140 | + /** |
|
141 | + * Set event start time |
|
142 | + * set the start time for an event |
|
143 | + * |
|
144 | + * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
145 | + * @throws ReflectionException |
|
146 | + * @throws InvalidArgumentException |
|
147 | + * @throws InvalidInterfaceException |
|
148 | + * @throws InvalidDataTypeException |
|
149 | + * @throws EE_Error |
|
150 | + */ |
|
151 | + public function set_start_time($time) |
|
152 | + { |
|
153 | + $this->_set_time_for($time, 'DTT_EVT_start'); |
|
154 | + } |
|
155 | + |
|
156 | + |
|
157 | + /** |
|
158 | + * Set event end date |
|
159 | + * set the end date for an event |
|
160 | + * |
|
161 | + * @param string $date a string representation of the event's date ex: Dec. 25, 2025 or 12-25-2025 |
|
162 | + * @throws ReflectionException |
|
163 | + * @throws InvalidArgumentException |
|
164 | + * @throws InvalidInterfaceException |
|
165 | + * @throws InvalidDataTypeException |
|
166 | + * @throws EE_Error |
|
167 | + */ |
|
168 | + public function set_end_date($date) |
|
169 | + { |
|
170 | + $this->_set_date_for($date, 'DTT_EVT_end'); |
|
171 | + } |
|
172 | + |
|
173 | + |
|
174 | + /** |
|
175 | + * Set event end time |
|
176 | + * set the end time for an event |
|
177 | + * |
|
178 | + * @param string $time a string representation of the event time ex: 9am or 7:30 PM |
|
179 | + * @throws ReflectionException |
|
180 | + * @throws InvalidArgumentException |
|
181 | + * @throws InvalidInterfaceException |
|
182 | + * @throws InvalidDataTypeException |
|
183 | + * @throws EE_Error |
|
184 | + */ |
|
185 | + public function set_end_time($time) |
|
186 | + { |
|
187 | + $this->_set_time_for($time, 'DTT_EVT_end'); |
|
188 | + } |
|
189 | + |
|
190 | + |
|
191 | + /** |
|
192 | + * Set registration limit |
|
193 | + * set the maximum number of attendees that can be registered for this datetime slot |
|
194 | + * |
|
195 | + * @param int|float $reg_limit |
|
196 | + * @throws ReflectionException |
|
197 | + * @throws InvalidArgumentException |
|
198 | + * @throws InvalidInterfaceException |
|
199 | + * @throws InvalidDataTypeException |
|
200 | + * @throws EE_Error |
|
201 | + */ |
|
202 | + public function set_reg_limit($reg_limit) |
|
203 | + { |
|
204 | + $this->set('DTT_reg_limit', $reg_limit); |
|
205 | + } |
|
206 | + |
|
207 | + |
|
208 | + /** |
|
209 | + * get the number of tickets sold for this datetime slot |
|
210 | + * |
|
211 | + * @return mixed int on success, FALSE on fail |
|
212 | + * @throws ReflectionException |
|
213 | + * @throws InvalidArgumentException |
|
214 | + * @throws InvalidInterfaceException |
|
215 | + * @throws InvalidDataTypeException |
|
216 | + * @throws EE_Error |
|
217 | + */ |
|
218 | + public function sold() |
|
219 | + { |
|
220 | + return $this->get_raw('DTT_sold'); |
|
221 | + } |
|
222 | + |
|
223 | + |
|
224 | + /** |
|
225 | + * @param int $sold |
|
226 | + * @throws ReflectionException |
|
227 | + * @throws InvalidArgumentException |
|
228 | + * @throws InvalidInterfaceException |
|
229 | + * @throws InvalidDataTypeException |
|
230 | + * @throws EE_Error |
|
231 | + */ |
|
232 | + public function set_sold($sold) |
|
233 | + { |
|
234 | + // sold can not go below zero |
|
235 | + $sold = max(0, $sold); |
|
236 | + $this->set('DTT_sold', $sold); |
|
237 | + } |
|
238 | + |
|
239 | + |
|
240 | + /** |
|
241 | + * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
242 | + * Simultaneously decreases the reserved count, unless $also_decrease_reserved is false. |
|
243 | + * |
|
244 | + * @param int $qty |
|
245 | + * @param boolean $also_decrease_reserved |
|
246 | + * @return boolean indicating success |
|
247 | + * @throws ReflectionException |
|
248 | + * @throws InvalidArgumentException |
|
249 | + * @throws InvalidInterfaceException |
|
250 | + * @throws InvalidDataTypeException |
|
251 | + * @throws EE_Error |
|
252 | + */ |
|
253 | + public function increaseSold(int $qty = 1, bool $also_decrease_reserved = true): bool |
|
254 | + { |
|
255 | + $qty = absint($qty); |
|
256 | + if ($also_decrease_reserved) { |
|
257 | + $success = $this->adjustNumericFieldsInDb( |
|
258 | + [ |
|
259 | + 'DTT_reserved' => $qty * -1, |
|
260 | + 'DTT_sold' => $qty |
|
261 | + ] |
|
262 | + ); |
|
263 | + } else { |
|
264 | + $success = $this->adjustNumericFieldsInDb( |
|
265 | + [ |
|
266 | + 'DTT_sold' => $qty |
|
267 | + ] |
|
268 | + ); |
|
269 | + } |
|
270 | + |
|
271 | + do_action( |
|
272 | + 'AHEE__EE_Datetime__increase_sold', |
|
273 | + $this, |
|
274 | + $qty, |
|
275 | + $this->sold(), |
|
276 | + $success |
|
277 | + ); |
|
278 | + return $success; |
|
279 | + } |
|
280 | + |
|
281 | + |
|
282 | + /** |
|
283 | + * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
284 | + * to save afterwards.) |
|
285 | + * |
|
286 | + * @param int $qty |
|
287 | + * @return boolean indicating success |
|
288 | + * @throws ReflectionException |
|
289 | + * @throws InvalidArgumentException |
|
290 | + * @throws InvalidInterfaceException |
|
291 | + * @throws InvalidDataTypeException |
|
292 | + * @throws EE_Error |
|
293 | + */ |
|
294 | + public function decreaseSold(int $qty = 1): bool |
|
295 | + { |
|
296 | + $qty = absint($qty); |
|
297 | + $success = $this->adjustNumericFieldsInDb( |
|
298 | + [ |
|
299 | + 'DTT_sold' => $qty * -1 |
|
300 | + ] |
|
301 | + ); |
|
302 | + do_action( |
|
303 | + 'AHEE__EE_Datetime__decrease_sold', |
|
304 | + $this, |
|
305 | + $qty, |
|
306 | + $this->sold(), |
|
307 | + $success |
|
308 | + ); |
|
309 | + return $success; |
|
310 | + } |
|
311 | + |
|
312 | + |
|
313 | + /** |
|
314 | + * Gets qty of reserved tickets for this datetime |
|
315 | + * |
|
316 | + * @return int |
|
317 | + * @throws ReflectionException |
|
318 | + * @throws InvalidArgumentException |
|
319 | + * @throws InvalidInterfaceException |
|
320 | + * @throws InvalidDataTypeException |
|
321 | + * @throws EE_Error |
|
322 | + */ |
|
323 | + public function reserved(): int |
|
324 | + { |
|
325 | + return $this->get_raw('DTT_reserved'); |
|
326 | + } |
|
327 | + |
|
328 | + |
|
329 | + /** |
|
330 | + * Sets qty of reserved tickets for this datetime |
|
331 | + * |
|
332 | + * @param int $reserved |
|
333 | + * @throws ReflectionException |
|
334 | + * @throws InvalidArgumentException |
|
335 | + * @throws InvalidInterfaceException |
|
336 | + * @throws InvalidDataTypeException |
|
337 | + * @throws EE_Error |
|
338 | + */ |
|
339 | + public function set_reserved(int $reserved) |
|
340 | + { |
|
341 | + // reserved can not go below zero |
|
342 | + $reserved = max(0, $reserved); |
|
343 | + $this->set('DTT_reserved', $reserved); |
|
344 | + } |
|
345 | + |
|
346 | + |
|
347 | + /** |
|
348 | + * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
349 | + * |
|
350 | + * @param int $qty |
|
351 | + * @return boolean indicating success |
|
352 | + * @throws ReflectionException |
|
353 | + * @throws InvalidArgumentException |
|
354 | + * @throws InvalidInterfaceException |
|
355 | + * @throws InvalidDataTypeException |
|
356 | + * @throws EE_Error |
|
357 | + */ |
|
358 | + public function increaseReserved(int $qty = 1): bool |
|
359 | + { |
|
360 | + $qty = absint($qty); |
|
361 | + $success = $this->incrementFieldConditionallyInDb( |
|
362 | + 'DTT_reserved', |
|
363 | + 'DTT_sold', |
|
364 | + 'DTT_reg_limit', |
|
365 | + $qty |
|
366 | + ); |
|
367 | + do_action( |
|
368 | + 'AHEE__EE_Datetime__increase_reserved', |
|
369 | + $this, |
|
370 | + $qty, |
|
371 | + $this->reserved(), |
|
372 | + $success |
|
373 | + ); |
|
374 | + return $success; |
|
375 | + } |
|
376 | + |
|
377 | + |
|
378 | + /** |
|
379 | + * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
380 | + * |
|
381 | + * @param int $qty |
|
382 | + * @return boolean indicating success |
|
383 | + * @throws ReflectionException |
|
384 | + * @throws InvalidArgumentException |
|
385 | + * @throws InvalidInterfaceException |
|
386 | + * @throws InvalidDataTypeException |
|
387 | + * @throws EE_Error |
|
388 | + */ |
|
389 | + public function decreaseReserved(int $qty = 1): bool |
|
390 | + { |
|
391 | + $qty = absint($qty); |
|
392 | + $success = $this->adjustNumericFieldsInDb( |
|
393 | + [ |
|
394 | + 'DTT_reserved' => $qty * -1 |
|
395 | + ] |
|
396 | + ); |
|
397 | + do_action( |
|
398 | + 'AHEE__EE_Datetime__decrease_reserved', |
|
399 | + $this, |
|
400 | + $qty, |
|
401 | + $this->reserved(), |
|
402 | + $success |
|
403 | + ); |
|
404 | + return $success; |
|
405 | + } |
|
406 | + |
|
407 | + |
|
408 | + /** |
|
409 | + * total sold and reserved tickets |
|
410 | + * |
|
411 | + * @return int |
|
412 | + * @throws ReflectionException |
|
413 | + * @throws InvalidArgumentException |
|
414 | + * @throws InvalidInterfaceException |
|
415 | + * @throws InvalidDataTypeException |
|
416 | + * @throws EE_Error |
|
417 | + */ |
|
418 | + public function sold_and_reserved(): int |
|
419 | + { |
|
420 | + return $this->sold() + $this->reserved(); |
|
421 | + } |
|
422 | + |
|
423 | + |
|
424 | + /** |
|
425 | + * returns the datetime name |
|
426 | + * |
|
427 | + * @return string |
|
428 | + * @throws ReflectionException |
|
429 | + * @throws InvalidArgumentException |
|
430 | + * @throws InvalidInterfaceException |
|
431 | + * @throws InvalidDataTypeException |
|
432 | + * @throws EE_Error |
|
433 | + */ |
|
434 | + public function name(): string |
|
435 | + { |
|
436 | + return $this->get('DTT_name'); |
|
437 | + } |
|
438 | + |
|
439 | + |
|
440 | + /** |
|
441 | + * returns the datetime description |
|
442 | + * |
|
443 | + * @return string |
|
444 | + * @throws ReflectionException |
|
445 | + * @throws InvalidArgumentException |
|
446 | + * @throws InvalidInterfaceException |
|
447 | + * @throws InvalidDataTypeException |
|
448 | + * @throws EE_Error |
|
449 | + */ |
|
450 | + public function description(): string |
|
451 | + { |
|
452 | + return $this->get('DTT_description'); |
|
453 | + } |
|
454 | + |
|
455 | + |
|
456 | + /** |
|
457 | + * This helper simply returns whether the event_datetime for the current datetime is a primary datetime |
|
458 | + * |
|
459 | + * @return boolean TRUE if is primary, FALSE if not. |
|
460 | + * @throws ReflectionException |
|
461 | + * @throws InvalidArgumentException |
|
462 | + * @throws InvalidInterfaceException |
|
463 | + * @throws InvalidDataTypeException |
|
464 | + * @throws EE_Error |
|
465 | + */ |
|
466 | + public function is_primary(): bool |
|
467 | + { |
|
468 | + return $this->get('DTT_is_primary'); |
|
469 | + } |
|
470 | + |
|
471 | + |
|
472 | + /** |
|
473 | + * This helper simply returns the order for the datetime |
|
474 | + * |
|
475 | + * @return int The order of the datetime for this event. |
|
476 | + * @throws ReflectionException |
|
477 | + * @throws InvalidArgumentException |
|
478 | + * @throws InvalidInterfaceException |
|
479 | + * @throws InvalidDataTypeException |
|
480 | + * @throws EE_Error |
|
481 | + */ |
|
482 | + public function order(): int |
|
483 | + { |
|
484 | + return $this->get('DTT_order'); |
|
485 | + } |
|
486 | + |
|
487 | + |
|
488 | + /** |
|
489 | + * This helper simply returns the parent id for the datetime |
|
490 | + * |
|
491 | + * @return int |
|
492 | + * @throws ReflectionException |
|
493 | + * @throws InvalidArgumentException |
|
494 | + * @throws InvalidInterfaceException |
|
495 | + * @throws InvalidDataTypeException |
|
496 | + * @throws EE_Error |
|
497 | + */ |
|
498 | + public function parent(): int |
|
499 | + { |
|
500 | + return $this->get('DTT_parent'); |
|
501 | + } |
|
502 | + |
|
503 | + |
|
504 | + /** |
|
505 | + * show date and/or time |
|
506 | + * |
|
507 | + * @param string $date_or_time whether to display a date or time or both |
|
508 | + * @param string $start_or_end whether to display start or end datetimes |
|
509 | + * @param string $dt_frmt |
|
510 | + * @param string $tm_frmt |
|
511 | + * @param bool $echo whether we echo or return (note echoing uses "pretty" formats, |
|
512 | + * otherwise we use the standard formats) |
|
513 | + * @return string|bool string on success, FALSE on fail |
|
514 | + * @throws ReflectionException |
|
515 | + * @throws InvalidArgumentException |
|
516 | + * @throws InvalidInterfaceException |
|
517 | + * @throws InvalidDataTypeException |
|
518 | + * @throws EE_Error |
|
519 | + */ |
|
520 | + private function _show_datetime( |
|
521 | + $date_or_time = null, |
|
522 | + $start_or_end = 'start', |
|
523 | + $dt_frmt = '', |
|
524 | + $tm_frmt = '', |
|
525 | + $echo = false |
|
526 | + ) { |
|
527 | + $field_name = "DTT_EVT_{$start_or_end}"; |
|
528 | + $dtt = $this->_get_datetime( |
|
529 | + $field_name, |
|
530 | + $dt_frmt, |
|
531 | + $tm_frmt, |
|
532 | + $date_or_time, |
|
533 | + $echo |
|
534 | + ); |
|
535 | + if (! $echo) { |
|
536 | + return $dtt; |
|
537 | + } |
|
538 | + return ''; |
|
539 | + } |
|
540 | + |
|
541 | + |
|
542 | + /** |
|
543 | + * get event start date. Provide either the date format, or NULL to re-use the |
|
544 | + * last-used format, or '' to use the default date format |
|
545 | + * |
|
546 | + * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
547 | + * @return mixed string on success, FALSE on fail |
|
548 | + * @throws ReflectionException |
|
549 | + * @throws InvalidArgumentException |
|
550 | + * @throws InvalidInterfaceException |
|
551 | + * @throws InvalidDataTypeException |
|
552 | + * @throws EE_Error |
|
553 | + */ |
|
554 | + public function start_date($dt_frmt = '') |
|
555 | + { |
|
556 | + return $this->_show_datetime('D', 'start', $dt_frmt); |
|
557 | + } |
|
558 | + |
|
559 | + |
|
560 | + /** |
|
561 | + * Echoes start_date() |
|
562 | + * |
|
563 | + * @param string $dt_frmt |
|
564 | + * @throws ReflectionException |
|
565 | + * @throws InvalidArgumentException |
|
566 | + * @throws InvalidInterfaceException |
|
567 | + * @throws InvalidDataTypeException |
|
568 | + * @throws EE_Error |
|
569 | + */ |
|
570 | + public function e_start_date($dt_frmt = '') |
|
571 | + { |
|
572 | + $this->_show_datetime('D', 'start', $dt_frmt, null, true); |
|
573 | + } |
|
574 | + |
|
575 | + |
|
576 | + /** |
|
577 | + * get end date. Provide either the date format, or NULL to re-use the |
|
578 | + * last-used format, or '' to use the default date format |
|
579 | + * |
|
580 | + * @param string $dt_frmt string representation of date format defaults to 'F j, Y' |
|
581 | + * @return mixed string on success, FALSE on fail |
|
582 | + * @throws ReflectionException |
|
583 | + * @throws InvalidArgumentException |
|
584 | + * @throws InvalidInterfaceException |
|
585 | + * @throws InvalidDataTypeException |
|
586 | + * @throws EE_Error |
|
587 | + */ |
|
588 | + public function end_date($dt_frmt = '') |
|
589 | + { |
|
590 | + return $this->_show_datetime('D', 'end', $dt_frmt); |
|
591 | + } |
|
592 | + |
|
593 | + |
|
594 | + /** |
|
595 | + * Echoes the end date. See end_date() |
|
596 | + * |
|
597 | + * @param string $dt_frmt |
|
598 | + * @throws ReflectionException |
|
599 | + * @throws InvalidArgumentException |
|
600 | + * @throws InvalidInterfaceException |
|
601 | + * @throws InvalidDataTypeException |
|
602 | + * @throws EE_Error |
|
603 | + */ |
|
604 | + public function e_end_date($dt_frmt = '') |
|
605 | + { |
|
606 | + $this->_show_datetime('D', 'end', $dt_frmt, null, true); |
|
607 | + } |
|
608 | + |
|
609 | + |
|
610 | + /** |
|
611 | + * get date_range - meaning the start AND end date |
|
612 | + * |
|
613 | + * @access public |
|
614 | + * @param string $dt_frmt string representation of date format defaults to WP settings |
|
615 | + * @param string $conjunction conjunction junction what's your function ? |
|
616 | + * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
617 | + * @return mixed string on success, FALSE on fail |
|
618 | + * @throws ReflectionException |
|
619 | + * @throws InvalidArgumentException |
|
620 | + * @throws InvalidInterfaceException |
|
621 | + * @throws InvalidDataTypeException |
|
622 | + * @throws EE_Error |
|
623 | + */ |
|
624 | + public function date_range($dt_frmt = '', $conjunction = ' - ') |
|
625 | + { |
|
626 | + $dt_frmt = ! empty($dt_frmt) ? $dt_frmt : $this->_dt_frmt; |
|
627 | + $start = str_replace( |
|
628 | + ' ', |
|
629 | + ' ', |
|
630 | + $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt) |
|
631 | + ); |
|
632 | + $end = str_replace( |
|
633 | + ' ', |
|
634 | + ' ', |
|
635 | + $this->get_i18n_datetime('DTT_EVT_end', $dt_frmt) |
|
636 | + ); |
|
637 | + return $start !== $end ? $start . $conjunction . $end : $start; |
|
638 | + } |
|
639 | + |
|
640 | + |
|
641 | + /** |
|
642 | + * @param string $dt_frmt |
|
643 | + * @param string $conjunction |
|
644 | + * @throws ReflectionException |
|
645 | + * @throws InvalidArgumentException |
|
646 | + * @throws InvalidInterfaceException |
|
647 | + * @throws InvalidDataTypeException |
|
648 | + * @throws EE_Error |
|
649 | + */ |
|
650 | + public function e_date_range($dt_frmt = '', $conjunction = ' - ') |
|
651 | + { |
|
652 | + echo esc_html($this->date_range($dt_frmt, $conjunction)); |
|
653 | + } |
|
654 | + |
|
655 | + |
|
656 | + /** |
|
657 | + * get start time |
|
658 | + * |
|
659 | + * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
660 | + * @return mixed string on success, FALSE on fail |
|
661 | + * @throws ReflectionException |
|
662 | + * @throws InvalidArgumentException |
|
663 | + * @throws InvalidInterfaceException |
|
664 | + * @throws InvalidDataTypeException |
|
665 | + * @throws EE_Error |
|
666 | + */ |
|
667 | + public function start_time($tm_format = '') |
|
668 | + { |
|
669 | + return $this->_show_datetime('T', 'start', null, $tm_format); |
|
670 | + } |
|
671 | + |
|
672 | + |
|
673 | + /** |
|
674 | + * @param string $tm_format |
|
675 | + * @throws ReflectionException |
|
676 | + * @throws InvalidArgumentException |
|
677 | + * @throws InvalidInterfaceException |
|
678 | + * @throws InvalidDataTypeException |
|
679 | + * @throws EE_Error |
|
680 | + */ |
|
681 | + public function e_start_time($tm_format = '') |
|
682 | + { |
|
683 | + $this->_show_datetime('T', 'start', null, $tm_format, true); |
|
684 | + } |
|
685 | + |
|
686 | + |
|
687 | + /** |
|
688 | + * get end time |
|
689 | + * |
|
690 | + * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
691 | + * @return mixed string on success, FALSE on fail |
|
692 | + * @throws ReflectionException |
|
693 | + * @throws InvalidArgumentException |
|
694 | + * @throws InvalidInterfaceException |
|
695 | + * @throws InvalidDataTypeException |
|
696 | + * @throws EE_Error |
|
697 | + */ |
|
698 | + public function end_time($tm_format = '') |
|
699 | + { |
|
700 | + return $this->_show_datetime('T', 'end', null, $tm_format); |
|
701 | + } |
|
702 | + |
|
703 | + |
|
704 | + /** |
|
705 | + * @param string $tm_format |
|
706 | + * @throws ReflectionException |
|
707 | + * @throws InvalidArgumentException |
|
708 | + * @throws InvalidInterfaceException |
|
709 | + * @throws InvalidDataTypeException |
|
710 | + * @throws EE_Error |
|
711 | + */ |
|
712 | + public function e_end_time($tm_format = '') |
|
713 | + { |
|
714 | + $this->_show_datetime('T', 'end', null, $tm_format, true); |
|
715 | + } |
|
716 | + |
|
717 | + |
|
718 | + /** |
|
719 | + * get time_range |
|
720 | + * |
|
721 | + * @access public |
|
722 | + * @param string $tm_format string representation of time format defaults to 'g:i a' |
|
723 | + * @param string $conjunction conjunction junction what's your function ? |
|
724 | + * this string joins the start date with the end date ie: Jan 01 "to" Dec 31 |
|
725 | + * @return mixed string on success, FALSE on fail |
|
726 | + * @throws ReflectionException |
|
727 | + * @throws InvalidArgumentException |
|
728 | + * @throws InvalidInterfaceException |
|
729 | + * @throws InvalidDataTypeException |
|
730 | + * @throws EE_Error |
|
731 | + */ |
|
732 | + public function time_range($tm_format = '', $conjunction = ' - ') |
|
733 | + { |
|
734 | + $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
735 | + $start = str_replace( |
|
736 | + ' ', |
|
737 | + ' ', |
|
738 | + $this->get_i18n_datetime('DTT_EVT_start', $tm_format) |
|
739 | + ); |
|
740 | + $end = str_replace( |
|
741 | + ' ', |
|
742 | + ' ', |
|
743 | + $this->get_i18n_datetime('DTT_EVT_end', $tm_format) |
|
744 | + ); |
|
745 | + return $start !== $end ? $start . $conjunction . $end : $start; |
|
746 | + } |
|
747 | + |
|
748 | + |
|
749 | + /** |
|
750 | + * @param string $tm_format |
|
751 | + * @param string $conjunction |
|
752 | + * @throws ReflectionException |
|
753 | + * @throws InvalidArgumentException |
|
754 | + * @throws InvalidInterfaceException |
|
755 | + * @throws InvalidDataTypeException |
|
756 | + * @throws EE_Error |
|
757 | + */ |
|
758 | + public function e_time_range($tm_format = '', $conjunction = ' - ') |
|
759 | + { |
|
760 | + echo esc_html($this->time_range($tm_format, $conjunction)); |
|
761 | + } |
|
762 | + |
|
763 | + |
|
764 | + /** |
|
765 | + * This returns a range representation of the date and times. |
|
766 | + * Output is dependent on the difference (or similarity) between DTT_EVT_start and DTT_EVT_end. |
|
767 | + * Also, the return value is localized. |
|
768 | + * |
|
769 | + * @param string $dt_format |
|
770 | + * @param string $tm_format |
|
771 | + * @param string $conjunction used between two different dates or times. |
|
772 | + * ex: Dec 1{$conjunction}}Dec 6, or 2pm{$conjunction}3pm |
|
773 | + * @param string $separator used between the date and time formats. |
|
774 | + * ex: Dec 1, 2016{$separator}2pm |
|
775 | + * @return string |
|
776 | + * @throws ReflectionException |
|
777 | + * @throws InvalidArgumentException |
|
778 | + * @throws InvalidInterfaceException |
|
779 | + * @throws InvalidDataTypeException |
|
780 | + * @throws EE_Error |
|
781 | + */ |
|
782 | + public function date_and_time_range( |
|
783 | + $dt_format = '', |
|
784 | + $tm_format = '', |
|
785 | + $conjunction = ' - ', |
|
786 | + $separator = ' ' |
|
787 | + ) { |
|
788 | + $dt_format = ! empty($dt_format) ? $dt_format : $this->_dt_frmt; |
|
789 | + $tm_format = ! empty($tm_format) ? $tm_format : $this->_tm_frmt; |
|
790 | + $full_format = $dt_format . $separator . $tm_format; |
|
791 | + // the range output depends on various conditions |
|
792 | + switch (true) { |
|
793 | + // start date timestamp and end date timestamp are the same. |
|
794 | + case ($this->get_raw('DTT_EVT_start') === $this->get_raw('DTT_EVT_end')): |
|
795 | + $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format); |
|
796 | + break; |
|
797 | + // start and end date are the same but times are different |
|
798 | + case ($this->start_date() === $this->end_date()): |
|
799 | + $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
800 | + . $conjunction |
|
801 | + . $this->get_i18n_datetime('DTT_EVT_end', $tm_format); |
|
802 | + break; |
|
803 | + // all other conditions |
|
804 | + default: |
|
805 | + $output = $this->get_i18n_datetime('DTT_EVT_start', $full_format) |
|
806 | + . $conjunction |
|
807 | + . $this->get_i18n_datetime('DTT_EVT_end', $full_format); |
|
808 | + break; |
|
809 | + } |
|
810 | + return $output; |
|
811 | + } |
|
812 | + |
|
813 | + |
|
814 | + /** |
|
815 | + * This echos the results of date and time range. |
|
816 | + * |
|
817 | + * @see date_and_time_range() for more details on purpose. |
|
818 | + * @param string $dt_format |
|
819 | + * @param string $tm_format |
|
820 | + * @param string $conjunction |
|
821 | + * @return void |
|
822 | + * @throws ReflectionException |
|
823 | + * @throws InvalidArgumentException |
|
824 | + * @throws InvalidInterfaceException |
|
825 | + * @throws InvalidDataTypeException |
|
826 | + * @throws EE_Error |
|
827 | + */ |
|
828 | + public function e_date_and_time_range($dt_format = '', $tm_format = '', $conjunction = ' - ') |
|
829 | + { |
|
830 | + echo esc_html($this->date_and_time_range($dt_format, $tm_format, $conjunction)); |
|
831 | + } |
|
832 | + |
|
833 | + |
|
834 | + /** |
|
835 | + * get start date and start time |
|
836 | + * |
|
837 | + * @param string $dt_format - string representation of date format defaults to 'F j, Y' |
|
838 | + * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
839 | + * @return mixed string on success, FALSE on fail |
|
840 | + * @throws ReflectionException |
|
841 | + * @throws InvalidArgumentException |
|
842 | + * @throws InvalidInterfaceException |
|
843 | + * @throws InvalidDataTypeException |
|
844 | + * @throws EE_Error |
|
845 | + */ |
|
846 | + public function start_date_and_time($dt_format = '', $tm_format = '') |
|
847 | + { |
|
848 | + return $this->_show_datetime('', 'start', $dt_format, $tm_format); |
|
849 | + } |
|
850 | + |
|
851 | + |
|
852 | + /** |
|
853 | + * @param string $dt_frmt |
|
854 | + * @param string $tm_format |
|
855 | + * @throws ReflectionException |
|
856 | + * @throws InvalidArgumentException |
|
857 | + * @throws InvalidInterfaceException |
|
858 | + * @throws InvalidDataTypeException |
|
859 | + * @throws EE_Error |
|
860 | + */ |
|
861 | + public function e_start_date_and_time($dt_frmt = '', $tm_format = '') |
|
862 | + { |
|
863 | + $this->_show_datetime('', 'start', $dt_frmt, $tm_format, true); |
|
864 | + } |
|
865 | + |
|
866 | + |
|
867 | + /** |
|
868 | + * Shows the length of the event (start to end time). |
|
869 | + * Can be shown in 'seconds','minutes','hours', or 'days'. |
|
870 | + * By default, rounds up. (So if you use 'days', and then event |
|
871 | + * only occurs for 1 hour, it will return 1 day). |
|
872 | + * |
|
873 | + * @param string $units 'seconds','minutes','hours','days' |
|
874 | + * @param bool $round_up |
|
875 | + * @return float|int|mixed |
|
876 | + * @throws ReflectionException |
|
877 | + * @throws InvalidArgumentException |
|
878 | + * @throws InvalidInterfaceException |
|
879 | + * @throws InvalidDataTypeException |
|
880 | + * @throws EE_Error |
|
881 | + */ |
|
882 | + public function length($units = 'seconds', $round_up = false) |
|
883 | + { |
|
884 | + $start = $this->get_raw('DTT_EVT_start'); |
|
885 | + $end = $this->get_raw('DTT_EVT_end'); |
|
886 | + $length_in_units = $end - $start; |
|
887 | + switch ($units) { |
|
888 | + // NOTE: We purposefully don't use "break;" in order to chain the divisions |
|
889 | + /** @noinspection PhpMissingBreakStatementInspection */ |
|
890 | + // phpcs:disable PSR2.ControlStructures.SwitchDeclaration.TerminatingComment |
|
891 | + case 'days': |
|
892 | + $length_in_units /= 24; |
|
893 | + /** @noinspection PhpMissingBreakStatementInspection */ |
|
894 | + case 'hours': |
|
895 | + // fall through is intentional |
|
896 | + $length_in_units /= 60; |
|
897 | + /** @noinspection PhpMissingBreakStatementInspection */ |
|
898 | + case 'minutes': |
|
899 | + // fall through is intentional |
|
900 | + $length_in_units /= 60; |
|
901 | + case 'seconds': |
|
902 | + default: |
|
903 | + $length_in_units = ceil($length_in_units); |
|
904 | + } |
|
905 | + // phpcs:enable |
|
906 | + if ($round_up) { |
|
907 | + $length_in_units = max($length_in_units, 1); |
|
908 | + } |
|
909 | + return $length_in_units; |
|
910 | + } |
|
911 | + |
|
912 | + |
|
913 | + /** |
|
914 | + * get end date and time |
|
915 | + * |
|
916 | + * @param string $dt_frmt - string representation of date format defaults to 'F j, Y' |
|
917 | + * @param string $tm_format - string representation of time format defaults to 'g:i a' |
|
918 | + * @return mixed string on success, FALSE on fail |
|
919 | + * @throws ReflectionException |
|
920 | + * @throws InvalidArgumentException |
|
921 | + * @throws InvalidInterfaceException |
|
922 | + * @throws InvalidDataTypeException |
|
923 | + * @throws EE_Error |
|
924 | + */ |
|
925 | + public function end_date_and_time($dt_frmt = '', $tm_format = '') |
|
926 | + { |
|
927 | + return $this->_show_datetime('', 'end', $dt_frmt, $tm_format); |
|
928 | + } |
|
929 | + |
|
930 | + |
|
931 | + /** |
|
932 | + * @param string $dt_frmt |
|
933 | + * @param string $tm_format |
|
934 | + * @throws ReflectionException |
|
935 | + * @throws InvalidArgumentException |
|
936 | + * @throws InvalidInterfaceException |
|
937 | + * @throws InvalidDataTypeException |
|
938 | + * @throws EE_Error |
|
939 | + */ |
|
940 | + public function e_end_date_and_time($dt_frmt = '', $tm_format = '') |
|
941 | + { |
|
942 | + $this->_show_datetime('', 'end', $dt_frmt, $tm_format, true); |
|
943 | + } |
|
944 | + |
|
945 | + |
|
946 | + /** |
|
947 | + * get start timestamp |
|
948 | + * |
|
949 | + * @return int |
|
950 | + * @throws ReflectionException |
|
951 | + * @throws InvalidArgumentException |
|
952 | + * @throws InvalidInterfaceException |
|
953 | + * @throws InvalidDataTypeException |
|
954 | + * @throws EE_Error |
|
955 | + */ |
|
956 | + public function start() |
|
957 | + { |
|
958 | + return $this->get_raw('DTT_EVT_start'); |
|
959 | + } |
|
960 | + |
|
961 | + |
|
962 | + /** |
|
963 | + * get end timestamp |
|
964 | + * |
|
965 | + * @return int |
|
966 | + * @throws ReflectionException |
|
967 | + * @throws InvalidArgumentException |
|
968 | + * @throws InvalidInterfaceException |
|
969 | + * @throws InvalidDataTypeException |
|
970 | + * @throws EE_Error |
|
971 | + */ |
|
972 | + public function end() |
|
973 | + { |
|
974 | + return $this->get_raw('DTT_EVT_end'); |
|
975 | + } |
|
976 | + |
|
977 | + |
|
978 | + /** |
|
979 | + * get the registration limit for this datetime slot |
|
980 | + * |
|
981 | + * @return int|float int = finite limit EE_INF(float) = unlimited |
|
982 | + * @throws ReflectionException |
|
983 | + * @throws InvalidArgumentException |
|
984 | + * @throws InvalidInterfaceException |
|
985 | + * @throws InvalidDataTypeException |
|
986 | + * @throws EE_Error |
|
987 | + */ |
|
988 | + public function reg_limit() |
|
989 | + { |
|
990 | + return $this->get_raw('DTT_reg_limit'); |
|
991 | + } |
|
992 | + |
|
993 | + |
|
994 | + /** |
|
995 | + * have the tickets sold for this datetime, met or exceed the registration limit ? |
|
996 | + * |
|
997 | + * @return boolean |
|
998 | + * @throws ReflectionException |
|
999 | + * @throws InvalidArgumentException |
|
1000 | + * @throws InvalidInterfaceException |
|
1001 | + * @throws InvalidDataTypeException |
|
1002 | + * @throws EE_Error |
|
1003 | + */ |
|
1004 | + public function sold_out() |
|
1005 | + { |
|
1006 | + return $this->reg_limit() > 0 && $this->sold() >= $this->reg_limit(); |
|
1007 | + } |
|
1008 | + |
|
1009 | + |
|
1010 | + /** |
|
1011 | + * return the total number of spaces remaining at this venue. |
|
1012 | + * This only takes the venue's capacity into account, NOT the tickets available for sale |
|
1013 | + * |
|
1014 | + * @param bool $consider_tickets Whether to consider tickets remaining when determining if there are any spaces left |
|
1015 | + * Because if all tickets attached to this datetime have no spaces left, |
|
1016 | + * then this datetime IS effectively sold out. |
|
1017 | + * However, there are cases where we just want to know the spaces |
|
1018 | + * remaining for this particular datetime, hence the flag. |
|
1019 | + * @return int|float |
|
1020 | + * @throws ReflectionException |
|
1021 | + * @throws InvalidArgumentException |
|
1022 | + * @throws InvalidInterfaceException |
|
1023 | + * @throws InvalidDataTypeException |
|
1024 | + * @throws EE_Error |
|
1025 | + */ |
|
1026 | + public function spaces_remaining($consider_tickets = false) |
|
1027 | + { |
|
1028 | + // tickets remaining available for purchase |
|
1029 | + // no need for special checks for infinite, because if DTT_reg_limit == EE_INF, then EE_INF - x = EE_INF |
|
1030 | + $dtt_remaining = $this->reg_limit() - $this->sold_and_reserved(); |
|
1031 | + if (! $consider_tickets) { |
|
1032 | + return $dtt_remaining; |
|
1033 | + } |
|
1034 | + $tickets_remaining = $this->tickets_remaining(); |
|
1035 | + return min($dtt_remaining, $tickets_remaining); |
|
1036 | + } |
|
1037 | + |
|
1038 | + |
|
1039 | + /** |
|
1040 | + * Counts the total tickets available |
|
1041 | + * (from all the different types of tickets which are available for this datetime). |
|
1042 | + * |
|
1043 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1044 | + * @return int |
|
1045 | + * @throws ReflectionException |
|
1046 | + * @throws InvalidArgumentException |
|
1047 | + * @throws InvalidInterfaceException |
|
1048 | + * @throws InvalidDataTypeException |
|
1049 | + * @throws EE_Error |
|
1050 | + */ |
|
1051 | + public function tickets_remaining($query_params = array()) |
|
1052 | + { |
|
1053 | + $sum = 0; |
|
1054 | + $tickets = $this->tickets($query_params); |
|
1055 | + if (! empty($tickets)) { |
|
1056 | + foreach ($tickets as $ticket) { |
|
1057 | + if ($ticket instanceof EE_Ticket) { |
|
1058 | + // get the actual amount of tickets that can be sold |
|
1059 | + $qty = $ticket->qty('saleable'); |
|
1060 | + if ($qty === EE_INF) { |
|
1061 | + return EE_INF; |
|
1062 | + } |
|
1063 | + // no negative ticket quantities plz |
|
1064 | + if ($qty > 0) { |
|
1065 | + $sum += $qty; |
|
1066 | + } |
|
1067 | + } |
|
1068 | + } |
|
1069 | + } |
|
1070 | + return $sum; |
|
1071 | + } |
|
1072 | + |
|
1073 | + |
|
1074 | + /** |
|
1075 | + * Gets the count of all the tickets available at this datetime (not ticket types) |
|
1076 | + * before any were sold |
|
1077 | + * |
|
1078 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1079 | + * @return int |
|
1080 | + * @throws ReflectionException |
|
1081 | + * @throws InvalidArgumentException |
|
1082 | + * @throws InvalidInterfaceException |
|
1083 | + * @throws InvalidDataTypeException |
|
1084 | + * @throws EE_Error |
|
1085 | + */ |
|
1086 | + public function sum_tickets_initially_available($query_params = array()) |
|
1087 | + { |
|
1088 | + return $this->sum_related('Ticket', $query_params, 'TKT_qty'); |
|
1089 | + } |
|
1090 | + |
|
1091 | + |
|
1092 | + /** |
|
1093 | + * Returns the lesser-of-the two: spaces remaining at this datetime, or |
|
1094 | + * the total tickets remaining (a sum of the tickets remaining for each ticket type |
|
1095 | + * that is available for this datetime). |
|
1096 | + * |
|
1097 | + * @return int |
|
1098 | + * @throws ReflectionException |
|
1099 | + * @throws InvalidArgumentException |
|
1100 | + * @throws InvalidInterfaceException |
|
1101 | + * @throws InvalidDataTypeException |
|
1102 | + * @throws EE_Error |
|
1103 | + */ |
|
1104 | + public function total_tickets_available_at_this_datetime() |
|
1105 | + { |
|
1106 | + return $this->spaces_remaining(true); |
|
1107 | + } |
|
1108 | + |
|
1109 | + |
|
1110 | + /** |
|
1111 | + * This simply compares the internal dtt for the given string with NOW |
|
1112 | + * and determines if the date is upcoming or not. |
|
1113 | + * |
|
1114 | + * @access public |
|
1115 | + * @return boolean |
|
1116 | + * @throws ReflectionException |
|
1117 | + * @throws InvalidArgumentException |
|
1118 | + * @throws InvalidInterfaceException |
|
1119 | + * @throws InvalidDataTypeException |
|
1120 | + * @throws EE_Error |
|
1121 | + */ |
|
1122 | + public function is_upcoming() |
|
1123 | + { |
|
1124 | + return ($this->get_raw('DTT_EVT_start') > time()); |
|
1125 | + } |
|
1126 | + |
|
1127 | + |
|
1128 | + /** |
|
1129 | + * This simply compares the internal datetime for the given string with NOW |
|
1130 | + * and returns if the date is active (i.e. start and end time) |
|
1131 | + * |
|
1132 | + * @return boolean |
|
1133 | + * @throws ReflectionException |
|
1134 | + * @throws InvalidArgumentException |
|
1135 | + * @throws InvalidInterfaceException |
|
1136 | + * @throws InvalidDataTypeException |
|
1137 | + * @throws EE_Error |
|
1138 | + */ |
|
1139 | + public function is_active() |
|
1140 | + { |
|
1141 | + return ($this->get_raw('DTT_EVT_start') < time() && $this->get_raw('DTT_EVT_end') > time()); |
|
1142 | + } |
|
1143 | + |
|
1144 | + |
|
1145 | + /** |
|
1146 | + * This simply compares the internal dtt for the given string with NOW |
|
1147 | + * and determines if the date is expired or not. |
|
1148 | + * |
|
1149 | + * @return boolean |
|
1150 | + * @throws ReflectionException |
|
1151 | + * @throws InvalidArgumentException |
|
1152 | + * @throws InvalidInterfaceException |
|
1153 | + * @throws InvalidDataTypeException |
|
1154 | + * @throws EE_Error |
|
1155 | + */ |
|
1156 | + public function is_expired() |
|
1157 | + { |
|
1158 | + return ($this->get_raw('DTT_EVT_end') < time()); |
|
1159 | + } |
|
1160 | + |
|
1161 | + |
|
1162 | + /** |
|
1163 | + * This returns the active status for whether an event is active, upcoming, or expired |
|
1164 | + * |
|
1165 | + * @return int return value will be one of the EE_Datetime status constants. |
|
1166 | + * @throws ReflectionException |
|
1167 | + * @throws InvalidArgumentException |
|
1168 | + * @throws InvalidInterfaceException |
|
1169 | + * @throws InvalidDataTypeException |
|
1170 | + * @throws EE_Error |
|
1171 | + */ |
|
1172 | + public function get_active_status() |
|
1173 | + { |
|
1174 | + $total_tickets_for_this_dtt = $this->total_tickets_available_at_this_datetime(); |
|
1175 | + if ($total_tickets_for_this_dtt !== false && $total_tickets_for_this_dtt < 1) { |
|
1176 | + return EE_Datetime::sold_out; |
|
1177 | + } |
|
1178 | + if ($this->is_expired()) { |
|
1179 | + return EE_Datetime::expired; |
|
1180 | + } |
|
1181 | + if ($this->is_upcoming()) { |
|
1182 | + return EE_Datetime::upcoming; |
|
1183 | + } |
|
1184 | + if ($this->is_active()) { |
|
1185 | + return EE_Datetime::active; |
|
1186 | + } |
|
1187 | + return null; |
|
1188 | + } |
|
1189 | + |
|
1190 | + |
|
1191 | + /** |
|
1192 | + * This returns a nice display name for the datetime that is contingent on the span between the dates and times. |
|
1193 | + * |
|
1194 | + * @param boolean $use_dtt_name if TRUE then we'll use DTT->name() if its not empty. |
|
1195 | + * @return string |
|
1196 | + * @throws ReflectionException |
|
1197 | + * @throws InvalidArgumentException |
|
1198 | + * @throws InvalidInterfaceException |
|
1199 | + * @throws InvalidDataTypeException |
|
1200 | + * @throws EE_Error |
|
1201 | + */ |
|
1202 | + public function get_dtt_display_name($use_dtt_name = false) |
|
1203 | + { |
|
1204 | + if ($use_dtt_name) { |
|
1205 | + $dtt_name = $this->name(); |
|
1206 | + if (! empty($dtt_name)) { |
|
1207 | + return $dtt_name; |
|
1208 | + } |
|
1209 | + } |
|
1210 | + // first condition is to see if the months are different |
|
1211 | + if ( |
|
1212 | + date('m', $this->get_raw('DTT_EVT_start')) !== date('m', $this->get_raw('DTT_EVT_end')) |
|
1213 | + ) { |
|
1214 | + $display_date = $this->start_date('M j\, Y g:i a') . ' - ' . $this->end_date('M j\, Y g:i a'); |
|
1215 | + // next condition is if its the same month but different day |
|
1216 | + } else { |
|
1217 | + if ( |
|
1218 | + date('m', $this->get_raw('DTT_EVT_start')) === date('m', $this->get_raw('DTT_EVT_end')) |
|
1219 | + && date('d', $this->get_raw('DTT_EVT_start')) !== date('d', $this->get_raw('DTT_EVT_end')) |
|
1220 | + ) { |
|
1221 | + $display_date = $this->start_date('M j\, g:i a') . ' - ' . $this->end_date('M j\, g:i a Y'); |
|
1222 | + } else { |
|
1223 | + $display_date = $this->start_date('F j\, Y') |
|
1224 | + . ' @ ' |
|
1225 | + . $this->start_date('g:i a') |
|
1226 | + . ' - ' |
|
1227 | + . $this->end_date('g:i a'); |
|
1228 | + } |
|
1229 | + } |
|
1230 | + return $display_date; |
|
1231 | + } |
|
1232 | + |
|
1233 | + |
|
1234 | + /** |
|
1235 | + * Gets all the tickets for this datetime |
|
1236 | + * |
|
1237 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1238 | + * @return EE_Base_Class[]|EE_Ticket[] |
|
1239 | + * @throws ReflectionException |
|
1240 | + * @throws InvalidArgumentException |
|
1241 | + * @throws InvalidInterfaceException |
|
1242 | + * @throws InvalidDataTypeException |
|
1243 | + * @throws EE_Error |
|
1244 | + */ |
|
1245 | + public function tickets($query_params = array()) |
|
1246 | + { |
|
1247 | + return $this->get_many_related('Ticket', $query_params); |
|
1248 | + } |
|
1249 | + |
|
1250 | + |
|
1251 | + /** |
|
1252 | + * Gets all the ticket types currently available for purchase |
|
1253 | + * |
|
1254 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1255 | + * @return EE_Ticket[] |
|
1256 | + * @throws ReflectionException |
|
1257 | + * @throws InvalidArgumentException |
|
1258 | + * @throws InvalidInterfaceException |
|
1259 | + * @throws InvalidDataTypeException |
|
1260 | + * @throws EE_Error |
|
1261 | + */ |
|
1262 | + public function ticket_types_available_for_purchase($query_params = array()) |
|
1263 | + { |
|
1264 | + // first check if datetime is valid |
|
1265 | + if ($this->sold_out() || ! ($this->is_upcoming() || $this->is_active())) { |
|
1266 | + return array(); |
|
1267 | + } |
|
1268 | + if (empty($query_params)) { |
|
1269 | + $query_params = array( |
|
1270 | + array( |
|
1271 | + 'TKT_start_date' => array('<=', EEM_Ticket::instance()->current_time_for_query('TKT_start_date')), |
|
1272 | + 'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')), |
|
1273 | + 'TKT_deleted' => false, |
|
1274 | + ), |
|
1275 | + ); |
|
1276 | + } |
|
1277 | + return $this->tickets($query_params); |
|
1278 | + } |
|
1279 | + |
|
1280 | + |
|
1281 | + /** |
|
1282 | + * @return EE_Base_Class|EE_Event |
|
1283 | + * @throws ReflectionException |
|
1284 | + * @throws InvalidArgumentException |
|
1285 | + * @throws InvalidInterfaceException |
|
1286 | + * @throws InvalidDataTypeException |
|
1287 | + * @throws EE_Error |
|
1288 | + */ |
|
1289 | + public function event() |
|
1290 | + { |
|
1291 | + return $this->get_first_related('Event'); |
|
1292 | + } |
|
1293 | + |
|
1294 | + |
|
1295 | + /** |
|
1296 | + * Updates the DTT_sold attribute (and saves) based on the number of registrations for this datetime |
|
1297 | + * (via the tickets). |
|
1298 | + * |
|
1299 | + * @return int |
|
1300 | + * @throws ReflectionException |
|
1301 | + * @throws InvalidArgumentException |
|
1302 | + * @throws InvalidInterfaceException |
|
1303 | + * @throws InvalidDataTypeException |
|
1304 | + * @throws EE_Error |
|
1305 | + */ |
|
1306 | + public function update_sold() |
|
1307 | + { |
|
1308 | + $count_regs_for_this_datetime = EEM_Registration::instance()->count( |
|
1309 | + array( |
|
1310 | + array( |
|
1311 | + 'STS_ID' => EEM_Registration::status_id_approved, |
|
1312 | + 'REG_deleted' => 0, |
|
1313 | + 'Ticket.Datetime.DTT_ID' => $this->ID(), |
|
1314 | + ), |
|
1315 | + ) |
|
1316 | + ); |
|
1317 | + $this->set_sold($count_regs_for_this_datetime); |
|
1318 | + $this->save(); |
|
1319 | + return $count_regs_for_this_datetime; |
|
1320 | + } |
|
1321 | + |
|
1322 | + |
|
1323 | + /** |
|
1324 | + * Adds a venue to this event |
|
1325 | + * |
|
1326 | + * @param int|EE_Venue /int $venue_id_or_obj |
|
1327 | + * @return EE_Base_Class|EE_Venue |
|
1328 | + * @throws EE_Error |
|
1329 | + * @throws ReflectionException |
|
1330 | + */ |
|
1331 | + public function add_venue($venue_id_or_obj): EE_Venue |
|
1332 | + { |
|
1333 | + return $this->_add_relation_to($venue_id_or_obj, 'Venue'); |
|
1334 | + } |
|
1335 | + |
|
1336 | + |
|
1337 | + /** |
|
1338 | + * Removes a venue from the event |
|
1339 | + * |
|
1340 | + * @param EE_Venue /int $venue_id_or_obj |
|
1341 | + * @return EE_Base_Class|EE_Venue |
|
1342 | + * @throws EE_Error |
|
1343 | + * @throws ReflectionException |
|
1344 | + */ |
|
1345 | + public function remove_venue($venue_id_or_obj): EE_Venue |
|
1346 | + { |
|
1347 | + $venue_id_or_obj = ! empty($venue_id_or_obj) ? $venue_id_or_obj : $this->venue(); |
|
1348 | + return $this->_remove_relation_to($venue_id_or_obj, 'Venue'); |
|
1349 | + } |
|
1350 | + |
|
1351 | + |
|
1352 | + /** |
|
1353 | + * Gets the venue related to the event. May provide additional $query_params if desired |
|
1354 | + * |
|
1355 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1356 | + * @return int |
|
1357 | + * @throws EE_Error |
|
1358 | + * @throws ReflectionException |
|
1359 | + */ |
|
1360 | + public function venue_ID(array $query_params = []): int |
|
1361 | + { |
|
1362 | + $venue = $this->get_first_related('Venue', $query_params); |
|
1363 | + return $venue instanceof EE_Venue |
|
1364 | + ? $venue->ID() |
|
1365 | + : 0; |
|
1366 | + } |
|
1367 | + |
|
1368 | + |
|
1369 | + /** |
|
1370 | + * Gets the venue related to the event. May provide additional $query_params if desired |
|
1371 | + * |
|
1372 | + * @param array $query_params @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md |
|
1373 | + * @return EE_Base_Class|EE_Venue |
|
1374 | + * @throws EE_Error |
|
1375 | + * @throws ReflectionException |
|
1376 | + */ |
|
1377 | + public function venue(array $query_params = []) |
|
1378 | + { |
|
1379 | + return $this->get_first_related('Venue', $query_params); |
|
1380 | + } |
|
1381 | + |
|
1382 | + |
|
1383 | + /** |
|
1384 | + * @param EE_Base_Class|int|string $otherObjectModelObjectOrID |
|
1385 | + * @param string $relationName |
|
1386 | + * @param array $extra_join_model_fields_n_values |
|
1387 | + * @param string|null $cache_id |
|
1388 | + * @return EE_Base_Class |
|
1389 | + * @throws EE_Error |
|
1390 | + * @throws ReflectionException |
|
1391 | + * @since $VID:$ |
|
1392 | + */ |
|
1393 | + public function _add_relation_to( |
|
1394 | + $otherObjectModelObjectOrID, |
|
1395 | + $relationName, |
|
1396 | + $extra_join_model_fields_n_values = [], |
|
1397 | + $cache_id = null |
|
1398 | + ) { |
|
1399 | + // if we're adding a new relation to a ticket |
|
1400 | + if ($relationName === 'Ticket' && ! $this->hasRelation($otherObjectModelObjectOrID, $relationName)) { |
|
1401 | + /** @var EE_Ticket $ticket */ |
|
1402 | + $ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID); |
|
1403 | + $this->increaseSold($ticket->sold(), false); |
|
1404 | + $this->increaseReserved($ticket->reserved()); |
|
1405 | + $this->save(); |
|
1406 | + $otherObjectModelObjectOrID = $ticket; |
|
1407 | + } |
|
1408 | + return parent::_add_relation_to( |
|
1409 | + $otherObjectModelObjectOrID, |
|
1410 | + $relationName, |
|
1411 | + $extra_join_model_fields_n_values, |
|
1412 | + $cache_id |
|
1413 | + ); |
|
1414 | + } |
|
1415 | + |
|
1416 | + |
|
1417 | + /** |
|
1418 | + * @param EE_Base_Class|int|string $otherObjectModelObjectOrID |
|
1419 | + * @param string $relationName |
|
1420 | + * @param array $where_query |
|
1421 | + * @return bool|EE_Base_Class|null |
|
1422 | + * @throws EE_Error |
|
1423 | + * @throws ReflectionException |
|
1424 | + * @since $VID:$ |
|
1425 | + */ |
|
1426 | + public function _remove_relation_to($otherObjectModelObjectOrID, $relationName, $where_query = []) |
|
1427 | + { |
|
1428 | + if ($relationName === 'Ticket' && $this->hasRelation($otherObjectModelObjectOrID, $relationName)) { |
|
1429 | + /** @var EE_Ticket $ticket */ |
|
1430 | + $ticket = EEM_Ticket::instance()->ensure_is_obj($otherObjectModelObjectOrID); |
|
1431 | + $this->decreaseSold($ticket->sold()); |
|
1432 | + $this->decreaseReserved($ticket->reserved()); |
|
1433 | + $this->save(); |
|
1434 | + $otherObjectModelObjectOrID = $ticket; |
|
1435 | + } |
|
1436 | + return parent::_remove_relation_to( |
|
1437 | + $otherObjectModelObjectOrID, |
|
1438 | + $relationName, |
|
1439 | + $where_query |
|
1440 | + ); |
|
1441 | + } |
|
1442 | + |
|
1443 | + |
|
1444 | + /** |
|
1445 | + * Removes ALL the related things for the $relationName. |
|
1446 | + * |
|
1447 | + * @param string $relationName |
|
1448 | + * @param array $where_query_params |
|
1449 | + * @return EE_Base_Class |
|
1450 | + * @throws ReflectionException |
|
1451 | + * @throws InvalidArgumentException |
|
1452 | + * @throws InvalidInterfaceException |
|
1453 | + * @throws InvalidDataTypeException |
|
1454 | + * @throws EE_Error |
|
1455 | + * @see https://github.com/eventespresso/event-espresso-core/tree/master/docs/G--Model-System/model-query-params.md#0-where-conditions |
|
1456 | + */ |
|
1457 | + public function _remove_relations($relationName, $where_query_params = []) |
|
1458 | + { |
|
1459 | + if ($relationName === 'Ticket') { |
|
1460 | + $tickets = $this->tickets(); |
|
1461 | + foreach ($tickets as $ticket) { |
|
1462 | + $this->decreaseSold($ticket->sold()); |
|
1463 | + $this->decreaseReserved($ticket->reserved()); |
|
1464 | + $this->save(); |
|
1465 | + } |
|
1466 | + } |
|
1467 | + return parent::_remove_relations($relationName, $where_query_params); |
|
1468 | + } |
|
1469 | + |
|
1470 | + |
|
1471 | + /******************************************************************* |
|
1472 | 1472 | *********************** DEPRECATED METHODS ********************** |
1473 | 1473 | *******************************************************************/ |
1474 | 1474 | |
1475 | 1475 | |
1476 | - /** |
|
1477 | - * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
1478 | - * |
|
1479 | - * @deprecated 4.9.80.p |
|
1480 | - * @param int $qty |
|
1481 | - * @return boolean |
|
1482 | - * @throws ReflectionException |
|
1483 | - * @throws InvalidArgumentException |
|
1484 | - * @throws InvalidInterfaceException |
|
1485 | - * @throws InvalidDataTypeException |
|
1486 | - * @throws EE_Error |
|
1487 | - */ |
|
1488 | - public function increase_sold($qty = 1) |
|
1489 | - { |
|
1490 | - EE_Error::doing_it_wrong( |
|
1491 | - __FUNCTION__, |
|
1492 | - esc_html__('Please use EE_Datetime::increaseSold() instead', 'event_espresso'), |
|
1493 | - '4.9.80.p', |
|
1494 | - '5.0.0.p' |
|
1495 | - ); |
|
1496 | - return $this->increaseSold($qty); |
|
1497 | - } |
|
1498 | - |
|
1499 | - |
|
1500 | - /** |
|
1501 | - * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
1502 | - * to save afterwards.) |
|
1503 | - * |
|
1504 | - * @deprecated 4.9.80.p |
|
1505 | - * @param int $qty |
|
1506 | - * @return boolean |
|
1507 | - * @throws ReflectionException |
|
1508 | - * @throws InvalidArgumentException |
|
1509 | - * @throws InvalidInterfaceException |
|
1510 | - * @throws InvalidDataTypeException |
|
1511 | - * @throws EE_Error |
|
1512 | - */ |
|
1513 | - public function decrease_sold($qty = 1) |
|
1514 | - { |
|
1515 | - EE_Error::doing_it_wrong( |
|
1516 | - __FUNCTION__, |
|
1517 | - esc_html__('Please use EE_Datetime::decreaseSold() instead', 'event_espresso'), |
|
1518 | - '4.9.80.p', |
|
1519 | - '5.0.0.p' |
|
1520 | - ); |
|
1521 | - return $this->decreaseSold($qty); |
|
1522 | - } |
|
1523 | - |
|
1524 | - |
|
1525 | - /** |
|
1526 | - * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
1527 | - * |
|
1528 | - * @deprecated 4.9.80.p |
|
1529 | - * @param int $qty |
|
1530 | - * @return boolean indicating success |
|
1531 | - * @throws ReflectionException |
|
1532 | - * @throws InvalidArgumentException |
|
1533 | - * @throws InvalidInterfaceException |
|
1534 | - * @throws InvalidDataTypeException |
|
1535 | - * @throws EE_Error |
|
1536 | - */ |
|
1537 | - public function increase_reserved($qty = 1) |
|
1538 | - { |
|
1539 | - EE_Error::doing_it_wrong( |
|
1540 | - __FUNCTION__, |
|
1541 | - esc_html__('Please use EE_Datetime::increaseReserved() instead', 'event_espresso'), |
|
1542 | - '4.9.80.p', |
|
1543 | - '5.0.0.p' |
|
1544 | - ); |
|
1545 | - return $this->increaseReserved($qty); |
|
1546 | - } |
|
1547 | - |
|
1548 | - |
|
1549 | - /** |
|
1550 | - * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
1551 | - * |
|
1552 | - * @deprecated 4.9.80.p |
|
1553 | - * @param int $qty |
|
1554 | - * @return boolean |
|
1555 | - * @throws ReflectionException |
|
1556 | - * @throws InvalidArgumentException |
|
1557 | - * @throws InvalidInterfaceException |
|
1558 | - * @throws InvalidDataTypeException |
|
1559 | - * @throws EE_Error |
|
1560 | - */ |
|
1561 | - public function decrease_reserved($qty = 1) |
|
1562 | - { |
|
1563 | - EE_Error::doing_it_wrong( |
|
1564 | - __FUNCTION__, |
|
1565 | - esc_html__('Please use EE_Datetime::decreaseReserved() instead', 'event_espresso'), |
|
1566 | - '4.9.80.p', |
|
1567 | - '5.0.0.p' |
|
1568 | - ); |
|
1569 | - return $this->decreaseReserved($qty); |
|
1570 | - } |
|
1476 | + /** |
|
1477 | + * Increments sold by amount passed by $qty, and persists it immediately to the database. |
|
1478 | + * |
|
1479 | + * @deprecated 4.9.80.p |
|
1480 | + * @param int $qty |
|
1481 | + * @return boolean |
|
1482 | + * @throws ReflectionException |
|
1483 | + * @throws InvalidArgumentException |
|
1484 | + * @throws InvalidInterfaceException |
|
1485 | + * @throws InvalidDataTypeException |
|
1486 | + * @throws EE_Error |
|
1487 | + */ |
|
1488 | + public function increase_sold($qty = 1) |
|
1489 | + { |
|
1490 | + EE_Error::doing_it_wrong( |
|
1491 | + __FUNCTION__, |
|
1492 | + esc_html__('Please use EE_Datetime::increaseSold() instead', 'event_espresso'), |
|
1493 | + '4.9.80.p', |
|
1494 | + '5.0.0.p' |
|
1495 | + ); |
|
1496 | + return $this->increaseSold($qty); |
|
1497 | + } |
|
1498 | + |
|
1499 | + |
|
1500 | + /** |
|
1501 | + * Decrements (subtracts) sold amount passed by $qty directly in the DB and on the model object. (Ie, no need |
|
1502 | + * to save afterwards.) |
|
1503 | + * |
|
1504 | + * @deprecated 4.9.80.p |
|
1505 | + * @param int $qty |
|
1506 | + * @return boolean |
|
1507 | + * @throws ReflectionException |
|
1508 | + * @throws InvalidArgumentException |
|
1509 | + * @throws InvalidInterfaceException |
|
1510 | + * @throws InvalidDataTypeException |
|
1511 | + * @throws EE_Error |
|
1512 | + */ |
|
1513 | + public function decrease_sold($qty = 1) |
|
1514 | + { |
|
1515 | + EE_Error::doing_it_wrong( |
|
1516 | + __FUNCTION__, |
|
1517 | + esc_html__('Please use EE_Datetime::decreaseSold() instead', 'event_espresso'), |
|
1518 | + '4.9.80.p', |
|
1519 | + '5.0.0.p' |
|
1520 | + ); |
|
1521 | + return $this->decreaseSold($qty); |
|
1522 | + } |
|
1523 | + |
|
1524 | + |
|
1525 | + /** |
|
1526 | + * Increments reserved by amount passed by $qty, and persists it immediately to the database. |
|
1527 | + * |
|
1528 | + * @deprecated 4.9.80.p |
|
1529 | + * @param int $qty |
|
1530 | + * @return boolean indicating success |
|
1531 | + * @throws ReflectionException |
|
1532 | + * @throws InvalidArgumentException |
|
1533 | + * @throws InvalidInterfaceException |
|
1534 | + * @throws InvalidDataTypeException |
|
1535 | + * @throws EE_Error |
|
1536 | + */ |
|
1537 | + public function increase_reserved($qty = 1) |
|
1538 | + { |
|
1539 | + EE_Error::doing_it_wrong( |
|
1540 | + __FUNCTION__, |
|
1541 | + esc_html__('Please use EE_Datetime::increaseReserved() instead', 'event_espresso'), |
|
1542 | + '4.9.80.p', |
|
1543 | + '5.0.0.p' |
|
1544 | + ); |
|
1545 | + return $this->increaseReserved($qty); |
|
1546 | + } |
|
1547 | + |
|
1548 | + |
|
1549 | + /** |
|
1550 | + * Decrements (subtracts) reserved by amount passed by $qty, and persists it immediately to the database. |
|
1551 | + * |
|
1552 | + * @deprecated 4.9.80.p |
|
1553 | + * @param int $qty |
|
1554 | + * @return boolean |
|
1555 | + * @throws ReflectionException |
|
1556 | + * @throws InvalidArgumentException |
|
1557 | + * @throws InvalidInterfaceException |
|
1558 | + * @throws InvalidDataTypeException |
|
1559 | + * @throws EE_Error |
|
1560 | + */ |
|
1561 | + public function decrease_reserved($qty = 1) |
|
1562 | + { |
|
1563 | + EE_Error::doing_it_wrong( |
|
1564 | + __FUNCTION__, |
|
1565 | + esc_html__('Please use EE_Datetime::decreaseReserved() instead', 'event_espresso'), |
|
1566 | + '4.9.80.p', |
|
1567 | + '5.0.0.p' |
|
1568 | + ); |
|
1569 | + return $this->decreaseReserved($qty); |
|
1570 | + } |
|
1571 | 1571 | } |
@@ -17,271 +17,271 @@ |
||
17 | 17 | */ |
18 | 18 | abstract class JobHandler implements JobHandlerInterface |
19 | 19 | { |
20 | - /** |
|
21 | - * @var array |
|
22 | - */ |
|
23 | - protected $feedback = []; |
|
24 | - |
|
25 | - /** |
|
26 | - * incoming Request data |
|
27 | - * |
|
28 | - * @var array |
|
29 | - */ |
|
30 | - protected $request_data = []; |
|
31 | - |
|
32 | - /** |
|
33 | - * Extra data to include as part of the response, literally gets set as JobStepResponse::$_extra_data |
|
34 | - * |
|
35 | - * @var array |
|
36 | - */ |
|
37 | - protected $response_data = []; |
|
38 | - |
|
39 | - |
|
40 | - /** |
|
41 | - * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
42 | - * Performs any necessary setup for starting the job. This is also a good |
|
43 | - * place to setup the $job_arguments which will be used for subsequent HTTP requests |
|
44 | - * when continue_job will be called |
|
45 | - * |
|
46 | - * @param JobParameters $job_parameters |
|
47 | - * @return JobStepResponse |
|
48 | - * @throws BatchRequestException |
|
49 | - * @since $VID:$ |
|
50 | - */ |
|
51 | - public function createJob(JobParameters $job_parameters): JobStepResponse |
|
52 | - { |
|
53 | - return $this->create_job($job_parameters); |
|
54 | - } |
|
55 | - |
|
56 | - |
|
57 | - /** |
|
58 | - * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
59 | - * Performs another step of the job |
|
60 | - * |
|
61 | - * @param JobParameters $job_parameters |
|
62 | - * @param int $batch_size |
|
63 | - * @return JobStepResponse |
|
64 | - * @throws BatchRequestException |
|
65 | - * @since $VID:$ |
|
66 | - */ |
|
67 | - public function continueJob(JobParameters $job_parameters, int $batch_size = 50): JobStepResponse |
|
68 | - { |
|
69 | - return $this->continue_job($job_parameters, $batch_size); |
|
70 | - } |
|
71 | - |
|
72 | - |
|
73 | - /** |
|
74 | - * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
75 | - * used to advance from one batch job to another |
|
76 | - * primarily used for executing a job assessment phase where an accurate count of items to update can be made, |
|
77 | - * followed by the actual update job. |
|
78 | - * |
|
79 | - * @param JobParameters $job_parameters |
|
80 | - * @return JobStepResponse |
|
81 | - * @since $VID:$ |
|
82 | - */ |
|
83 | - public function advanceJob(JobParameters $job_parameters): JobStepResponse |
|
84 | - { |
|
85 | - return $this->advance_job($job_parameters); |
|
86 | - } |
|
87 | - |
|
88 | - // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
89 | - /** |
|
90 | - * used to advance from one batch job to another |
|
91 | - * primarily used for executing a job assessment phase where an accurate count of items to update can be made, |
|
92 | - * followed by the actual update job. |
|
93 | - * By default, this function won't do anything until overridden in a chile class. |
|
94 | - * |
|
95 | - * @param JobParameters $job_parameters |
|
96 | - * @return JobStepResponse |
|
97 | - * @since $VID:$ |
|
98 | - */ |
|
99 | - public function advance_job(JobParameters $job_parameters): JobStepResponse |
|
100 | - { |
|
101 | - $job_parameters->set_status(JobParameters::status_continue); |
|
102 | - return new JobStepResponse($job_parameters, $this->feedback); |
|
103 | - } |
|
104 | - |
|
105 | - |
|
106 | - /** |
|
107 | - * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
108 | - * Performs any clean-up logic when we know the job is completed |
|
109 | - * |
|
110 | - * @param JobParameters $job_parameters |
|
111 | - * @return JobStepResponse |
|
112 | - * @throws BatchRequestException |
|
113 | - * @since $VID:$ |
|
114 | - */ |
|
115 | - public function cleanupJob(JobParameters $job_parameters): JobStepResponse |
|
116 | - { |
|
117 | - return $this->cleanup_job($job_parameters); |
|
118 | - } |
|
119 | - |
|
120 | - |
|
121 | - /** |
|
122 | - * @return array |
|
123 | - */ |
|
124 | - public function requestData(): array |
|
125 | - { |
|
126 | - return $this->request_data; |
|
127 | - } |
|
128 | - |
|
129 | - |
|
130 | - /** |
|
131 | - * @return mixed |
|
132 | - */ |
|
133 | - public function getRequestData($key) |
|
134 | - { |
|
135 | - return $this->request_data[ $key ] ?? null; |
|
136 | - } |
|
137 | - |
|
138 | - |
|
139 | - /** |
|
140 | - * @param array $request_data |
|
141 | - */ |
|
142 | - public function setRequestData(array $request_data): void |
|
143 | - { |
|
144 | - $this->request_data = $request_data; |
|
145 | - } |
|
146 | - |
|
147 | - |
|
148 | - /** |
|
149 | - * @return array |
|
150 | - */ |
|
151 | - public function responseData(): array |
|
152 | - { |
|
153 | - return $this->response_data; |
|
154 | - } |
|
155 | - |
|
156 | - |
|
157 | - /** |
|
158 | - * @param array $response_data |
|
159 | - */ |
|
160 | - public function addResponseData(array $response_data): void |
|
161 | - { |
|
162 | - $this->response_data += $response_data; |
|
163 | - } |
|
164 | - |
|
165 | - |
|
166 | - |
|
167 | - /** |
|
168 | - * @param array $response_data |
|
169 | - */ |
|
170 | - public function setResponseData(array $response_data): void |
|
171 | - { |
|
172 | - $this->response_data = $response_data; |
|
173 | - } |
|
174 | - |
|
175 | - |
|
176 | - |
|
177 | - |
|
178 | - protected function displayJobStepResults(int $processed, string $custom_message = '') |
|
179 | - { |
|
180 | - $this->feedback[] = ' |
|
20 | + /** |
|
21 | + * @var array |
|
22 | + */ |
|
23 | + protected $feedback = []; |
|
24 | + |
|
25 | + /** |
|
26 | + * incoming Request data |
|
27 | + * |
|
28 | + * @var array |
|
29 | + */ |
|
30 | + protected $request_data = []; |
|
31 | + |
|
32 | + /** |
|
33 | + * Extra data to include as part of the response, literally gets set as JobStepResponse::$_extra_data |
|
34 | + * |
|
35 | + * @var array |
|
36 | + */ |
|
37 | + protected $response_data = []; |
|
38 | + |
|
39 | + |
|
40 | + /** |
|
41 | + * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
42 | + * Performs any necessary setup for starting the job. This is also a good |
|
43 | + * place to setup the $job_arguments which will be used for subsequent HTTP requests |
|
44 | + * when continue_job will be called |
|
45 | + * |
|
46 | + * @param JobParameters $job_parameters |
|
47 | + * @return JobStepResponse |
|
48 | + * @throws BatchRequestException |
|
49 | + * @since $VID:$ |
|
50 | + */ |
|
51 | + public function createJob(JobParameters $job_parameters): JobStepResponse |
|
52 | + { |
|
53 | + return $this->create_job($job_parameters); |
|
54 | + } |
|
55 | + |
|
56 | + |
|
57 | + /** |
|
58 | + * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
59 | + * Performs another step of the job |
|
60 | + * |
|
61 | + * @param JobParameters $job_parameters |
|
62 | + * @param int $batch_size |
|
63 | + * @return JobStepResponse |
|
64 | + * @throws BatchRequestException |
|
65 | + * @since $VID:$ |
|
66 | + */ |
|
67 | + public function continueJob(JobParameters $job_parameters, int $batch_size = 50): JobStepResponse |
|
68 | + { |
|
69 | + return $this->continue_job($job_parameters, $batch_size); |
|
70 | + } |
|
71 | + |
|
72 | + |
|
73 | + /** |
|
74 | + * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
75 | + * used to advance from one batch job to another |
|
76 | + * primarily used for executing a job assessment phase where an accurate count of items to update can be made, |
|
77 | + * followed by the actual update job. |
|
78 | + * |
|
79 | + * @param JobParameters $job_parameters |
|
80 | + * @return JobStepResponse |
|
81 | + * @since $VID:$ |
|
82 | + */ |
|
83 | + public function advanceJob(JobParameters $job_parameters): JobStepResponse |
|
84 | + { |
|
85 | + return $this->advance_job($job_parameters); |
|
86 | + } |
|
87 | + |
|
88 | + // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps |
|
89 | + /** |
|
90 | + * used to advance from one batch job to another |
|
91 | + * primarily used for executing a job assessment phase where an accurate count of items to update can be made, |
|
92 | + * followed by the actual update job. |
|
93 | + * By default, this function won't do anything until overridden in a chile class. |
|
94 | + * |
|
95 | + * @param JobParameters $job_parameters |
|
96 | + * @return JobStepResponse |
|
97 | + * @since $VID:$ |
|
98 | + */ |
|
99 | + public function advance_job(JobParameters $job_parameters): JobStepResponse |
|
100 | + { |
|
101 | + $job_parameters->set_status(JobParameters::status_continue); |
|
102 | + return new JobStepResponse($job_parameters, $this->feedback); |
|
103 | + } |
|
104 | + |
|
105 | + |
|
106 | + /** |
|
107 | + * utilized in newer batch job implementations, but forwarding to existing methods for now. |
|
108 | + * Performs any clean-up logic when we know the job is completed |
|
109 | + * |
|
110 | + * @param JobParameters $job_parameters |
|
111 | + * @return JobStepResponse |
|
112 | + * @throws BatchRequestException |
|
113 | + * @since $VID:$ |
|
114 | + */ |
|
115 | + public function cleanupJob(JobParameters $job_parameters): JobStepResponse |
|
116 | + { |
|
117 | + return $this->cleanup_job($job_parameters); |
|
118 | + } |
|
119 | + |
|
120 | + |
|
121 | + /** |
|
122 | + * @return array |
|
123 | + */ |
|
124 | + public function requestData(): array |
|
125 | + { |
|
126 | + return $this->request_data; |
|
127 | + } |
|
128 | + |
|
129 | + |
|
130 | + /** |
|
131 | + * @return mixed |
|
132 | + */ |
|
133 | + public function getRequestData($key) |
|
134 | + { |
|
135 | + return $this->request_data[ $key ] ?? null; |
|
136 | + } |
|
137 | + |
|
138 | + |
|
139 | + /** |
|
140 | + * @param array $request_data |
|
141 | + */ |
|
142 | + public function setRequestData(array $request_data): void |
|
143 | + { |
|
144 | + $this->request_data = $request_data; |
|
145 | + } |
|
146 | + |
|
147 | + |
|
148 | + /** |
|
149 | + * @return array |
|
150 | + */ |
|
151 | + public function responseData(): array |
|
152 | + { |
|
153 | + return $this->response_data; |
|
154 | + } |
|
155 | + |
|
156 | + |
|
157 | + /** |
|
158 | + * @param array $response_data |
|
159 | + */ |
|
160 | + public function addResponseData(array $response_data): void |
|
161 | + { |
|
162 | + $this->response_data += $response_data; |
|
163 | + } |
|
164 | + |
|
165 | + |
|
166 | + |
|
167 | + /** |
|
168 | + * @param array $response_data |
|
169 | + */ |
|
170 | + public function setResponseData(array $response_data): void |
|
171 | + { |
|
172 | + $this->response_data = $response_data; |
|
173 | + } |
|
174 | + |
|
175 | + |
|
176 | + |
|
177 | + |
|
178 | + protected function displayJobStepResults(int $processed, string $custom_message = '') |
|
179 | + { |
|
180 | + $this->feedback[] = ' |
|
181 | 181 | <div class="ee-batch-job-step-results"> |
182 | 182 | ' . $this->infoWrapper( |
183 | - sprintf( |
|
184 | - $custom_message !== '' |
|
185 | - ? $custom_message |
|
186 | - : esc_html__('processed this batch: %d', 'event_espresso'), |
|
187 | - $processed |
|
188 | - ) |
|
189 | - ) . ' |
|
183 | + sprintf( |
|
184 | + $custom_message !== '' |
|
185 | + ? $custom_message |
|
186 | + : esc_html__('processed this batch: %d', 'event_espresso'), |
|
187 | + $processed |
|
188 | + ) |
|
189 | + ) . ' |
|
190 | 190 | </div>'; |
191 | - } |
|
191 | + } |
|
192 | 192 | |
193 | 193 | |
194 | - protected function displayJobFinalResults(JobParameters $job_parameters, string $custom_message = '') |
|
195 | - { |
|
196 | - if ($job_parameters->status() === JobParameters::status_complete) { |
|
197 | - $this->feedback[] = ' |
|
194 | + protected function displayJobFinalResults(JobParameters $job_parameters, string $custom_message = '') |
|
195 | + { |
|
196 | + if ($job_parameters->status() === JobParameters::status_complete) { |
|
197 | + $this->feedback[] = ' |
|
198 | 198 | <div class="ee-batch-job-final-results"> |
199 | 199 | ' . $this->okWrapper( |
200 | - sprintf( |
|
201 | - $custom_message !== '' |
|
202 | - ? $custom_message |
|
203 | - : esc_html__('total units processed: %d', 'event_espresso'), |
|
204 | - $job_parameters->units_processed() |
|
205 | - ) |
|
206 | - ) . ' |
|
200 | + sprintf( |
|
201 | + $custom_message !== '' |
|
202 | + ? $custom_message |
|
203 | + : esc_html__('total units processed: %d', 'event_espresso'), |
|
204 | + $job_parameters->units_processed() |
|
205 | + ) |
|
206 | + ) . ' |
|
207 | 207 | ' . $this->jobStatusNotice($job_parameters) . ' |
208 | 208 | </div>'; |
209 | - } |
|
210 | - } |
|
209 | + } |
|
210 | + } |
|
211 | 211 | |
212 | 212 | |
213 | - protected function jobStatusNotice(JobParameters $job_parameters): string |
|
214 | - { |
|
215 | - switch ($job_parameters->status()) { |
|
216 | - case JobParameters::status_cleaned_up: |
|
217 | - case JobParameters::status_continue: |
|
218 | - case JobParameters::status_pause: |
|
219 | - break; |
|
220 | - case JobParameters::status_complete: |
|
221 | - return $this->successWrapper('job status: COMPLETE'); |
|
222 | - case JobParameters::status_error: |
|
223 | - return $this->errorWrapper('job status: ERROR'); |
|
224 | - } |
|
225 | - return ''; |
|
226 | - } |
|
213 | + protected function jobStatusNotice(JobParameters $job_parameters): string |
|
214 | + { |
|
215 | + switch ($job_parameters->status()) { |
|
216 | + case JobParameters::status_cleaned_up: |
|
217 | + case JobParameters::status_continue: |
|
218 | + case JobParameters::status_pause: |
|
219 | + break; |
|
220 | + case JobParameters::status_complete: |
|
221 | + return $this->successWrapper('job status: COMPLETE'); |
|
222 | + case JobParameters::status_error: |
|
223 | + return $this->errorWrapper('job status: ERROR'); |
|
224 | + } |
|
225 | + return ''; |
|
226 | + } |
|
227 | 227 | |
228 | 228 | |
229 | - /** |
|
230 | - * @param string $update_text |
|
231 | - */ |
|
232 | - protected function updateText(string $update_text) |
|
233 | - { |
|
234 | - $this->feedback[] = "<p class='ee-batch-job-update'>$update_text</p>"; |
|
235 | - } |
|
229 | + /** |
|
230 | + * @param string $update_text |
|
231 | + */ |
|
232 | + protected function updateText(string $update_text) |
|
233 | + { |
|
234 | + $this->feedback[] = "<p class='ee-batch-job-update'>$update_text</p>"; |
|
235 | + } |
|
236 | 236 | |
237 | 237 | |
238 | - protected function updateTextHeader(string $update_text) |
|
239 | - { |
|
240 | - $this->feedback[] = "<h4 class='ee-batch-job-update-heading'>$update_text</h4>"; |
|
241 | - } |
|
238 | + protected function updateTextHeader(string $update_text) |
|
239 | + { |
|
240 | + $this->feedback[] = "<h4 class='ee-batch-job-update-heading'>$update_text</h4>"; |
|
241 | + } |
|
242 | 242 | |
243 | 243 | |
244 | - protected function attentionWrapper(string $update_text): string |
|
245 | - { |
|
246 | - return "<span class='ee-status-outline ee-status-bg--attention'>$update_text</span>"; |
|
247 | - } |
|
244 | + protected function attentionWrapper(string $update_text): string |
|
245 | + { |
|
246 | + return "<span class='ee-status-outline ee-status-bg--attention'>$update_text</span>"; |
|
247 | + } |
|
248 | 248 | |
249 | 249 | |
250 | - protected function errorWrapper(string $update_text): string |
|
251 | - { |
|
252 | - return "<span class='ee-status-outline ee-status-bg--error'>$update_text</span>"; |
|
253 | - } |
|
250 | + protected function errorWrapper(string $update_text): string |
|
251 | + { |
|
252 | + return "<span class='ee-status-outline ee-status-bg--error'>$update_text</span>"; |
|
253 | + } |
|
254 | 254 | |
255 | 255 | |
256 | - protected function infoWrapper(string $update_text): string |
|
257 | - { |
|
258 | - return "<span class='ee-status-outline ee-status-bg--info'>$update_text</span>"; |
|
259 | - } |
|
256 | + protected function infoWrapper(string $update_text): string |
|
257 | + { |
|
258 | + return "<span class='ee-status-outline ee-status-bg--info'>$update_text</span>"; |
|
259 | + } |
|
260 | 260 | |
261 | 261 | |
262 | - protected function okWrapper(string $update_text): string |
|
263 | - { |
|
264 | - return "<span class='ee-status-outline ee-status-bg--ok'>$update_text</span>"; |
|
265 | - } |
|
262 | + protected function okWrapper(string $update_text): string |
|
263 | + { |
|
264 | + return "<span class='ee-status-outline ee-status-bg--ok'>$update_text</span>"; |
|
265 | + } |
|
266 | 266 | |
267 | 267 | |
268 | - protected function successWrapper(string $update_text): string |
|
269 | - { |
|
270 | - return "<span class='ee-status-outline ee-status-bg--success'>$update_text</span>"; |
|
271 | - } |
|
268 | + protected function successWrapper(string $update_text): string |
|
269 | + { |
|
270 | + return "<span class='ee-status-outline ee-status-bg--success'>$update_text</span>"; |
|
271 | + } |
|
272 | 272 | |
273 | 273 | |
274 | - protected function warningWrapper(string $update_text): string |
|
275 | - { |
|
276 | - return "<span class='ee-status-outline ee-status-bg--warning'>$update_text</span>"; |
|
277 | - } |
|
274 | + protected function warningWrapper(string $update_text): string |
|
275 | + { |
|
276 | + return "<span class='ee-status-outline ee-status-bg--warning'>$update_text</span>"; |
|
277 | + } |
|
278 | 278 | |
279 | 279 | |
280 | - /** |
|
281 | - * @return string |
|
282 | - */ |
|
283 | - protected function spinner(): string |
|
284 | - { |
|
285 | - return '<span class="spinner"></span>'; |
|
286 | - } |
|
280 | + /** |
|
281 | + * @return string |
|
282 | + */ |
|
283 | + protected function spinner(): string |
|
284 | + { |
|
285 | + return '<span class="spinner"></span>'; |
|
286 | + } |
|
287 | 287 | } |