Completed
Branch master (87d3f3)
by
unknown
03:30
created
core/admin/EE_Admin_Page_Sub_Menu.core.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -12,12 +12,12 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
caffeinated/admin/new/pricing/Pricing_Admin_Page_Init.core.php 1 patch
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -16,51 +16,51 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
core/services/assets/AssetManager.php 1 patch
Indentation   +323 added lines, -323 removed lines patch added patch discarded remove patch
@@ -23,332 +23,332 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
core/services/assets/Registry.php 1 patch
Indentation   +570 added lines, -570 removed lines patch added patch discarded remove patch
@@ -25,581 +25,581 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Init.core.php 1 patch
Indentation   +490 added lines, -490 removed lines patch added patch discarded remove patch
@@ -18,497 +18,497 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Loader.core.php 1 patch
Indentation   +433 added lines, -433 removed lines patch added patch discarded remove patch
@@ -16,437 +16,437 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
core/domain/services/graphql/types/Event.php 1 patch
Indentation   +217 added lines, -217 removed lines patch added patch discarded remove patch
@@ -24,225 +24,225 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.
core/db_classes/EE_Datetime.class.php 1 patch
Indentation   +1552 added lines, -1552 removed lines patch added patch discarded remove patch
@@ -12,1560 +12,1560 @@
 block discarded – undo
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
-            '&nbsp;',
630
-            $this->get_i18n_datetime('DTT_EVT_start', $dt_frmt)
631
-        );
632
-        $end = str_replace(
633
-            ' ',
634
-            '&nbsp;',
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
-            '&nbsp;',
738
-            $this->get_i18n_datetime('DTT_EVT_start', $tm_format)
739
-        );
740
-        $end = str_replace(
741
-            ' ',
742
-            '&nbsp;',
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
+			'&nbsp;',
630
+			$this->get_i18n_datetime('DTT_EVT_start', $dt_frmt)
631
+		);
632
+		$end = str_replace(
633
+			' ',
634
+			'&nbsp;',
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
+			'&nbsp;',
738
+			$this->get_i18n_datetime('DTT_EVT_start', $tm_format)
739
+		);
740
+		$end = str_replace(
741
+			' ',
742
+			'&nbsp;',
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
 }
Please login to merge, or discard this patch.
core/libraries/batch/JobHandlerBaseClasses/JobHandler.php 1 patch
Indentation   +238 added lines, -238 removed lines patch added patch discarded remove patch
@@ -17,271 +17,271 @@
 block discarded – undo
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
 }
Please login to merge, or discard this patch.