Completed
Branch EDTR/refactor-master (7fdaf0)
by
unknown
17:48 queued 09:57
created
core/domain/services/assets/EspressoEditorAssetManager.php 1 patch
Indentation   +38 added lines, -38 removed lines patch added patch discarded remove patch
@@ -19,47 +19,47 @@
 block discarded – undo
19 19
  */
20 20
 class EspressoEditorAssetManager extends AssetManager
21 21
 {
22
-    const JS_HANDLE_EDITOR = 'eventespresso-editor';
23
-    const CSS_HANDLE_EDITOR = 'eventespresso-editor';
24
-    const JS_HANDLE_EDITOR_HOCS = 'eventespresso-editor-hocs';
25
-    const CSS_HANDLE_EDITOR_HOCS = 'eventespresso-editor-hocs';
22
+	const JS_HANDLE_EDITOR = 'eventespresso-editor';
23
+	const CSS_HANDLE_EDITOR = 'eventespresso-editor';
24
+	const JS_HANDLE_EDITOR_HOCS = 'eventespresso-editor-hocs';
25
+	const CSS_HANDLE_EDITOR_HOCS = 'eventespresso-editor-hocs';
26 26
 
27
-    /**
28
-     * @throws InvalidDataTypeException
29
-     * @throws InvalidEntityException
30
-     * @throws DuplicateCollectionIdentifierException
31
-     */
32
-    public function addAssets()
33
-    {
34
-        $this->registerJavascript();
35
-        $this->registerStyleSheets();
36
-    }
27
+	/**
28
+	 * @throws InvalidDataTypeException
29
+	 * @throws InvalidEntityException
30
+	 * @throws DuplicateCollectionIdentifierException
31
+	 */
32
+	public function addAssets()
33
+	{
34
+		$this->registerJavascript();
35
+		$this->registerStyleSheets();
36
+	}
37 37
 
38 38
 
39
-    /**
40
-     * Register javascript assets
41
-     *
42
-     * @throws InvalidDataTypeException
43
-     * @throws InvalidEntityException
44
-     * @throws DuplicateCollectionIdentifierException
45
-     */
46
-    private function registerJavascript()
47
-    {
48
-        $this->addJs(self::JS_HANDLE_EDITOR)->setRequiresTranslation();
49
-        $this->addJs(self::JS_HANDLE_EDITOR_HOCS)->setRequiresTranslation();
50
-    }
39
+	/**
40
+	 * Register javascript assets
41
+	 *
42
+	 * @throws InvalidDataTypeException
43
+	 * @throws InvalidEntityException
44
+	 * @throws DuplicateCollectionIdentifierException
45
+	 */
46
+	private function registerJavascript()
47
+	{
48
+		$this->addJs(self::JS_HANDLE_EDITOR)->setRequiresTranslation();
49
+		$this->addJs(self::JS_HANDLE_EDITOR_HOCS)->setRequiresTranslation();
50
+	}
51 51
 
52 52
 
53
-    /**
54
-     * Register CSS assets.
55
-     *
56
-     * @throws DuplicateCollectionIdentifierException
57
-     * @throws InvalidDataTypeException
58
-     * @throws InvalidEntityException
59
-     */
60
-    private function registerStyleSheets()
61
-    {
62
-        $this->addCss(self::CSS_HANDLE_EDITOR);
63
-        $this->addCss(self::CSS_HANDLE_EDITOR_HOCS);
64
-    }
53
+	/**
54
+	 * Register CSS assets.
55
+	 *
56
+	 * @throws DuplicateCollectionIdentifierException
57
+	 * @throws InvalidDataTypeException
58
+	 * @throws InvalidEntityException
59
+	 */
60
+	private function registerStyleSheets()
61
+	{
62
+		$this->addCss(self::CSS_HANDLE_EDITOR);
63
+		$this->addCss(self::CSS_HANDLE_EDITOR_HOCS);
64
+	}
65 65
 }
Please login to merge, or discard this patch.
core/domain/services/assets/CoreAssetManager.php 2 patches
Indentation   +434 added lines, -434 removed lines patch added patch discarded remove patch
@@ -32,462 +32,462 @@
 block discarded – undo
32 32
 class CoreAssetManager extends AssetManager
33 33
 {
34 34
 
35
-    // WordPress core / Third party JS asset handles
36
-    const JS_HANDLE_JQUERY = 'jquery';
35
+	// WordPress core / Third party JS asset handles
36
+	const JS_HANDLE_JQUERY = 'jquery';
37 37
 
38
-    const JS_HANDLE_JQUERY_VALIDATE = 'jquery-validate';
38
+	const JS_HANDLE_JQUERY_VALIDATE = 'jquery-validate';
39 39
 
40
-    const JS_HANDLE_JQUERY_VALIDATE_EXTRA = 'jquery-validate-extra-methods';
40
+	const JS_HANDLE_JQUERY_VALIDATE_EXTRA = 'jquery-validate-extra-methods';
41 41
 
42
-    const JS_HANDLE_UNDERSCORE = 'underscore';
42
+	const JS_HANDLE_UNDERSCORE = 'underscore';
43 43
 
44
-    const JS_HANDLE_ACCOUNTING_CORE = 'ee-accounting-core';
44
+	const JS_HANDLE_ACCOUNTING_CORE = 'ee-accounting-core';
45 45
 
46
-    /**
47
-     * @since 4.9.71.p
48
-     */
49
-    const JS_HANDLE_REACT = 'react';
46
+	/**
47
+	 * @since 4.9.71.p
48
+	 */
49
+	const JS_HANDLE_REACT = 'react';
50 50
 
51
-    /**
52
-     * @since 4.9.71.p
53
-     */
54
-    const JS_HANDLE_REACT_DOM = 'react-dom';
51
+	/**
52
+	 * @since 4.9.71.p
53
+	 */
54
+	const JS_HANDLE_REACT_DOM = 'react-dom';
55 55
 
56
-    /**
57
-     * @since 4.9.71.p
58
-     */
59
-    const JS_HANDLE_LODASH = 'lodash';
56
+	/**
57
+	 * @since 4.9.71.p
58
+	 */
59
+	const JS_HANDLE_LODASH = 'lodash';
60 60
 
61
-    const JS_HANDLE_JS_CORE = 'eejs-core';
61
+	const JS_HANDLE_JS_CORE = 'eejs-core';
62 62
 
63
-    const JS_HANDLE_VENDOR = 'eventespresso-vendor';
63
+	const JS_HANDLE_VENDOR = 'eventespresso-vendor';
64 64
 
65
-    const JS_HANDLE_UTILS = 'eventespresso-utils';
65
+	const JS_HANDLE_UTILS = 'eventespresso-utils';
66 66
 
67
-    const JS_HANDLE_DATA_STORES = 'eventespresso-data-stores';
67
+	const JS_HANDLE_DATA_STORES = 'eventespresso-data-stores';
68 68
 
69
-    const JS_HANDLE_HELPERS = 'eventespresso-helpers';
69
+	const JS_HANDLE_HELPERS = 'eventespresso-helpers';
70 70
 
71
-    const JS_HANDLE_MODEL = 'eventespresso-model';
71
+	const JS_HANDLE_MODEL = 'eventespresso-model';
72 72
 
73
-    const JS_HANDLE_VALUE_OBJECTS = 'eventespresso-value-objects';
73
+	const JS_HANDLE_VALUE_OBJECTS = 'eventespresso-value-objects';
74 74
 
75
-    const JS_HANDLE_HOCS = 'eventespresso-hocs';
75
+	const JS_HANDLE_HOCS = 'eventespresso-hocs';
76 76
 
77
-    const JS_HANDLE_COMPONENTS = 'eventespresso-components';
77
+	const JS_HANDLE_COMPONENTS = 'eventespresso-components';
78 78
 
79
-    const JS_HANDLE_HOOKS = 'eventespresso-hooks';
79
+	const JS_HANDLE_HOOKS = 'eventespresso-hooks';
80 80
 
81
-    const JS_HANDLE_VALIDATORS = 'eventespresso-validators';
81
+	const JS_HANDLE_VALIDATORS = 'eventespresso-validators';
82 82
 
83
-    const JS_HANDLE_CORE = 'espresso_core';
83
+	const JS_HANDLE_CORE = 'espresso_core';
84 84
 
85
-    const JS_HANDLE_I18N = 'eei18n';
85
+	const JS_HANDLE_I18N = 'eei18n';
86 86
 
87
-    const JS_HANDLE_ACCOUNTING = 'ee-accounting';
87
+	const JS_HANDLE_ACCOUNTING = 'ee-accounting';
88 88
 
89
-    const JS_HANDLE_WP_PLUGINS_PAGE = 'ee-wp-plugins-page';
89
+	const JS_HANDLE_WP_PLUGINS_PAGE = 'ee-wp-plugins-page';
90 90
 
91
-    // EE CSS assets handles
92
-    const CSS_HANDLE_DEFAULT = 'espresso_default';
91
+	// EE CSS assets handles
92
+	const CSS_HANDLE_DEFAULT = 'espresso_default';
93 93
 
94
-    const CSS_HANDLE_CUSTOM = 'espresso_custom_css';
95
-
96
-    const CSS_HANDLE_COMPONENTS = 'eventespresso-components';
97
-
98
-    const CSS_HANDLE_HOCS = 'eventespresso-hocs';
99
-
100
-    const CSS_HANDLE_CORE_CSS_DEFAULT = 'eventespresso-core-css-default';
101
-
102
-    /**
103
-     * @var EE_Currency_Config $currency_config
104
-     */
105
-    protected $currency_config;
106
-
107
-    /**
108
-     * @var EE_Template_Config $template_config
109
-     */
110
-    protected $template_config;
111
-
112
-
113
-    /**
114
-     * CoreAssetRegister constructor.
115
-     *
116
-     * @param AssetCollection    $assets
117
-     * @param EE_Currency_Config $currency_config
118
-     * @param EE_Template_Config $template_config
119
-     * @param DomainInterface    $domain
120
-     * @param Registry           $registry
121
-     */
122
-    public function __construct(
123
-        AssetCollection $assets,
124
-        EE_Currency_Config $currency_config,
125
-        EE_Template_Config $template_config,
126
-        DomainInterface $domain,
127
-        Registry $registry
128
-    ) {
129
-        $this->currency_config = $currency_config;
130
-        $this->template_config = $template_config;
131
-        parent::__construct($domain, $assets, $registry);
132
-    }
133
-
134
-
135
-    /**
136
-     * @since 4.9.62.p
137
-     * @throws DomainException
138
-     * @throws DuplicateCollectionIdentifierException
139
-     * @throws InvalidArgumentException
140
-     * @throws InvalidDataTypeException
141
-     * @throws InvalidEntityException
142
-     * @throws InvalidInterfaceException
143
-     */
144
-    public function addAssets()
145
-    {
146
-        $this->addJavascriptFiles();
147
-        $this->addStylesheetFiles();
148
-    }
149
-
150
-
151
-    /**
152
-     * @since 4.9.62.p
153
-     * @throws DomainException
154
-     * @throws DuplicateCollectionIdentifierException
155
-     * @throws InvalidArgumentException
156
-     * @throws InvalidDataTypeException
157
-     * @throws InvalidEntityException
158
-     * @throws InvalidInterfaceException
159
-     */
160
-    public function addJavascriptFiles()
161
-    {
162
-        $this->loadCoreJs();
163
-        $this->loadJqueryValidate();
164
-        $this->loadAccountingJs();
165
-        add_action(
166
-            'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
167
-            array($this, 'loadQtipJs')
168
-        );
169
-        $this->registerAdminAssets();
170
-    }
171
-
172
-
173
-    /**
174
-     * @since 4.9.62.p
175
-     * @throws DuplicateCollectionIdentifierException
176
-     * @throws InvalidDataTypeException
177
-     * @throws InvalidEntityException
178
-     */
179
-    public function addStylesheetFiles()
180
-    {
181
-        $this->loadCoreCss();
182
-    }
183
-
184
-
185
-    /**
186
-     * core default javascript
187
-     *
188
-     * @since 4.9.62.p
189
-     * @throws DomainException
190
-     * @throws DuplicateCollectionIdentifierException
191
-     * @throws InvalidArgumentException
192
-     * @throws InvalidDataTypeException
193
-     * @throws InvalidEntityException
194
-     * @throws InvalidInterfaceException
195
-     */
196
-    private function loadCoreJs()
197
-    {
198
-        // conditionally load third-party libraries that WP core MIGHT have.
199
-        $this->registerWpAssets();
200
-
201
-        $this->addJs(self::JS_HANDLE_JS_CORE)->setHasInlineData();
202
-        $this->addJs(self::JS_HANDLE_VENDOR);
203
-        $this->addJs(self::JS_HANDLE_UTILS)->setRequiresTranslation();
204
-        $this->addJs(self::JS_HANDLE_VALIDATORS)->setRequiresTranslation();
205
-        $this->addJs(self::JS_HANDLE_HELPERS)->setRequiresTranslation();
206
-        $this->addJs(self::JS_HANDLE_MODEL)->setRequiresTranslation();
207
-        $this->addJs(self::JS_HANDLE_HOOKS);
208
-        $this->addJs(self::JS_HANDLE_VALUE_OBJECTS)->setRequiresTranslation();
209
-        $this->addJs(self::JS_HANDLE_DATA_STORES)->setRequiresTranslation()->setInlineDataCallback(
210
-            static function () {
211
-                wp_add_inline_script(
212
-                    CoreAssetManager::JS_HANDLE_DATA_STORES,
213
-                    is_admin()
214
-                        ? 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware( eejs.middleWares.apiFetch.CONTEXT_CAPS_EDIT ) )'
215
-                        : 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware )'
216
-                );
217
-            }
218
-        );
219
-        $this->addJs(self::JS_HANDLE_HOCS, self::JS_HANDLE_DATA_STORES)->setRequiresTranslation();
220
-        $this->addJs(self::JS_HANDLE_COMPONENTS, self::JS_HANDLE_DATA_STORES)->setRequiresTranslation();
221
-
222
-        $this->registry->addData('eejs_api_nonce', wp_create_nonce('wp_rest'));
223
-        $this->registry->addData(
224
-            'paths',
225
-            array(
226
-                'base_rest_route' => rest_url(),
227
-                'rest_route' => rest_url('ee/v4.8.36/'),
228
-                'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName(),
229
-                'primary_keys' => EED_Core_Rest_Api::getPrimaryKeyNamesIndexedByModelName(),
230
-                'site_url' => site_url('/'),
231
-                'admin_url' => admin_url('/'),
232
-            )
233
-        );
234
-        // Event Espresso brand name
235
-        $this->registry->addData('brandName', Domain::brandName());
236
-        /** site formatting values **/
237
-        $this->registry->addData(
238
-            'site_formats',
239
-            array(
240
-                'date_formats' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats()
241
-            )
242
-        );
243
-        /** currency data **/
244
-        $this->registry->addData(
245
-            'currency_config',
246
-            $this->getCurrencySettings()
247
-        );
248
-        /** site timezone */
249
-        $this->registry->addData(
250
-            'default_timezone',
251
-            array(
252
-                'pretty' => EEH_DTT_Helper::get_timezone_string_for_display(),
253
-                'string' => get_option('timezone_string'),
254
-                'offset' => EEH_DTT_Helper::get_site_timezone_gmt_offset(),
255
-            )
256
-        );
257
-        /** site locale (user locale if user logged in) */
258
-        $this->registry->addData(
259
-            'locale',
260
-            array(
261
-                'user' => get_user_locale(),
262
-                'site' => get_locale()
263
-            )
264
-        );
265
-
266
-        $this->addJavascript(
267
-            CoreAssetManager::JS_HANDLE_CORE,
268
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
269
-            array(CoreAssetManager::JS_HANDLE_JQUERY)
270
-        )
271
-        ->setInlineDataCallback(
272
-            static function () {
273
-                wp_localize_script(
274
-                    CoreAssetManager::JS_HANDLE_CORE,
275
-                    CoreAssetManager::JS_HANDLE_I18N,
276
-                    EE_Registry::$i18n_js_strings
277
-                );
278
-            }
279
-        );
280
-    }
281
-
282
-
283
-    /**
284
-     * Registers vendor files that are bundled with a later version WP but might not be for the current version of
285
-     * WordPress in the running environment.
286
-     *
287
-     * @throws DuplicateCollectionIdentifierException
288
-     * @throws InvalidDataTypeException
289
-     * @throws InvalidEntityException
290
-     * @throws DomainException
291
-     * @since 4.9.71.p
292
-     */
293
-    private function registerWpAssets()
294
-    {
295
-        global $wp_version;
296
-        if (version_compare($wp_version, '5.0.beta', '>=')) {
297
-            return;
298
-        }
299
-        $this->addVendorJavascript(CoreAssetManager::JS_HANDLE_REACT)
300
-            ->setVersion('16.6.0');
301
-        $this->addVendorJavascript(
302
-            CoreAssetManager::JS_HANDLE_REACT_DOM,
303
-            array(CoreAssetManager::JS_HANDLE_REACT)
304
-        )->setVersion('16.6.0');
305
-        $this->addVendorJavascript(CoreAssetManager::JS_HANDLE_LODASH)
306
-            ->setInlineDataCallback(
307
-                static function() {
308
-                    wp_add_inline_script(
309
-                        CoreAssetManager::JS_HANDLE_LODASH,
310
-                        'window.lodash = _.noConflict();'
311
-                    );
312
-                }
313
-            )
314
-            ->setVersion('4.17.11');
315
-    }
316
-
317
-
318
-    /**
319
-     * Returns configuration data for the accounting-js library.
320
-     * @since 4.9.71.p
321
-     * @return array
322
-     */
323
-    private function getAccountingSettings() {
324
-        return array(
325
-            'currency' => array(
326
-                'symbol'    => $this->currency_config->sign,
327
-                'format'    => array(
328
-                    'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
329
-                    'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
330
-                    'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
331
-                ),
332
-                'decimal'   => $this->currency_config->dec_mrk,
333
-                'thousand'  => $this->currency_config->thsnds,
334
-                'precision' => $this->currency_config->dec_plc,
335
-            ),
336
-            'number'   => array(
337
-                'precision' => $this->currency_config->dec_plc,
338
-                'thousand'  => $this->currency_config->thsnds,
339
-                'decimal'   => $this->currency_config->dec_mrk,
340
-            ),
341
-        );
342
-    }
343
-
344
-
345
-    /**
346
-     * Returns configuration data for the js Currency VO.
347
-     * @since 4.9.71.p
348
-     * @return array
349
-     */
350
-    private function getCurrencySettings()
351
-    {
352
-        return array(
353
-            'code' => $this->currency_config->code,
354
-            'singularLabel' => $this->currency_config->name,
355
-            'pluralLabel' => $this->currency_config->plural,
356
-            'sign' => $this->currency_config->sign,
357
-            'signB4' => $this->currency_config->sign_b4,
358
-            'decimalPlaces' => $this->currency_config->dec_plc,
359
-            'decimalMark' => $this->currency_config->dec_mrk,
360
-            'thousandsSeparator' => $this->currency_config->thsnds,
361
-        );
362
-    }
363
-
364
-
365
-    /**
366
-     * @since 4.9.62.p
367
-     * @throws DuplicateCollectionIdentifierException
368
-     * @throws InvalidDataTypeException
369
-     * @throws InvalidEntityException
370
-     */
371
-    private function loadCoreCss()
372
-    {
373
-        if ($this->template_config->enable_default_style && ! is_admin()) {
374
-            $this->addStylesheet(
375
-                CoreAssetManager::CSS_HANDLE_DEFAULT,
376
-                is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
377
-                    ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
378
-                    : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
379
-                array('dashicons')
380
-            );
381
-            //Load custom style sheet if available
382
-            if ($this->template_config->custom_style_sheet !== null) {
383
-                $this->addStylesheet(
384
-                    CoreAssetManager::CSS_HANDLE_CUSTOM,
385
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
386
-                    array(CoreAssetManager::CSS_HANDLE_DEFAULT)
387
-                );
388
-            }
389
-        }
390
-        $this->addCss(self::CSS_HANDLE_CORE_CSS_DEFAULT, 'dashicons');
391
-        $this->addCss(self::CSS_HANDLE_COMPONENTS, self::CSS_HANDLE_CORE_CSS_DEFAULT);
392
-        $this->addCss(self::CSS_HANDLE_HOCS);
393
-    }
394
-
395
-
396
-    /**
397
-     * jQuery Validate for form validation
398
-     *
399
-     * @since 4.9.62.p
400
-     * @throws DomainException
401
-     * @throws DuplicateCollectionIdentifierException
402
-     * @throws InvalidDataTypeException
403
-     * @throws InvalidEntityException
404
-     */
405
-    private function loadJqueryValidate()
406
-    {
407
-        $this->addJavascript(
408
-            CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
409
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
410
-            array(CoreAssetManager::JS_HANDLE_JQUERY)
411
-        )
412
-        ->setVersion('1.15.0');
413
-
414
-        $this->addJavascript(
415
-            CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
416
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
417
-            array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE)
418
-        )
419
-        ->setVersion('1.15.0');
420
-    }
421
-
422
-
423
-    /**
424
-     * accounting.js for performing client-side calculations
425
-     *
426
-     * @since 4.9.62.p
427
-     * @throws DomainException
428
-     * @throws DuplicateCollectionIdentifierException
429
-     * @throws InvalidDataTypeException
430
-     * @throws InvalidEntityException
431
-     */
432
-    private function loadAccountingJs()
433
-    {
434
-        //accounting.js library
435
-        // @link http://josscrowcroft.github.io/accounting.js/
436
-        $this->addJavascript(
437
-            CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE,
438
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
439
-            array(CoreAssetManager::JS_HANDLE_UNDERSCORE)
440
-        )
441
-        ->setVersion('0.3.2');
442
-
443
-        $this->addJavascript(
444
-            CoreAssetManager::JS_HANDLE_ACCOUNTING,
445
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
446
-            array(CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE)
447
-        )
448
-        ->setInlineDataCallback(
449
-            function () {
450
-                 wp_localize_script(
451
-                     CoreAssetManager::JS_HANDLE_ACCOUNTING,
452
-                     'EE_ACCOUNTING_CFG',
453
-                     $this->getAccountingSettings()
454
-                 );
455
-            }
456
-        )
457
-        ->setVersion();
458
-    }
459
-
460
-
461
-    /**
462
-     * registers assets for cleaning your ears
463
-     *
464
-     * @param JavascriptAsset $script
465
-     */
466
-    public function loadQtipJs(JavascriptAsset $script)
467
-    {
468
-        // qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
469
-        // can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
470
-        if (
471
-            $script->handle() === CoreAssetManager::JS_HANDLE_WP_PLUGINS_PAGE
472
-            && apply_filters('FHEE_load_qtip', false)
473
-        ) {
474
-            EEH_Qtip_Loader::instance()->register_and_enqueue();
475
-        }
476
-    }
477
-
478
-
479
-    /**
480
-     * assets that are used in the WordPress admin
481
-     *
482
-     * @since 4.9.62.p
483
-     * @throws DuplicateCollectionIdentifierException
484
-     * @throws InvalidDataTypeException
485
-     * @throws InvalidEntityException
486
-     */
487
-    private function registerAdminAssets()
488
-    {
489
-        $this->addJs(self::JS_HANDLE_WP_PLUGINS_PAGE)->setRequiresTranslation();
490
-        // note usage of the "JS_HANDLE.." constant is intentional here because css uses the same handle.
491
-        $this->addCss(self::JS_HANDLE_WP_PLUGINS_PAGE);
492
-    }
94
+	const CSS_HANDLE_CUSTOM = 'espresso_custom_css';
95
+
96
+	const CSS_HANDLE_COMPONENTS = 'eventespresso-components';
97
+
98
+	const CSS_HANDLE_HOCS = 'eventespresso-hocs';
99
+
100
+	const CSS_HANDLE_CORE_CSS_DEFAULT = 'eventespresso-core-css-default';
101
+
102
+	/**
103
+	 * @var EE_Currency_Config $currency_config
104
+	 */
105
+	protected $currency_config;
106
+
107
+	/**
108
+	 * @var EE_Template_Config $template_config
109
+	 */
110
+	protected $template_config;
111
+
112
+
113
+	/**
114
+	 * CoreAssetRegister constructor.
115
+	 *
116
+	 * @param AssetCollection    $assets
117
+	 * @param EE_Currency_Config $currency_config
118
+	 * @param EE_Template_Config $template_config
119
+	 * @param DomainInterface    $domain
120
+	 * @param Registry           $registry
121
+	 */
122
+	public function __construct(
123
+		AssetCollection $assets,
124
+		EE_Currency_Config $currency_config,
125
+		EE_Template_Config $template_config,
126
+		DomainInterface $domain,
127
+		Registry $registry
128
+	) {
129
+		$this->currency_config = $currency_config;
130
+		$this->template_config = $template_config;
131
+		parent::__construct($domain, $assets, $registry);
132
+	}
133
+
134
+
135
+	/**
136
+	 * @since 4.9.62.p
137
+	 * @throws DomainException
138
+	 * @throws DuplicateCollectionIdentifierException
139
+	 * @throws InvalidArgumentException
140
+	 * @throws InvalidDataTypeException
141
+	 * @throws InvalidEntityException
142
+	 * @throws InvalidInterfaceException
143
+	 */
144
+	public function addAssets()
145
+	{
146
+		$this->addJavascriptFiles();
147
+		$this->addStylesheetFiles();
148
+	}
149
+
150
+
151
+	/**
152
+	 * @since 4.9.62.p
153
+	 * @throws DomainException
154
+	 * @throws DuplicateCollectionIdentifierException
155
+	 * @throws InvalidArgumentException
156
+	 * @throws InvalidDataTypeException
157
+	 * @throws InvalidEntityException
158
+	 * @throws InvalidInterfaceException
159
+	 */
160
+	public function addJavascriptFiles()
161
+	{
162
+		$this->loadCoreJs();
163
+		$this->loadJqueryValidate();
164
+		$this->loadAccountingJs();
165
+		add_action(
166
+			'AHEE__EventEspresso_core_services_assets_Registry__registerScripts__before_script',
167
+			array($this, 'loadQtipJs')
168
+		);
169
+		$this->registerAdminAssets();
170
+	}
171
+
172
+
173
+	/**
174
+	 * @since 4.9.62.p
175
+	 * @throws DuplicateCollectionIdentifierException
176
+	 * @throws InvalidDataTypeException
177
+	 * @throws InvalidEntityException
178
+	 */
179
+	public function addStylesheetFiles()
180
+	{
181
+		$this->loadCoreCss();
182
+	}
183
+
184
+
185
+	/**
186
+	 * core default javascript
187
+	 *
188
+	 * @since 4.9.62.p
189
+	 * @throws DomainException
190
+	 * @throws DuplicateCollectionIdentifierException
191
+	 * @throws InvalidArgumentException
192
+	 * @throws InvalidDataTypeException
193
+	 * @throws InvalidEntityException
194
+	 * @throws InvalidInterfaceException
195
+	 */
196
+	private function loadCoreJs()
197
+	{
198
+		// conditionally load third-party libraries that WP core MIGHT have.
199
+		$this->registerWpAssets();
200
+
201
+		$this->addJs(self::JS_HANDLE_JS_CORE)->setHasInlineData();
202
+		$this->addJs(self::JS_HANDLE_VENDOR);
203
+		$this->addJs(self::JS_HANDLE_UTILS)->setRequiresTranslation();
204
+		$this->addJs(self::JS_HANDLE_VALIDATORS)->setRequiresTranslation();
205
+		$this->addJs(self::JS_HANDLE_HELPERS)->setRequiresTranslation();
206
+		$this->addJs(self::JS_HANDLE_MODEL)->setRequiresTranslation();
207
+		$this->addJs(self::JS_HANDLE_HOOKS);
208
+		$this->addJs(self::JS_HANDLE_VALUE_OBJECTS)->setRequiresTranslation();
209
+		$this->addJs(self::JS_HANDLE_DATA_STORES)->setRequiresTranslation()->setInlineDataCallback(
210
+			static function () {
211
+				wp_add_inline_script(
212
+					CoreAssetManager::JS_HANDLE_DATA_STORES,
213
+					is_admin()
214
+						? 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware( eejs.middleWares.apiFetch.CONTEXT_CAPS_EDIT ) )'
215
+						: 'wp.apiFetch.use( eejs.middleWares.apiFetch.capsMiddleware )'
216
+				);
217
+			}
218
+		);
219
+		$this->addJs(self::JS_HANDLE_HOCS, self::JS_HANDLE_DATA_STORES)->setRequiresTranslation();
220
+		$this->addJs(self::JS_HANDLE_COMPONENTS, self::JS_HANDLE_DATA_STORES)->setRequiresTranslation();
221
+
222
+		$this->registry->addData('eejs_api_nonce', wp_create_nonce('wp_rest'));
223
+		$this->registry->addData(
224
+			'paths',
225
+			array(
226
+				'base_rest_route' => rest_url(),
227
+				'rest_route' => rest_url('ee/v4.8.36/'),
228
+				'collection_endpoints' => EED_Core_Rest_Api::getCollectionRoutesIndexedByModelName(),
229
+				'primary_keys' => EED_Core_Rest_Api::getPrimaryKeyNamesIndexedByModelName(),
230
+				'site_url' => site_url('/'),
231
+				'admin_url' => admin_url('/'),
232
+			)
233
+		);
234
+		// Event Espresso brand name
235
+		$this->registry->addData('brandName', Domain::brandName());
236
+		/** site formatting values **/
237
+		$this->registry->addData(
238
+			'site_formats',
239
+			array(
240
+				'date_formats' => EEH_DTT_Helper::convert_php_to_js_and_moment_date_formats()
241
+			)
242
+		);
243
+		/** currency data **/
244
+		$this->registry->addData(
245
+			'currency_config',
246
+			$this->getCurrencySettings()
247
+		);
248
+		/** site timezone */
249
+		$this->registry->addData(
250
+			'default_timezone',
251
+			array(
252
+				'pretty' => EEH_DTT_Helper::get_timezone_string_for_display(),
253
+				'string' => get_option('timezone_string'),
254
+				'offset' => EEH_DTT_Helper::get_site_timezone_gmt_offset(),
255
+			)
256
+		);
257
+		/** site locale (user locale if user logged in) */
258
+		$this->registry->addData(
259
+			'locale',
260
+			array(
261
+				'user' => get_user_locale(),
262
+				'site' => get_locale()
263
+			)
264
+		);
265
+
266
+		$this->addJavascript(
267
+			CoreAssetManager::JS_HANDLE_CORE,
268
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
269
+			array(CoreAssetManager::JS_HANDLE_JQUERY)
270
+		)
271
+		->setInlineDataCallback(
272
+			static function () {
273
+				wp_localize_script(
274
+					CoreAssetManager::JS_HANDLE_CORE,
275
+					CoreAssetManager::JS_HANDLE_I18N,
276
+					EE_Registry::$i18n_js_strings
277
+				);
278
+			}
279
+		);
280
+	}
281
+
282
+
283
+	/**
284
+	 * Registers vendor files that are bundled with a later version WP but might not be for the current version of
285
+	 * WordPress in the running environment.
286
+	 *
287
+	 * @throws DuplicateCollectionIdentifierException
288
+	 * @throws InvalidDataTypeException
289
+	 * @throws InvalidEntityException
290
+	 * @throws DomainException
291
+	 * @since 4.9.71.p
292
+	 */
293
+	private function registerWpAssets()
294
+	{
295
+		global $wp_version;
296
+		if (version_compare($wp_version, '5.0.beta', '>=')) {
297
+			return;
298
+		}
299
+		$this->addVendorJavascript(CoreAssetManager::JS_HANDLE_REACT)
300
+			->setVersion('16.6.0');
301
+		$this->addVendorJavascript(
302
+			CoreAssetManager::JS_HANDLE_REACT_DOM,
303
+			array(CoreAssetManager::JS_HANDLE_REACT)
304
+		)->setVersion('16.6.0');
305
+		$this->addVendorJavascript(CoreAssetManager::JS_HANDLE_LODASH)
306
+			->setInlineDataCallback(
307
+				static function() {
308
+					wp_add_inline_script(
309
+						CoreAssetManager::JS_HANDLE_LODASH,
310
+						'window.lodash = _.noConflict();'
311
+					);
312
+				}
313
+			)
314
+			->setVersion('4.17.11');
315
+	}
316
+
317
+
318
+	/**
319
+	 * Returns configuration data for the accounting-js library.
320
+	 * @since 4.9.71.p
321
+	 * @return array
322
+	 */
323
+	private function getAccountingSettings() {
324
+		return array(
325
+			'currency' => array(
326
+				'symbol'    => $this->currency_config->sign,
327
+				'format'    => array(
328
+					'pos'  => $this->currency_config->sign_b4 ? '%s%v' : '%v%s',
329
+					'neg'  => $this->currency_config->sign_b4 ? '- %s%v' : '- %v%s',
330
+					'zero' => $this->currency_config->sign_b4 ? '%s--' : '--%s',
331
+				),
332
+				'decimal'   => $this->currency_config->dec_mrk,
333
+				'thousand'  => $this->currency_config->thsnds,
334
+				'precision' => $this->currency_config->dec_plc,
335
+			),
336
+			'number'   => array(
337
+				'precision' => $this->currency_config->dec_plc,
338
+				'thousand'  => $this->currency_config->thsnds,
339
+				'decimal'   => $this->currency_config->dec_mrk,
340
+			),
341
+		);
342
+	}
343
+
344
+
345
+	/**
346
+	 * Returns configuration data for the js Currency VO.
347
+	 * @since 4.9.71.p
348
+	 * @return array
349
+	 */
350
+	private function getCurrencySettings()
351
+	{
352
+		return array(
353
+			'code' => $this->currency_config->code,
354
+			'singularLabel' => $this->currency_config->name,
355
+			'pluralLabel' => $this->currency_config->plural,
356
+			'sign' => $this->currency_config->sign,
357
+			'signB4' => $this->currency_config->sign_b4,
358
+			'decimalPlaces' => $this->currency_config->dec_plc,
359
+			'decimalMark' => $this->currency_config->dec_mrk,
360
+			'thousandsSeparator' => $this->currency_config->thsnds,
361
+		);
362
+	}
363
+
364
+
365
+	/**
366
+	 * @since 4.9.62.p
367
+	 * @throws DuplicateCollectionIdentifierException
368
+	 * @throws InvalidDataTypeException
369
+	 * @throws InvalidEntityException
370
+	 */
371
+	private function loadCoreCss()
372
+	{
373
+		if ($this->template_config->enable_default_style && ! is_admin()) {
374
+			$this->addStylesheet(
375
+				CoreAssetManager::CSS_HANDLE_DEFAULT,
376
+				is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
377
+					? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
378
+					: EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
379
+				array('dashicons')
380
+			);
381
+			//Load custom style sheet if available
382
+			if ($this->template_config->custom_style_sheet !== null) {
383
+				$this->addStylesheet(
384
+					CoreAssetManager::CSS_HANDLE_CUSTOM,
385
+					EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
386
+					array(CoreAssetManager::CSS_HANDLE_DEFAULT)
387
+				);
388
+			}
389
+		}
390
+		$this->addCss(self::CSS_HANDLE_CORE_CSS_DEFAULT, 'dashicons');
391
+		$this->addCss(self::CSS_HANDLE_COMPONENTS, self::CSS_HANDLE_CORE_CSS_DEFAULT);
392
+		$this->addCss(self::CSS_HANDLE_HOCS);
393
+	}
394
+
395
+
396
+	/**
397
+	 * jQuery Validate for form validation
398
+	 *
399
+	 * @since 4.9.62.p
400
+	 * @throws DomainException
401
+	 * @throws DuplicateCollectionIdentifierException
402
+	 * @throws InvalidDataTypeException
403
+	 * @throws InvalidEntityException
404
+	 */
405
+	private function loadJqueryValidate()
406
+	{
407
+		$this->addJavascript(
408
+			CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
409
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
410
+			array(CoreAssetManager::JS_HANDLE_JQUERY)
411
+		)
412
+		->setVersion('1.15.0');
413
+
414
+		$this->addJavascript(
415
+			CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
416
+			EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
417
+			array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE)
418
+		)
419
+		->setVersion('1.15.0');
420
+	}
421
+
422
+
423
+	/**
424
+	 * accounting.js for performing client-side calculations
425
+	 *
426
+	 * @since 4.9.62.p
427
+	 * @throws DomainException
428
+	 * @throws DuplicateCollectionIdentifierException
429
+	 * @throws InvalidDataTypeException
430
+	 * @throws InvalidEntityException
431
+	 */
432
+	private function loadAccountingJs()
433
+	{
434
+		//accounting.js library
435
+		// @link http://josscrowcroft.github.io/accounting.js/
436
+		$this->addJavascript(
437
+			CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE,
438
+			EE_THIRD_PARTY_URL . 'accounting/accounting.js',
439
+			array(CoreAssetManager::JS_HANDLE_UNDERSCORE)
440
+		)
441
+		->setVersion('0.3.2');
442
+
443
+		$this->addJavascript(
444
+			CoreAssetManager::JS_HANDLE_ACCOUNTING,
445
+			EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
446
+			array(CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE)
447
+		)
448
+		->setInlineDataCallback(
449
+			function () {
450
+				 wp_localize_script(
451
+					 CoreAssetManager::JS_HANDLE_ACCOUNTING,
452
+					 'EE_ACCOUNTING_CFG',
453
+					 $this->getAccountingSettings()
454
+				 );
455
+			}
456
+		)
457
+		->setVersion();
458
+	}
459
+
460
+
461
+	/**
462
+	 * registers assets for cleaning your ears
463
+	 *
464
+	 * @param JavascriptAsset $script
465
+	 */
466
+	public function loadQtipJs(JavascriptAsset $script)
467
+	{
468
+		// qtip is turned OFF by default, but prior to the wp_enqueue_scripts hook,
469
+		// can be turned back on again via: add_filter('FHEE_load_qtip', '__return_true' );
470
+		if (
471
+			$script->handle() === CoreAssetManager::JS_HANDLE_WP_PLUGINS_PAGE
472
+			&& apply_filters('FHEE_load_qtip', false)
473
+		) {
474
+			EEH_Qtip_Loader::instance()->register_and_enqueue();
475
+		}
476
+	}
477
+
478
+
479
+	/**
480
+	 * assets that are used in the WordPress admin
481
+	 *
482
+	 * @since 4.9.62.p
483
+	 * @throws DuplicateCollectionIdentifierException
484
+	 * @throws InvalidDataTypeException
485
+	 * @throws InvalidEntityException
486
+	 */
487
+	private function registerAdminAssets()
488
+	{
489
+		$this->addJs(self::JS_HANDLE_WP_PLUGINS_PAGE)->setRequiresTranslation();
490
+		// note usage of the "JS_HANDLE.." constant is intentional here because css uses the same handle.
491
+		$this->addCss(self::JS_HANDLE_WP_PLUGINS_PAGE);
492
+	}
493 493
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
         $this->addJs(self::JS_HANDLE_HOOKS);
208 208
         $this->addJs(self::JS_HANDLE_VALUE_OBJECTS)->setRequiresTranslation();
209 209
         $this->addJs(self::JS_HANDLE_DATA_STORES)->setRequiresTranslation()->setInlineDataCallback(
210
-            static function () {
210
+            static function() {
211 211
                 wp_add_inline_script(
212 212
                     CoreAssetManager::JS_HANDLE_DATA_STORES,
213 213
                     is_admin()
@@ -265,11 +265,11 @@  discard block
 block discarded – undo
265 265
 
266 266
         $this->addJavascript(
267 267
             CoreAssetManager::JS_HANDLE_CORE,
268
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
268
+            EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
269 269
             array(CoreAssetManager::JS_HANDLE_JQUERY)
270 270
         )
271 271
         ->setInlineDataCallback(
272
-            static function () {
272
+            static function() {
273 273
                 wp_localize_script(
274 274
                     CoreAssetManager::JS_HANDLE_CORE,
275 275
                     CoreAssetManager::JS_HANDLE_I18N,
@@ -373,16 +373,16 @@  discard block
 block discarded – undo
373 373
         if ($this->template_config->enable_default_style && ! is_admin()) {
374 374
             $this->addStylesheet(
375 375
                 CoreAssetManager::CSS_HANDLE_DEFAULT,
376
-                is_readable(EVENT_ESPRESSO_UPLOAD_DIR . 'css/style.css')
376
+                is_readable(EVENT_ESPRESSO_UPLOAD_DIR.'css/style.css')
377 377
                     ? EVENT_ESPRESSO_UPLOAD_DIR . 'css/espresso_default.css'
378
-                    : EE_GLOBAL_ASSETS_URL . 'css/espresso_default.css',
378
+                    : EE_GLOBAL_ASSETS_URL.'css/espresso_default.css',
379 379
                 array('dashicons')
380 380
             );
381 381
             //Load custom style sheet if available
382 382
             if ($this->template_config->custom_style_sheet !== null) {
383 383
                 $this->addStylesheet(
384 384
                     CoreAssetManager::CSS_HANDLE_CUSTOM,
385
-                    EVENT_ESPRESSO_UPLOAD_URL . 'css/' . $this->template_config->custom_style_sheet,
385
+                    EVENT_ESPRESSO_UPLOAD_URL.'css/'.$this->template_config->custom_style_sheet,
386 386
                     array(CoreAssetManager::CSS_HANDLE_DEFAULT)
387 387
                 );
388 388
             }
@@ -406,14 +406,14 @@  discard block
 block discarded – undo
406 406
     {
407 407
         $this->addJavascript(
408 408
             CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE,
409
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.min.js',
409
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.min.js',
410 410
             array(CoreAssetManager::JS_HANDLE_JQUERY)
411 411
         )
412 412
         ->setVersion('1.15.0');
413 413
 
414 414
         $this->addJavascript(
415 415
             CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE_EXTRA,
416
-            EE_GLOBAL_ASSETS_URL . 'scripts/jquery.validate.additional-methods.min.js',
416
+            EE_GLOBAL_ASSETS_URL.'scripts/jquery.validate.additional-methods.min.js',
417 417
             array(CoreAssetManager::JS_HANDLE_JQUERY_VALIDATE)
418 418
         )
419 419
         ->setVersion('1.15.0');
@@ -435,18 +435,18 @@  discard block
 block discarded – undo
435 435
         // @link http://josscrowcroft.github.io/accounting.js/
436 436
         $this->addJavascript(
437 437
             CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE,
438
-            EE_THIRD_PARTY_URL . 'accounting/accounting.js',
438
+            EE_THIRD_PARTY_URL.'accounting/accounting.js',
439 439
             array(CoreAssetManager::JS_HANDLE_UNDERSCORE)
440 440
         )
441 441
         ->setVersion('0.3.2');
442 442
 
443 443
         $this->addJavascript(
444 444
             CoreAssetManager::JS_HANDLE_ACCOUNTING,
445
-            EE_GLOBAL_ASSETS_URL . 'scripts/ee-accounting-config.js',
445
+            EE_GLOBAL_ASSETS_URL.'scripts/ee-accounting-config.js',
446 446
             array(CoreAssetManager::JS_HANDLE_ACCOUNTING_CORE)
447 447
         )
448 448
         ->setInlineDataCallback(
449
-            function () {
449
+            function() {
450 450
                  wp_localize_script(
451 451
                      CoreAssetManager::JS_HANDLE_ACCOUNTING,
452 452
                      'EE_ACCOUNTING_CFG',
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.4.0');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.2.rc.000');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.2.rc.000');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
Please login to merge, or discard this patch.
core/EE_Log.core.php 1 patch
Indentation   +192 added lines, -192 removed lines patch added patch discarded remove patch
@@ -17,196 +17,196 @@
 block discarded – undo
17 17
 class EE_Log
18 18
 {
19 19
 
20
-    /**
21
-     * @var string
22
-     */
23
-    private $_log = '';
24
-
25
-    /**
26
-     * Used for remote logging
27
-     *
28
-     * @var string
29
-     */
30
-    private $_remote_logging_url = '';
31
-
32
-    /**
33
-     * @var string
34
-     */
35
-    private $_remote_log = '';
36
-
37
-    /**
38
-     * @var EE_Log
39
-     */
40
-    private static $_instance;
41
-
42
-
43
-    /**
44
-     * @return EE_Log
45
-     */
46
-    public static function instance()
47
-    {
48
-        if (! self::$_instance instanceof EE_Log) {
49
-            self::$_instance = new self();
50
-        }
51
-        return self::$_instance;
52
-    }
53
-
54
-    /**
55
-     * @access private
56
-     * @return EE_Log
57
-     */
58
-    private function __construct()
59
-    {
60
-
61
-        if (! EE_Registry::instance()->CFG->admin->use_remote_logging) {
62
-            return;
63
-        }
64
-
65
-        $this->_remote_logging_url = EE_Registry::instance()->CFG->admin->remote_logging_url;
66
-        $this->_remote_log = '';
67
-
68
-        if (EE_Registry::instance()->CFG->admin->use_remote_logging) {
69
-            add_action('shutdown', array($this, 'send_log'), 9999);
70
-        }
71
-    }
72
-
73
-
74
-    /**
75
-     *    verify_filesystem
76
-     * tests that the required files and folders exist and are writable
77
-     *
78
-     */
79
-    public function verify_filesystem()
80
-    {
81
-        $msg = esc_html__(
82
-            'The Local File Logging functionality was removed permanently. Remote Logging is recommended instead.',
83
-            'event_espresso'
84
-        );
85
-        EE_Error::doing_it_wrong(
86
-            __METHOD__,
87
-            $msg,
88
-            '4.10.1.p'
89
-        );
90
-    }
91
-
92
-
93
-    /**
94
-     *    _format_message
95
-     *    makes yer log entries look all purdy
96
-     *
97
-     * @param string $file
98
-     * @param string $function
99
-     * @param string $message
100
-     * @param string $type
101
-     * @return string
102
-     */
103
-    private function _format_message($file = '', $function = '', $message = '', $type = '')
104
-    {
105
-        $msg = '----------------------------------------------------------------------------------------' . PHP_EOL;
106
-        $msg .= '[' . current_time('mysql') . '] ';
107
-        $msg .= ! empty($file) ? basename($file) : '';
108
-        $msg .= ! empty($file) && ! empty($function) ? ' -> ' : '';
109
-        $msg .= ! empty($function) ? $function . '()' : '';
110
-        $msg .= PHP_EOL;
111
-        $type = ! empty($type) ? $type : 'log message';
112
-        $msg .= ! empty($message) ? "\t" . '[' . $type . '] ' . $message . PHP_EOL : '';
113
-        return $msg;
114
-    }
115
-
116
-
117
-    /**
118
-     *    log
119
-     * adds content to the EE_Log->_log property which gets written to file during the WP 'shutdown' hookpoint via the
120
-     * EE_Log::write_log() callback
121
-     *
122
-     * @param string $file
123
-     * @param string $function
124
-     * @param string $message
125
-     * @param string $type
126
-     */
127
-    public function log($file = '', $function = '', $message = '', $type = '')
128
-    {
129
-        $this->_log .= $this->_format_message($file, $function, $message, $type);
130
-    }
131
-
132
-
133
-    /**
134
-     * write_log
135
-     * appends the results of the 'AHEE_log' filter to the espresso log file
136
-     */
137
-    public function write_log()
138
-    {
139
-        $msg = esc_html__(
140
-            'The Local File Logging functionality was removed permanently. Remote Logging is recommended instead.',
141
-            'event_espresso'
142
-        );
143
-        EE_Error::doing_it_wrong(
144
-            __METHOD__,
145
-            $msg,
146
-            '4.10.1.p'
147
-        );
148
-    }
149
-
150
-
151
-    /**
152
-     * send_log
153
-     * sends the espresso log to a remote URL via a PHP cURL request
154
-     */
155
-    public function send_log()
156
-    {
157
-
158
-        if (empty($this->_remote_logging_url)) {
159
-            return;
160
-        }
161
-
162
-        $data = 'domain=' . $_SERVER['HTTP_HOST'];
163
-        $data .= '&ip=' . $_SERVER['SERVER_ADDR'];
164
-        $data .= '&server_type=' . $_SERVER['SERVER_SOFTWARE'];
165
-        $data .= '&time=' . time();
166
-        $data .= '&remote_log=' . $this->_log;
167
-        $data .= '&request_array=' . json_encode($_REQUEST);
168
-        $data .= '&action=save';
169
-
170
-        if (defined('EELOGGING_PASS')) {
171
-            $data .= '&pass=' . EELOGGING_PASS;
172
-        }
173
-        if (defined('EELOGGING_KEY')) {
174
-            $data .= '&key=' . EELOGGING_KEY;
175
-        }
176
-
177
-        $c = curl_init($this->_remote_logging_url);
178
-        curl_setopt($c, CURLOPT_POST, true);
179
-        curl_setopt($c, CURLOPT_POSTFIELDS, $data);
180
-        curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
181
-        curl_exec($c);
182
-        curl_close($c);
183
-    }
184
-
185
-
186
-    /**
187
-     * write_debug
188
-     * writes the contents of the current request's $_GET and $_POST arrays to a log file.
189
-     * previous entries are overwritten
190
-     */
191
-    public function write_debug()
192
-    {
193
-        $msg = esc_html__(
194
-            'The Local File Logging functionality was removed permanently. Remote Logging is recommended instead.',
195
-            'event_espresso'
196
-        );
197
-        EE_Error::doing_it_wrong(
198
-            __METHOD__,
199
-            $msg,
200
-            '4.10.1.p'
201
-        );
202
-    }
203
-
204
-
205
-    /**
206
-     * __clone
207
-     */
208
-    public function __clone()
209
-    {
210
-        trigger_error(__('Clone is not allowed.', 'event_espresso'), E_USER_ERROR);
211
-    }
20
+	/**
21
+	 * @var string
22
+	 */
23
+	private $_log = '';
24
+
25
+	/**
26
+	 * Used for remote logging
27
+	 *
28
+	 * @var string
29
+	 */
30
+	private $_remote_logging_url = '';
31
+
32
+	/**
33
+	 * @var string
34
+	 */
35
+	private $_remote_log = '';
36
+
37
+	/**
38
+	 * @var EE_Log
39
+	 */
40
+	private static $_instance;
41
+
42
+
43
+	/**
44
+	 * @return EE_Log
45
+	 */
46
+	public static function instance()
47
+	{
48
+		if (! self::$_instance instanceof EE_Log) {
49
+			self::$_instance = new self();
50
+		}
51
+		return self::$_instance;
52
+	}
53
+
54
+	/**
55
+	 * @access private
56
+	 * @return EE_Log
57
+	 */
58
+	private function __construct()
59
+	{
60
+
61
+		if (! EE_Registry::instance()->CFG->admin->use_remote_logging) {
62
+			return;
63
+		}
64
+
65
+		$this->_remote_logging_url = EE_Registry::instance()->CFG->admin->remote_logging_url;
66
+		$this->_remote_log = '';
67
+
68
+		if (EE_Registry::instance()->CFG->admin->use_remote_logging) {
69
+			add_action('shutdown', array($this, 'send_log'), 9999);
70
+		}
71
+	}
72
+
73
+
74
+	/**
75
+	 *    verify_filesystem
76
+	 * tests that the required files and folders exist and are writable
77
+	 *
78
+	 */
79
+	public function verify_filesystem()
80
+	{
81
+		$msg = esc_html__(
82
+			'The Local File Logging functionality was removed permanently. Remote Logging is recommended instead.',
83
+			'event_espresso'
84
+		);
85
+		EE_Error::doing_it_wrong(
86
+			__METHOD__,
87
+			$msg,
88
+			'4.10.1.p'
89
+		);
90
+	}
91
+
92
+
93
+	/**
94
+	 *    _format_message
95
+	 *    makes yer log entries look all purdy
96
+	 *
97
+	 * @param string $file
98
+	 * @param string $function
99
+	 * @param string $message
100
+	 * @param string $type
101
+	 * @return string
102
+	 */
103
+	private function _format_message($file = '', $function = '', $message = '', $type = '')
104
+	{
105
+		$msg = '----------------------------------------------------------------------------------------' . PHP_EOL;
106
+		$msg .= '[' . current_time('mysql') . '] ';
107
+		$msg .= ! empty($file) ? basename($file) : '';
108
+		$msg .= ! empty($file) && ! empty($function) ? ' -> ' : '';
109
+		$msg .= ! empty($function) ? $function . '()' : '';
110
+		$msg .= PHP_EOL;
111
+		$type = ! empty($type) ? $type : 'log message';
112
+		$msg .= ! empty($message) ? "\t" . '[' . $type . '] ' . $message . PHP_EOL : '';
113
+		return $msg;
114
+	}
115
+
116
+
117
+	/**
118
+	 *    log
119
+	 * adds content to the EE_Log->_log property which gets written to file during the WP 'shutdown' hookpoint via the
120
+	 * EE_Log::write_log() callback
121
+	 *
122
+	 * @param string $file
123
+	 * @param string $function
124
+	 * @param string $message
125
+	 * @param string $type
126
+	 */
127
+	public function log($file = '', $function = '', $message = '', $type = '')
128
+	{
129
+		$this->_log .= $this->_format_message($file, $function, $message, $type);
130
+	}
131
+
132
+
133
+	/**
134
+	 * write_log
135
+	 * appends the results of the 'AHEE_log' filter to the espresso log file
136
+	 */
137
+	public function write_log()
138
+	{
139
+		$msg = esc_html__(
140
+			'The Local File Logging functionality was removed permanently. Remote Logging is recommended instead.',
141
+			'event_espresso'
142
+		);
143
+		EE_Error::doing_it_wrong(
144
+			__METHOD__,
145
+			$msg,
146
+			'4.10.1.p'
147
+		);
148
+	}
149
+
150
+
151
+	/**
152
+	 * send_log
153
+	 * sends the espresso log to a remote URL via a PHP cURL request
154
+	 */
155
+	public function send_log()
156
+	{
157
+
158
+		if (empty($this->_remote_logging_url)) {
159
+			return;
160
+		}
161
+
162
+		$data = 'domain=' . $_SERVER['HTTP_HOST'];
163
+		$data .= '&ip=' . $_SERVER['SERVER_ADDR'];
164
+		$data .= '&server_type=' . $_SERVER['SERVER_SOFTWARE'];
165
+		$data .= '&time=' . time();
166
+		$data .= '&remote_log=' . $this->_log;
167
+		$data .= '&request_array=' . json_encode($_REQUEST);
168
+		$data .= '&action=save';
169
+
170
+		if (defined('EELOGGING_PASS')) {
171
+			$data .= '&pass=' . EELOGGING_PASS;
172
+		}
173
+		if (defined('EELOGGING_KEY')) {
174
+			$data .= '&key=' . EELOGGING_KEY;
175
+		}
176
+
177
+		$c = curl_init($this->_remote_logging_url);
178
+		curl_setopt($c, CURLOPT_POST, true);
179
+		curl_setopt($c, CURLOPT_POSTFIELDS, $data);
180
+		curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
181
+		curl_exec($c);
182
+		curl_close($c);
183
+	}
184
+
185
+
186
+	/**
187
+	 * write_debug
188
+	 * writes the contents of the current request's $_GET and $_POST arrays to a log file.
189
+	 * previous entries are overwritten
190
+	 */
191
+	public function write_debug()
192
+	{
193
+		$msg = esc_html__(
194
+			'The Local File Logging functionality was removed permanently. Remote Logging is recommended instead.',
195
+			'event_espresso'
196
+		);
197
+		EE_Error::doing_it_wrong(
198
+			__METHOD__,
199
+			$msg,
200
+			'4.10.1.p'
201
+		);
202
+	}
203
+
204
+
205
+	/**
206
+	 * __clone
207
+	 */
208
+	public function __clone()
209
+	{
210
+		trigger_error(__('Clone is not allowed.', 'event_espresso'), E_USER_ERROR);
211
+	}
212 212
 }
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 1 patch
Indentation   +2676 added lines, -2676 removed lines patch added patch discarded remove patch
@@ -15,2680 +15,2680 @@
 block discarded – undo
15 15
 class Events_Admin_Page extends EE_Admin_Page_CPT
16 16
 {
17 17
 
18
-    /**
19
-     * This will hold the event object for event_details screen.
20
-     *
21
-     * @access protected
22
-     * @var EE_Event $_event
23
-     */
24
-    protected $_event;
25
-
26
-
27
-    /**
28
-     * This will hold the category object for category_details screen.
29
-     *
30
-     * @var stdClass $_category
31
-     */
32
-    protected $_category;
33
-
34
-
35
-    /**
36
-     * This will hold the event model instance
37
-     *
38
-     * @var EEM_Event $_event_model
39
-     */
40
-    protected $_event_model;
41
-
42
-
43
-    /**
44
-     * @var EE_Event
45
-     */
46
-    protected $_cpt_model_obj = false;
47
-
48
-
49
-    /**
50
-     * Initialize page props for this admin page group.
51
-     */
52
-    protected function _init_page_props()
53
-    {
54
-        $this->page_slug = EVENTS_PG_SLUG;
55
-        $this->page_label = EVENTS_LABEL;
56
-        $this->_admin_base_url = EVENTS_ADMIN_URL;
57
-        $this->_admin_base_path = EVENTS_ADMIN;
58
-        $this->_cpt_model_names = array(
59
-            'create_new' => 'EEM_Event',
60
-            'edit'       => 'EEM_Event',
61
-        );
62
-        $this->_cpt_edit_routes = array(
63
-            'espresso_events' => 'edit',
64
-        );
65
-        add_action(
66
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
67
-            array($this, 'verify_event_edit'),
68
-            10,
69
-            2
70
-        );
71
-    }
72
-
73
-
74
-    /**
75
-     * Sets the ajax hooks used for this admin page group.
76
-     */
77
-    protected function _ajax_hooks()
78
-    {
79
-        add_action('wp_ajax_ee_save_timezone_setting', array($this, 'save_timezonestring_setting'));
80
-    }
81
-
82
-
83
-    /**
84
-     * Sets the page properties for this admin page group.
85
-     */
86
-    protected function _define_page_props()
87
-    {
88
-        $this->_admin_page_title = EVENTS_LABEL;
89
-        $this->_labels = array(
90
-            'buttons'      => array(
91
-                'add'             => esc_html__('Add New Event', 'event_espresso'),
92
-                'edit'            => esc_html__('Edit Event', 'event_espresso'),
93
-                'delete'          => esc_html__('Delete Event', 'event_espresso'),
94
-                'add_category'    => esc_html__('Add New Category', 'event_espresso'),
95
-                'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
96
-                'delete_category' => esc_html__('Delete Category', 'event_espresso'),
97
-            ),
98
-            'editor_title' => array(
99
-                'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
100
-            ),
101
-            'publishbox'   => array(
102
-                'create_new'        => esc_html__('Save New Event', 'event_espresso'),
103
-                'edit'              => esc_html__('Update Event', 'event_espresso'),
104
-                'add_category'      => esc_html__('Save New Category', 'event_espresso'),
105
-                'edit_category'     => esc_html__('Update Category', 'event_espresso'),
106
-                'template_settings' => esc_html__('Update Settings', 'event_espresso'),
107
-            ),
108
-        );
109
-    }
110
-
111
-
112
-    /**
113
-     * Sets the page routes property for this admin page group.
114
-     */
115
-    protected function _set_page_routes()
116
-    {
117
-        // load formatter helper
118
-        // load field generator helper
119
-        // is there a evt_id in the request?
120
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
121
-            ? $this->_req_data['EVT_ID']
122
-            : 0;
123
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
124
-        $this->_page_routes = array(
125
-            'default'                       => array(
126
-                'func'       => '_events_overview_list_table',
127
-                'capability' => 'ee_read_events',
128
-            ),
129
-            'create_new'                    => array(
130
-                'func'       => '_create_new_cpt_item',
131
-                'capability' => 'ee_edit_events',
132
-            ),
133
-            'edit'                          => array(
134
-                'func'       => '_edit_cpt_item',
135
-                'capability' => 'ee_edit_event',
136
-                'obj_id'     => $evt_id,
137
-            ),
138
-            'copy_event'                    => array(
139
-                'func'       => '_copy_events',
140
-                'capability' => 'ee_edit_event',
141
-                'obj_id'     => $evt_id,
142
-                'noheader'   => true,
143
-            ),
144
-            'trash_event'                   => array(
145
-                'func'       => '_trash_or_restore_event',
146
-                'args'       => array('event_status' => 'trash'),
147
-                'capability' => 'ee_delete_event',
148
-                'obj_id'     => $evt_id,
149
-                'noheader'   => true,
150
-            ),
151
-            'trash_events'                  => array(
152
-                'func'       => '_trash_or_restore_events',
153
-                'args'       => array('event_status' => 'trash'),
154
-                'capability' => 'ee_delete_events',
155
-                'noheader'   => true,
156
-            ),
157
-            'restore_event'                 => array(
158
-                'func'       => '_trash_or_restore_event',
159
-                'args'       => array('event_status' => 'draft'),
160
-                'capability' => 'ee_delete_event',
161
-                'obj_id'     => $evt_id,
162
-                'noheader'   => true,
163
-            ),
164
-            'restore_events'                => array(
165
-                'func'       => '_trash_or_restore_events',
166
-                'args'       => array('event_status' => 'draft'),
167
-                'capability' => 'ee_delete_events',
168
-                'noheader'   => true,
169
-            ),
170
-            'delete_event'                  => array(
171
-                'func'       => '_delete_event',
172
-                'capability' => 'ee_delete_event',
173
-                'obj_id'     => $evt_id,
174
-                'noheader'   => true,
175
-            ),
176
-            'delete_events'                 => array(
177
-                'func'       => '_delete_events',
178
-                'capability' => 'ee_delete_events',
179
-                'noheader'   => true,
180
-            ),
181
-            'view_report'                   => array(
182
-                'func'      => '_view_report',
183
-                'capablity' => 'ee_edit_events',
184
-            ),
185
-            'default_event_settings'        => array(
186
-                'func'       => '_default_event_settings',
187
-                'capability' => 'manage_options',
188
-            ),
189
-            'update_default_event_settings' => array(
190
-                'func'       => '_update_default_event_settings',
191
-                'capability' => 'manage_options',
192
-                'noheader'   => true,
193
-            ),
194
-            'template_settings'             => array(
195
-                'func'       => '_template_settings',
196
-                'capability' => 'manage_options',
197
-            ),
198
-            // event category tab related
199
-            'add_category'                  => array(
200
-                'func'       => '_category_details',
201
-                'capability' => 'ee_edit_event_category',
202
-                'args'       => array('add'),
203
-            ),
204
-            'edit_category'                 => array(
205
-                'func'       => '_category_details',
206
-                'capability' => 'ee_edit_event_category',
207
-                'args'       => array('edit'),
208
-            ),
209
-            'delete_categories'             => array(
210
-                'func'       => '_delete_categories',
211
-                'capability' => 'ee_delete_event_category',
212
-                'noheader'   => true,
213
-            ),
214
-            'delete_category'               => array(
215
-                'func'       => '_delete_categories',
216
-                'capability' => 'ee_delete_event_category',
217
-                'noheader'   => true,
218
-            ),
219
-            'insert_category'               => array(
220
-                'func'       => '_insert_or_update_category',
221
-                'args'       => array('new_category' => true),
222
-                'capability' => 'ee_edit_event_category',
223
-                'noheader'   => true,
224
-            ),
225
-            'update_category'               => array(
226
-                'func'       => '_insert_or_update_category',
227
-                'args'       => array('new_category' => false),
228
-                'capability' => 'ee_edit_event_category',
229
-                'noheader'   => true,
230
-            ),
231
-            'category_list'                 => array(
232
-                'func'       => '_category_list_table',
233
-                'capability' => 'ee_manage_event_categories',
234
-            ),
235
-        );
236
-    }
237
-
238
-
239
-    /**
240
-     * Set the _page_config property for this admin page group.
241
-     */
242
-    protected function _set_page_config()
243
-    {
244
-        $this->_page_config = array(
245
-            'default'                => array(
246
-                'nav'           => array(
247
-                    'label' => esc_html__('Overview', 'event_espresso'),
248
-                    'order' => 10,
249
-                ),
250
-                'list_table'    => 'Events_Admin_List_Table',
251
-                'help_tabs'     => array(
252
-                    'events_overview_help_tab'                       => array(
253
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
254
-                        'filename' => 'events_overview',
255
-                    ),
256
-                    'events_overview_table_column_headings_help_tab' => array(
257
-                        'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
258
-                        'filename' => 'events_overview_table_column_headings',
259
-                    ),
260
-                    'events_overview_filters_help_tab'               => array(
261
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
262
-                        'filename' => 'events_overview_filters',
263
-                    ),
264
-                    'events_overview_view_help_tab'                  => array(
265
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
266
-                        'filename' => 'events_overview_views',
267
-                    ),
268
-                    'events_overview_other_help_tab'                 => array(
269
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
270
-                        'filename' => 'events_overview_other',
271
-                    ),
272
-                ),
273
-                'help_tour'     => array(
274
-                    'Event_Overview_Help_Tour',
275
-                    // 'New_Features_Test_Help_Tour' for testing multiple help tour
276
-                ),
277
-                'qtips'         => array(
278
-                    'EE_Event_List_Table_Tips',
279
-                ),
280
-                'require_nonce' => false,
281
-            ),
282
-            'create_new'             => array(
283
-                'nav'           => array(
284
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
285
-                    'order'      => 5,
286
-                    'persistent' => false,
287
-                ),
288
-                'metaboxes'     => array('_register_event_editor_meta_boxes'),
289
-                'help_tabs'     => array(
290
-                    'event_editor_help_tab'                            => array(
291
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
292
-                        'filename' => 'event_editor',
293
-                    ),
294
-                    'event_editor_title_richtexteditor_help_tab'       => array(
295
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
296
-                        'filename' => 'event_editor_title_richtexteditor',
297
-                    ),
298
-                    'event_editor_venue_details_help_tab'              => array(
299
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
300
-                        'filename' => 'event_editor_venue_details',
301
-                    ),
302
-                    'event_editor_event_datetimes_help_tab'            => array(
303
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
304
-                        'filename' => 'event_editor_event_datetimes',
305
-                    ),
306
-                    'event_editor_event_tickets_help_tab'              => array(
307
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
308
-                        'filename' => 'event_editor_event_tickets',
309
-                    ),
310
-                    'event_editor_event_registration_options_help_tab' => array(
311
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
312
-                        'filename' => 'event_editor_event_registration_options',
313
-                    ),
314
-                    'event_editor_tags_categories_help_tab'            => array(
315
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
316
-                        'filename' => 'event_editor_tags_categories',
317
-                    ),
318
-                    'event_editor_questions_registrants_help_tab'      => array(
319
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
320
-                        'filename' => 'event_editor_questions_registrants',
321
-                    ),
322
-                    'event_editor_save_new_event_help_tab'             => array(
323
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
324
-                        'filename' => 'event_editor_save_new_event',
325
-                    ),
326
-                    'event_editor_other_help_tab'                      => array(
327
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
328
-                        'filename' => 'event_editor_other',
329
-                    ),
330
-                ),
331
-                'help_tour'     => array(
332
-                    'Event_Editor_Help_Tour',
333
-                ),
334
-                'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
335
-                'require_nonce' => false,
336
-            ),
337
-            'edit'                   => array(
338
-                'nav'           => array(
339
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
340
-                    'order'      => 5,
341
-                    'persistent' => false,
342
-                    'url'        => isset($this->_req_data['post'])
343
-                        ? EE_Admin_Page::add_query_args_and_nonce(
344
-                            array('post' => $this->_req_data['post'], 'action' => 'edit'),
345
-                            $this->_current_page_view_url
346
-                        )
347
-                        : $this->_admin_base_url,
348
-                ),
349
-                'metaboxes'     => array('_register_event_editor_meta_boxes'),
350
-                'help_tabs'     => array(
351
-                    'event_editor_help_tab'                            => array(
352
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
353
-                        'filename' => 'event_editor',
354
-                    ),
355
-                    'event_editor_title_richtexteditor_help_tab'       => array(
356
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
357
-                        'filename' => 'event_editor_title_richtexteditor',
358
-                    ),
359
-                    'event_editor_venue_details_help_tab'              => array(
360
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
361
-                        'filename' => 'event_editor_venue_details',
362
-                    ),
363
-                    'event_editor_event_datetimes_help_tab'            => array(
364
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
365
-                        'filename' => 'event_editor_event_datetimes',
366
-                    ),
367
-                    'event_editor_event_tickets_help_tab'              => array(
368
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
369
-                        'filename' => 'event_editor_event_tickets',
370
-                    ),
371
-                    'event_editor_event_registration_options_help_tab' => array(
372
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
373
-                        'filename' => 'event_editor_event_registration_options',
374
-                    ),
375
-                    'event_editor_tags_categories_help_tab'            => array(
376
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
377
-                        'filename' => 'event_editor_tags_categories',
378
-                    ),
379
-                    'event_editor_questions_registrants_help_tab'      => array(
380
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
381
-                        'filename' => 'event_editor_questions_registrants',
382
-                    ),
383
-                    'event_editor_save_new_event_help_tab'             => array(
384
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
385
-                        'filename' => 'event_editor_save_new_event',
386
-                    ),
387
-                    'event_editor_other_help_tab'                      => array(
388
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
389
-                        'filename' => 'event_editor_other',
390
-                    ),
391
-                ),
392
-                'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
393
-                'require_nonce' => false,
394
-            ),
395
-            'default_event_settings' => array(
396
-                'nav'           => array(
397
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
398
-                    'order' => 40,
399
-                ),
400
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
401
-                'labels'        => array(
402
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
403
-                ),
404
-                'help_tabs'     => array(
405
-                    'default_settings_help_tab'        => array(
406
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
407
-                        'filename' => 'events_default_settings',
408
-                    ),
409
-                    'default_settings_status_help_tab' => array(
410
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
411
-                        'filename' => 'events_default_settings_status',
412
-                    ),
413
-                    'default_maximum_tickets_help_tab' => array(
414
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
415
-                        'filename' => 'events_default_settings_max_tickets',
416
-                    ),
417
-                ),
418
-                'help_tour'     => array('Event_Default_Settings_Help_Tour'),
419
-                'require_nonce' => false,
420
-            ),
421
-            // template settings
422
-            'template_settings'      => array(
423
-                'nav'           => array(
424
-                    'label' => esc_html__('Templates', 'event_espresso'),
425
-                    'order' => 30,
426
-                ),
427
-                'metaboxes'     => $this->_default_espresso_metaboxes,
428
-                'help_tabs'     => array(
429
-                    'general_settings_templates_help_tab' => array(
430
-                        'title'    => esc_html__('Templates', 'event_espresso'),
431
-                        'filename' => 'general_settings_templates',
432
-                    ),
433
-                ),
434
-                'help_tour'     => array('Templates_Help_Tour'),
435
-                'require_nonce' => false,
436
-            ),
437
-            // event category stuff
438
-            'add_category'           => array(
439
-                'nav'           => array(
440
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
441
-                    'order'      => 15,
442
-                    'persistent' => false,
443
-                ),
444
-                'help_tabs'     => array(
445
-                    'add_category_help_tab' => array(
446
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
447
-                        'filename' => 'events_add_category',
448
-                    ),
449
-                ),
450
-                'help_tour'     => array('Event_Add_Category_Help_Tour'),
451
-                'metaboxes'     => array('_publish_post_box'),
452
-                'require_nonce' => false,
453
-            ),
454
-            'edit_category'          => array(
455
-                'nav'           => array(
456
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
457
-                    'order'      => 15,
458
-                    'persistent' => false,
459
-                    'url'        => isset($this->_req_data['EVT_CAT_ID'])
460
-                        ? add_query_arg(
461
-                            array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']),
462
-                            $this->_current_page_view_url
463
-                        )
464
-                        : $this->_admin_base_url,
465
-                ),
466
-                'help_tabs'     => array(
467
-                    'edit_category_help_tab' => array(
468
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
469
-                        'filename' => 'events_edit_category',
470
-                    ),
471
-                ),
472
-                /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
473
-                'metaboxes'     => array('_publish_post_box'),
474
-                'require_nonce' => false,
475
-            ),
476
-            'category_list'          => array(
477
-                'nav'           => array(
478
-                    'label' => esc_html__('Categories', 'event_espresso'),
479
-                    'order' => 20,
480
-                ),
481
-                'list_table'    => 'Event_Categories_Admin_List_Table',
482
-                'help_tabs'     => array(
483
-                    'events_categories_help_tab'                       => array(
484
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
485
-                        'filename' => 'events_categories',
486
-                    ),
487
-                    'events_categories_table_column_headings_help_tab' => array(
488
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
489
-                        'filename' => 'events_categories_table_column_headings',
490
-                    ),
491
-                    'events_categories_view_help_tab'                  => array(
492
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
493
-                        'filename' => 'events_categories_views',
494
-                    ),
495
-                    'events_categories_other_help_tab'                 => array(
496
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
497
-                        'filename' => 'events_categories_other',
498
-                    ),
499
-                ),
500
-                'help_tour'     => array(
501
-                    'Event_Categories_Help_Tour',
502
-                ),
503
-                'metaboxes'     => $this->_default_espresso_metaboxes,
504
-                'require_nonce' => false,
505
-            ),
506
-        );
507
-    }
508
-
509
-
510
-    /**
511
-     * Used to register any global screen options if necessary for every route in this admin page group.
512
-     */
513
-    protected function _add_screen_options()
514
-    {
515
-    }
516
-
517
-
518
-    /**
519
-     * Implementing the screen options for the 'default' route.
520
-     */
521
-    protected function _add_screen_options_default()
522
-    {
523
-        $this->_per_page_screen_option();
524
-    }
525
-
526
-
527
-    /**
528
-     * Implementing screen options for the category list route.
529
-     */
530
-    protected function _add_screen_options_category_list()
531
-    {
532
-        $page_title = $this->_admin_page_title;
533
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
534
-        $this->_per_page_screen_option();
535
-        $this->_admin_page_title = $page_title;
536
-    }
537
-
538
-
539
-    /**
540
-     * Used to register any global feature pointers for the admin page group.
541
-     */
542
-    protected function _add_feature_pointers()
543
-    {
544
-    }
545
-
546
-
547
-    /**
548
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
549
-     */
550
-    public function load_scripts_styles()
551
-    {
552
-        wp_register_style(
553
-            'events-admin-css',
554
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
555
-            array(),
556
-            EVENT_ESPRESSO_VERSION
557
-        );
558
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
559
-        wp_enqueue_style('events-admin-css');
560
-        wp_enqueue_style('ee-cat-admin');
561
-        // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
562
-        // registers for all views
563
-        // scripts
564
-        wp_register_script(
565
-            'event_editor_js',
566
-            EVENTS_ASSETS_URL . 'event_editor.js',
567
-            array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
568
-            EVENT_ESPRESSO_VERSION,
569
-            true
570
-        );
571
-    }
572
-
573
-
574
-    /**
575
-     * Enqueuing scripts and styles specific to this view
576
-     */
577
-    public function load_scripts_styles_create_new()
578
-    {
579
-        $this->load_scripts_styles_edit();
580
-    }
581
-
582
-
583
-    /**
584
-     * Enqueuing scripts and styles specific to this view
585
-     */
586
-    public function load_scripts_styles_edit()
587
-    {
588
-        // styles
589
-        wp_enqueue_style('espresso-ui-theme');
590
-        wp_register_style(
591
-            'event-editor-css',
592
-            EVENTS_ASSETS_URL . 'event-editor.css',
593
-            array('ee-admin-css'),
594
-            EVENT_ESPRESSO_VERSION
595
-        );
596
-        wp_enqueue_style('event-editor-css');
597
-        // scripts
598
-        wp_register_script(
599
-            'event-datetime-metabox',
600
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
601
-            array('event_editor_js', 'ee-datepicker'),
602
-            EVENT_ESPRESSO_VERSION
603
-        );
604
-        wp_enqueue_script('event-datetime-metabox');
605
-    }
606
-
607
-
608
-    /**
609
-     * Populating the _views property for the category list table view.
610
-     */
611
-    protected function _set_list_table_views_category_list()
612
-    {
613
-        $this->_views = array(
614
-            'all' => array(
615
-                'slug'        => 'all',
616
-                'label'       => esc_html__('All', 'event_espresso'),
617
-                'count'       => 0,
618
-                'bulk_action' => array(
619
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
620
-                ),
621
-            ),
622
-        );
623
-    }
624
-
625
-
626
-    /**
627
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
628
-     */
629
-    public function admin_init()
630
-    {
631
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
632
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
633
-            'event_espresso'
634
-        );
635
-    }
636
-
637
-
638
-    /**
639
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
640
-     * group.
641
-     */
642
-    public function admin_notices()
643
-    {
644
-    }
645
-
646
-
647
-    /**
648
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
649
-     * this admin page group.
650
-     */
651
-    public function admin_footer_scripts()
652
-    {
653
-    }
654
-
655
-
656
-    /**
657
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
658
-     * warning (via EE_Error::add_error());
659
-     *
660
-     * @param  EE_Event $event Event object
661
-     * @param string    $req_type
662
-     * @return void
663
-     * @throws EE_Error
664
-     * @access public
665
-     */
666
-    public function verify_event_edit($event = null, $req_type = '')
667
-    {
668
-        // don't need to do this when processing
669
-        if (! empty($req_type)) {
670
-            return;
671
-        }
672
-        // no event?
673
-        if (empty($event)) {
674
-            // set event
675
-            $event = $this->_cpt_model_obj;
676
-        }
677
-        // STILL no event?
678
-        if (! $event instanceof EE_Event) {
679
-            return;
680
-        }
681
-        $orig_status = $event->status();
682
-        // first check if event is active.
683
-        if ($orig_status === EEM_Event::cancelled
684
-            || $orig_status === EEM_Event::postponed
685
-            || $event->is_expired()
686
-            || $event->is_inactive()
687
-        ) {
688
-            return;
689
-        }
690
-        // made it here so it IS active... next check that any of the tickets are sold.
691
-        if ($event->is_sold_out(true)) {
692
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
693
-                EE_Error::add_attention(
694
-                    sprintf(
695
-                        esc_html__(
696
-                            'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
697
-                            'event_espresso'
698
-                        ),
699
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
700
-                    )
701
-                );
702
-            }
703
-            return;
704
-        } elseif ($orig_status === EEM_Event::sold_out) {
705
-            EE_Error::add_attention(
706
-                sprintf(
707
-                    esc_html__(
708
-                        'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
709
-                        'event_espresso'
710
-                    ),
711
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
712
-                )
713
-            );
714
-        }
715
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
716
-        if (! $event->tickets_on_sale()) {
717
-            return;
718
-        }
719
-        // made it here so show warning
720
-        $this->_edit_event_warning();
721
-    }
722
-
723
-
724
-    /**
725
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
726
-     * When needed, hook this into a EE_Error::add_error() notice.
727
-     *
728
-     * @access protected
729
-     * @return void
730
-     */
731
-    protected function _edit_event_warning()
732
-    {
733
-        // we don't want to add warnings during these requests
734
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
735
-            return;
736
-        }
737
-        EE_Error::add_attention(
738
-            sprintf(
739
-                esc_html__(
740
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
741
-                    'event_espresso'
742
-                ),
743
-                '<a class="espresso-help-tab-lnk">',
744
-                '</a>'
745
-            )
746
-        );
747
-    }
748
-
749
-
750
-    /**
751
-     * When a user is creating a new event, notify them if they haven't set their timezone.
752
-     * Otherwise, do the normal logic
753
-     *
754
-     * @return string
755
-     * @throws \EE_Error
756
-     */
757
-    protected function _create_new_cpt_item()
758
-    {
759
-        $has_timezone_string = get_option('timezone_string');
760
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
761
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) {
762
-            EE_Error::add_attention(
763
-                sprintf(
764
-                    __(
765
-                        'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
766
-                        'event_espresso'
767
-                    ),
768
-                    '<br>',
769
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
770
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
771
-                    . '</select>',
772
-                    '<button class="button button-secondary timezone-submit">',
773
-                    '</button><span class="spinner"></span>'
774
-                ),
775
-                __FILE__,
776
-                __FUNCTION__,
777
-                __LINE__
778
-            );
779
-        }
780
-        return parent::_create_new_cpt_item();
781
-    }
782
-
783
-
784
-    /**
785
-     * Sets the _views property for the default route in this admin page group.
786
-     */
787
-    protected function _set_list_table_views_default()
788
-    {
789
-        $this->_views = array(
790
-            'all'   => array(
791
-                'slug'        => 'all',
792
-                'label'       => esc_html__('View All Events', 'event_espresso'),
793
-                'count'       => 0,
794
-                'bulk_action' => array(
795
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
796
-                ),
797
-            ),
798
-            'draft' => array(
799
-                'slug'        => 'draft',
800
-                'label'       => esc_html__('Draft', 'event_espresso'),
801
-                'count'       => 0,
802
-                'bulk_action' => array(
803
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
804
-                ),
805
-            ),
806
-        );
807
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
808
-            $this->_views['trash'] = array(
809
-                'slug'        => 'trash',
810
-                'label'       => esc_html__('Trash', 'event_espresso'),
811
-                'count'       => 0,
812
-                'bulk_action' => array(
813
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
814
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
815
-                ),
816
-            );
817
-        }
818
-    }
819
-
820
-
821
-    /**
822
-     * Provides the legend item array for the default list table view.
823
-     *
824
-     * @return array
825
-     */
826
-    protected function _event_legend_items()
827
-    {
828
-        $items = array(
829
-            'view_details'   => array(
830
-                'class' => 'dashicons dashicons-search',
831
-                'desc'  => esc_html__('View Event', 'event_espresso'),
832
-            ),
833
-            'edit_event'     => array(
834
-                'class' => 'ee-icon ee-icon-calendar-edit',
835
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
836
-            ),
837
-            'view_attendees' => array(
838
-                'class' => 'dashicons dashicons-groups',
839
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
840
-            ),
841
-        );
842
-        $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
843
-        $statuses = array(
844
-            'sold_out_status'  => array(
845
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
846
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
847
-            ),
848
-            'active_status'    => array(
849
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
850
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
851
-            ),
852
-            'upcoming_status'  => array(
853
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
854
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
855
-            ),
856
-            'postponed_status' => array(
857
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
858
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
859
-            ),
860
-            'cancelled_status' => array(
861
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
862
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
863
-            ),
864
-            'expired_status'   => array(
865
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
866
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
867
-            ),
868
-            'inactive_status'  => array(
869
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
870
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
871
-            ),
872
-        );
873
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
874
-        return array_merge($items, $statuses);
875
-    }
876
-
877
-
878
-    /**
879
-     * @return EEM_Event
880
-     */
881
-    private function _event_model()
882
-    {
883
-        if (! $this->_event_model instanceof EEM_Event) {
884
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
885
-        }
886
-        return $this->_event_model;
887
-    }
888
-
889
-
890
-    /**
891
-     * Adds extra buttons to the WP CPT permalink field row.
892
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
893
-     *
894
-     * @param  string $return    the current html
895
-     * @param  int    $id        the post id for the page
896
-     * @param  string $new_title What the title is
897
-     * @param  string $new_slug  what the slug is
898
-     * @return string            The new html string for the permalink area
899
-     */
900
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
901
-    {
902
-        // make sure this is only when editing
903
-        if (! empty($id)) {
904
-            $post = get_post($id);
905
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
906
-                       . esc_html__('Shortcode', 'event_espresso')
907
-                       . '</a> ';
908
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
909
-                       . $post->ID
910
-                       . ']">';
911
-        }
912
-        return $return;
913
-    }
914
-
915
-
916
-    /**
917
-     * _events_overview_list_table
918
-     * This contains the logic for showing the events_overview list
919
-     *
920
-     * @access protected
921
-     * @return void
922
-     * @throws \EE_Error
923
-     */
924
-    protected function _events_overview_list_table()
925
-    {
926
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
927
-        $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
928
-            ? (array) $this->_template_args['after_list_table']
929
-            : array();
930
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
931
-                . EEH_Template::get_button_or_link(
932
-                    get_post_type_archive_link('espresso_events'),
933
-                    esc_html__("View Event Archive Page", "event_espresso"),
934
-                    'button'
935
-                );
936
-        $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
937
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
938
-            'create_new',
939
-            'add',
940
-            array(),
941
-            'add-new-h2'
942
-        );
943
-        $this->display_admin_list_table_page_with_no_sidebar();
944
-    }
945
-
946
-
947
-    /**
948
-     * this allows for extra misc actions in the default WP publish box
949
-     *
950
-     * @return void
951
-     */
952
-    public function extra_misc_actions_publish_box()
953
-    {
954
-        $this->_generate_publish_box_extra_content();
955
-    }
956
-
957
-
958
-    /**
959
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
960
-     * saved.
961
-     * Typically you would use this to save any additional data.
962
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
963
-     * ALSO very important.  When a post transitions from scheduled to published,
964
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
965
-     * other meta saves. So MAKE sure that you handle this accordingly.
966
-     *
967
-     * @access protected
968
-     * @abstract
969
-     * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
970
-     * @param  object $post    The post object of the cpt that was saved.
971
-     * @return void
972
-     * @throws \EE_Error
973
-     */
974
-    protected function _insert_update_cpt_item($post_id, $post)
975
-    {
976
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
977
-            // get out we're not processing an event save.
978
-            return;
979
-        }
980
-        $event_values = array(
981
-            'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
982
-            'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
983
-            'EVT_additional_limit'            => min(
984
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
985
-                ! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
986
-            ),
987
-            'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
988
-                ? $this->_req_data['EVT_default_registration_status']
989
-                : EE_Registry::instance()->CFG->registration->default_STS_ID,
990
-            'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
991
-            'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
992
-            'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
993
-                ? $this->_req_data['timezone_string'] : null,
994
-            'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
995
-                ? $this->_req_data['externalURL'] : null,
996
-            'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
997
-                ? $this->_req_data['event_phone'] : null,
998
-        );
999
-        // update event
1000
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1001
-        // get event_object for other metaboxes... though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id!
1002
-        $get_one_where = array(
1003
-            $this->_event_model()->primary_key_name() => $post_id,
1004
-            'OR'                                      => array(
1005
-                'status'   => $post->post_status,
1006
-                // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1007
-                // but the returned object here has a status of "publish", so use the original post status as well
1008
-                'status*1' => $this->_req_data['original_post_status'],
1009
-            ),
1010
-        );
1011
-        $event = $this->_event_model()->get_one(array($get_one_where));
1012
-        // the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1013
-        $event_update_callbacks = apply_filters(
1014
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1015
-            array(
1016
-                array($this, '_default_venue_update'),
1017
-                array($this, '_default_tickets_update'),
1018
-            )
1019
-        );
1020
-        $att_success = true;
1021
-        foreach ($event_update_callbacks as $e_callback) {
1022
-            $_success = is_callable($e_callback)
1023
-                ? call_user_func($e_callback, $event, $this->_req_data)
1024
-                : false;
1025
-            // if ANY of these updates fail then we want the appropriate global error message
1026
-            $att_success = ! $att_success ? $att_success : $_success;
1027
-        }
1028
-        // any errors?
1029
-        if ($success && false === $att_success) {
1030
-            EE_Error::add_error(
1031
-                esc_html__(
1032
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1033
-                    'event_espresso'
1034
-                ),
1035
-                __FILE__,
1036
-                __FUNCTION__,
1037
-                __LINE__
1038
-            );
1039
-        } elseif ($success === false) {
1040
-            EE_Error::add_error(
1041
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1042
-                __FILE__,
1043
-                __FUNCTION__,
1044
-                __LINE__
1045
-            );
1046
-        }
1047
-    }
1048
-
1049
-
1050
-    /**
1051
-     * @see parent::restore_item()
1052
-     * @param int $post_id
1053
-     * @param int $revision_id
1054
-     */
1055
-    protected function _restore_cpt_item($post_id, $revision_id)
1056
-    {
1057
-        // copy existing event meta to new post
1058
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1059
-        if ($post_evt instanceof EE_Event) {
1060
-            // meta revision restore
1061
-            $post_evt->restore_revision($revision_id);
1062
-            // related objs restore
1063
-            $post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1064
-        }
1065
-    }
1066
-
1067
-
1068
-    /**
1069
-     * Attach the venue to the Event
1070
-     *
1071
-     * @param  \EE_Event $evtobj Event Object to add the venue to
1072
-     * @param  array     $data   The request data from the form
1073
-     * @return bool           Success or fail.
1074
-     */
1075
-    protected function _default_venue_update(\EE_Event $evtobj, $data)
1076
-    {
1077
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1078
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1079
-        $rows_affected = null;
1080
-        $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1081
-        // very important.  If we don't have a venue name...
1082
-        // then we'll get out because not necessary to create empty venue
1083
-        if (empty($data['venue_title'])) {
1084
-            return false;
1085
-        }
1086
-        $venue_array = array(
1087
-            'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1088
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1089
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1090
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1091
-            'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1092
-                : null,
1093
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1094
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1095
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1096
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1097
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1098
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1099
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1100
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1101
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1102
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1103
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1104
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1105
-            'status'              => 'publish',
1106
-        );
1107
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1108
-        if (! empty($venue_id)) {
1109
-            $update_where = array($venue_model->primary_key_name() => $venue_id);
1110
-            $rows_affected = $venue_model->update($venue_array, array($update_where));
1111
-            // we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1112
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1113
-            return $rows_affected > 0 ? true : false;
1114
-        } else {
1115
-            // we insert the venue
1116
-            $venue_id = $venue_model->insert($venue_array);
1117
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1118
-            return ! empty($venue_id) ? true : false;
1119
-        }
1120
-        // when we have the ancestor come in it's already been handled by the revision save.
1121
-    }
1122
-
1123
-
1124
-    /**
1125
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1126
-     *
1127
-     * @param  EE_Event $evtobj The Event object we're attaching data to
1128
-     * @param  array    $data   The request data from the form
1129
-     * @return array
1130
-     */
1131
-    protected function _default_tickets_update(EE_Event $evtobj, $data)
1132
-    {
1133
-        $success = true;
1134
-        $saved_dtt = null;
1135
-        $saved_tickets = array();
1136
-        $incoming_date_formats = array('Y-m-d', 'h:i a');
1137
-        foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1138
-            // trim all values to ensure any excess whitespace is removed.
1139
-            $dtt = array_map('trim', $dtt);
1140
-            $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1141
-                : $dtt['DTT_EVT_start'];
1142
-            $datetime_values = array(
1143
-                'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1144
-                'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1145
-                'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1146
-                'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1147
-                'DTT_order'     => $row,
1148
-            );
1149
-            // if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
1150
-            if (! empty($dtt['DTT_ID'])) {
1151
-                $DTM = EE_Registry::instance()
1152
-                                  ->load_model('Datetime', array($evtobj->get_timezone()))
1153
-                                  ->get_one_by_ID($dtt['DTT_ID']);
1154
-                $DTM->set_date_format($incoming_date_formats[0]);
1155
-                $DTM->set_time_format($incoming_date_formats[1]);
1156
-                foreach ($datetime_values as $field => $value) {
1157
-                    $DTM->set($field, $value);
1158
-                }
1159
-                // make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.  We need to do this so we dont' TRASH the parent DTT.
1160
-                $saved_dtts[ $DTM->ID() ] = $DTM;
1161
-            } else {
1162
-                $DTM = EE_Registry::instance()->load_class(
1163
-                    'Datetime',
1164
-                    array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1165
-                    false,
1166
-                    false
1167
-                );
1168
-                foreach ($datetime_values as $field => $value) {
1169
-                    $DTM->set($field, $value);
1170
-                }
1171
-            }
1172
-            $DTM->save();
1173
-            $DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1174
-            // load DTT helper
1175
-            // before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1176
-            if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1177
-                $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1178
-                $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1179
-                $DTT->save();
1180
-            }
1181
-            // now we got to make sure we add the new DTT_ID to the $saved_dtts array  because it is possible there was a new one created for the autosave.
1182
-            $saved_dtt = $DTT;
1183
-            $success = ! $success ? $success : $DTT;
1184
-            // if ANY of these updates fail then we want the appropriate global error message.
1185
-            // //todo this is actually sucky we need a better error message but this is what it is for now.
1186
-        }
1187
-        // no dtts get deleted so we don't do any of that logic here.
1188
-        // update tickets next
1189
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1190
-        foreach ($data['edit_tickets'] as $row => $tkt) {
1191
-            $incoming_date_formats = array('Y-m-d', 'h:i a');
1192
-            $update_prices = false;
1193
-            $ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1194
-                ? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0;
1195
-            // trim inputs to ensure any excess whitespace is removed.
1196
-            $tkt = array_map('trim', $tkt);
1197
-            if (empty($tkt['TKT_start_date'])) {
1198
-                // let's use now in the set timezone.
1199
-                $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1200
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1201
-            }
1202
-            if (empty($tkt['TKT_end_date'])) {
1203
-                // use the start date of the first datetime
1204
-                $dtt = $evtobj->first_datetime();
1205
-                $tkt['TKT_end_date'] = $dtt->start_date_and_time(
1206
-                    $incoming_date_formats[0],
1207
-                    $incoming_date_formats[1]
1208
-                );
1209
-            }
1210
-            $TKT_values = array(
1211
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1212
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1213
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1214
-                'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1215
-                'TKT_start_date'  => $tkt['TKT_start_date'],
1216
-                'TKT_end_date'    => $tkt['TKT_end_date'],
1217
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1218
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1219
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1220
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1221
-                'TKT_row'         => $row,
1222
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1223
-                'TKT_price'       => $ticket_price,
1224
-            );
1225
-            // if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
1226
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1227
-                $TKT_values['TKT_ID'] = 0;
1228
-                $TKT_values['TKT_is_default'] = 0;
1229
-                $TKT_values['TKT_price'] = $ticket_price;
1230
-                $update_prices = true;
1231
-            }
1232
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1233
-            // we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
1234
-            // keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1235
-            if (! empty($tkt['TKT_ID'])) {
1236
-                $TKT = EE_Registry::instance()
1237
-                                  ->load_model('Ticket', array($evtobj->get_timezone()))
1238
-                                  ->get_one_by_ID($tkt['TKT_ID']);
1239
-                if ($TKT instanceof EE_Ticket) {
1240
-                    $ticket_sold = $TKT->count_related(
1241
-                        'Registration',
1242
-                        array(
1243
-                            array(
1244
-                                'STS_ID' => array(
1245
-                                    'NOT IN',
1246
-                                    array(EEM_Registration::status_id_incomplete),
1247
-                                ),
1248
-                            ),
1249
-                        )
1250
-                    ) > 0 ? true : false;
1251
-                    // let's just check the total price for the existing ticket and determine if it matches the new total price.  if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket.
1252
-                    $create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price')
1253
-                                      && ! $TKT->get('TKT_deleted');
1254
-                    $TKT->set_date_format($incoming_date_formats[0]);
1255
-                    $TKT->set_time_format($incoming_date_formats[1]);
1256
-                    // set new values
1257
-                    foreach ($TKT_values as $field => $value) {
1258
-                        if ($field == 'TKT_qty') {
1259
-                            $TKT->set_qty($value);
1260
-                        } else {
1261
-                            $TKT->set($field, $value);
1262
-                        }
1263
-                    }
1264
-                    // if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1265
-                    if ($create_new_TKT) {
1266
-                        // archive the old ticket first
1267
-                        $TKT->set('TKT_deleted', 1);
1268
-                        $TKT->save();
1269
-                        // make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1270
-                        $saved_tickets[ $TKT->ID() ] = $TKT;
1271
-                        // create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it.
1272
-                        $TKT = clone $TKT;
1273
-                        $TKT->set('TKT_ID', 0);
1274
-                        $TKT->set('TKT_deleted', 0);
1275
-                        $TKT->set('TKT_price', $ticket_price);
1276
-                        $TKT->set('TKT_sold', 0);
1277
-                        // now we need to make sure that $new prices are created as well and attached to new ticket.
1278
-                        $update_prices = true;
1279
-                    }
1280
-                    // make sure price is set if it hasn't been already
1281
-                    $TKT->set('TKT_price', $ticket_price);
1282
-                }
1283
-            } else {
1284
-                // no TKT_id so a new TKT
1285
-                $TKT_values['TKT_price'] = $ticket_price;
1286
-                $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1287
-                if ($TKT instanceof EE_Ticket) {
1288
-                    // need to reset values to properly account for the date formats
1289
-                    $TKT->set_date_format($incoming_date_formats[0]);
1290
-                    $TKT->set_time_format($incoming_date_formats[1]);
1291
-                    $TKT->set_timezone($evtobj->get_timezone());
1292
-                    // set new values
1293
-                    foreach ($TKT_values as $field => $value) {
1294
-                        if ($field == 'TKT_qty') {
1295
-                            $TKT->set_qty($value);
1296
-                        } else {
1297
-                            $TKT->set($field, $value);
1298
-                        }
1299
-                    }
1300
-                    $update_prices = true;
1301
-                }
1302
-            }
1303
-            // cap ticket qty by datetime reg limits
1304
-            $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1305
-            // update ticket.
1306
-            $TKT->save();
1307
-            // before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1308
-            if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1309
-                $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1310
-                $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1311
-                $TKT->save();
1312
-            }
1313
-            // initially let's add the ticket to the dtt
1314
-            $saved_dtt->_add_relation_to($TKT, 'Ticket');
1315
-            $saved_tickets[ $TKT->ID() ] = $TKT;
1316
-            // add prices to ticket
1317
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1318
-        }
1319
-        // however now we need to handle permanently deleting tickets via the ui.  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.  However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db.
1320
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
1321
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1322
-        foreach ($tickets_removed as $id) {
1323
-            $id = absint($id);
1324
-            // get the ticket for this id
1325
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1326
-            // need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold)
1327
-            $dtts = $tkt_to_remove->get_many_related('Datetime');
1328
-            foreach ($dtts as $dtt) {
1329
-                $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1330
-            }
1331
-            // need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1332
-            $tkt_to_remove->delete_related_permanently('Price');
1333
-            // finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1334
-            $tkt_to_remove->delete_permanently();
1335
-        }
1336
-        return array($saved_dtt, $saved_tickets);
1337
-    }
1338
-
1339
-
1340
-    /**
1341
-     * This attaches a list of given prices to a ticket.
1342
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1343
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1344
-     * price info and prices are automatically "archived" via the ticket.
1345
-     *
1346
-     * @access  private
1347
-     * @param array     $prices     Array of prices from the form.
1348
-     * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1349
-     * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1350
-     * @return  void
1351
-     */
1352
-    private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1353
-    {
1354
-        foreach ($prices as $row => $prc) {
1355
-            $PRC_values = array(
1356
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1357
-                'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1358
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1359
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1360
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1361
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1362
-                'PRC_order'      => $row,
1363
-            );
1364
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
1365
-                $PRC_values['PRC_ID'] = 0;
1366
-                $PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1367
-            } else {
1368
-                $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1369
-                // update this price with new values
1370
-                foreach ($PRC_values as $field => $newprc) {
1371
-                    $PRC->set($field, $newprc);
1372
-                }
1373
-                $PRC->save();
1374
-            }
1375
-            $ticket->_add_relation_to($PRC, 'Price');
1376
-        }
1377
-    }
1378
-
1379
-
1380
-    /**
1381
-     * Add in our autosave ajax handlers
1382
-     *
1383
-     */
1384
-    protected function _ee_autosave_create_new()
1385
-    {
1386
-    }
1387
-
1388
-
1389
-    /**
1390
-     * More autosave handlers.
1391
-     */
1392
-    protected function _ee_autosave_edit()
1393
-    {
1394
-        return; // TEMPORARILY EXITING CAUSE THIS IS A TODO
1395
-    }
1396
-
1397
-
1398
-    /**
1399
-     *    _generate_publish_box_extra_content
1400
-     */
1401
-    private function _generate_publish_box_extra_content()
1402
-    {
1403
-        // load formatter helper
1404
-        // args for getting related registrations
1405
-        $approved_query_args = array(
1406
-            array(
1407
-                'REG_deleted' => 0,
1408
-                'STS_ID'      => EEM_Registration::status_id_approved,
1409
-            ),
1410
-        );
1411
-        $not_approved_query_args = array(
1412
-            array(
1413
-                'REG_deleted' => 0,
1414
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1415
-            ),
1416
-        );
1417
-        $pending_payment_query_args = array(
1418
-            array(
1419
-                'REG_deleted' => 0,
1420
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1421
-            ),
1422
-        );
1423
-        // publish box
1424
-        $publish_box_extra_args = array(
1425
-            'view_approved_reg_url'        => add_query_arg(
1426
-                array(
1427
-                    'action'      => 'default',
1428
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1429
-                    '_reg_status' => EEM_Registration::status_id_approved,
1430
-                ),
1431
-                REG_ADMIN_URL
1432
-            ),
1433
-            'view_not_approved_reg_url'    => add_query_arg(
1434
-                array(
1435
-                    'action'      => 'default',
1436
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1437
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1438
-                ),
1439
-                REG_ADMIN_URL
1440
-            ),
1441
-            'view_pending_payment_reg_url' => add_query_arg(
1442
-                array(
1443
-                    'action'      => 'default',
1444
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1445
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1446
-                ),
1447
-                REG_ADMIN_URL
1448
-            ),
1449
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1450
-                'Registration',
1451
-                $approved_query_args
1452
-            ),
1453
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1454
-                'Registration',
1455
-                $not_approved_query_args
1456
-            ),
1457
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1458
-                'Registration',
1459
-                $pending_payment_query_args
1460
-            ),
1461
-            'misc_pub_section_class'       => apply_filters(
1462
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1463
-                'misc-pub-section'
1464
-            ),
1465
-        );
1466
-        ob_start();
1467
-        do_action(
1468
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1469
-            $this->_cpt_model_obj
1470
-        );
1471
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1472
-        // load template
1473
-        EEH_Template::display_template(
1474
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1475
-            $publish_box_extra_args
1476
-        );
1477
-    }
1478
-
1479
-
1480
-    /**
1481
-     * @return EE_Event
1482
-     */
1483
-    public function get_event_object()
1484
-    {
1485
-        return $this->_cpt_model_obj;
1486
-    }
1487
-
1488
-
1489
-
1490
-
1491
-    /** METABOXES * */
1492
-    /**
1493
-     * _register_event_editor_meta_boxes
1494
-     * add all metaboxes related to the event_editor
1495
-     *
1496
-     * @return void
1497
-     */
1498
-    protected function _register_event_editor_meta_boxes()
1499
-    {
1500
-        $this->verify_cpt_object();
1501
-        // add_meta_box(
1502
-        //     'espresso_event_editor_tickets',
1503
-        //     esc_html__('Event Datetime & Ticket', 'event_espresso'),
1504
-        //     array($this, 'ticket_metabox'),
1505
-        //     $this->page_slug,
1506
-        //     'normal',
1507
-        //     'high'
1508
-        // );
1509
-        add_meta_box(
1510
-            'espresso_event_editor_event_options',
1511
-            esc_html__('Event Registration Options', 'event_espresso'),
1512
-            array($this, 'registration_options_meta_box'),
1513
-            $this->page_slug,
1514
-            'side',
1515
-            'default'
1516
-        );
1517
-        // NOTE: if you're looking for other metaboxes in here,
1518
-        // where a metabox has a related management page in the admin
1519
-        // you will find it setup in the related management page's "_Hooks" file.
1520
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1521
-    }
1522
-
1523
-
1524
-    /**
1525
-     * @throws DomainException
1526
-     * @throws EE_Error
1527
-     */
1528
-    public function ticket_metabox()
1529
-    {
1530
-        $existing_datetime_ids = $existing_ticket_ids = array();
1531
-        // defaults for template args
1532
-        $template_args = array(
1533
-            'existing_datetime_ids'    => '',
1534
-            'event_datetime_help_link' => '',
1535
-            'ticket_options_help_link' => '',
1536
-            'time'                     => null,
1537
-            'ticket_rows'              => '',
1538
-            'existing_ticket_ids'      => '',
1539
-            'total_ticket_rows'        => 1,
1540
-            'ticket_js_structure'      => '',
1541
-            'trash_icon'               => 'ee-lock-icon',
1542
-            'disabled'                 => '',
1543
-        );
1544
-        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1545
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1546
-        /**
1547
-         * 1. Start with retrieving Datetimes
1548
-         * 2. Fore each datetime get related tickets
1549
-         * 3. For each ticket get related prices
1550
-         */
1551
-        $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1552
-        /** @type EE_Datetime $first_datetime */
1553
-        $first_datetime = reset($times);
1554
-        // do we get related tickets?
1555
-        if ($first_datetime instanceof EE_Datetime
1556
-            && $first_datetime->ID() !== 0
1557
-        ) {
1558
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1559
-            $template_args['time'] = $first_datetime;
1560
-            $related_tickets = $first_datetime->tickets(
1561
-                array(
1562
-                    array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1563
-                    'default_where_conditions' => 'none',
1564
-                )
1565
-            );
1566
-            if (! empty($related_tickets)) {
1567
-                $template_args['total_ticket_rows'] = count($related_tickets);
1568
-                $row = 0;
1569
-                foreach ($related_tickets as $ticket) {
1570
-                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1571
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1572
-                    $row++;
1573
-                }
1574
-            } else {
1575
-                $template_args['total_ticket_rows'] = 1;
1576
-                /** @type EE_Ticket $ticket */
1577
-                $ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1578
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1579
-            }
1580
-        } else {
1581
-            $template_args['time'] = $times[0];
1582
-            /** @type EE_Ticket $ticket */
1583
-            $ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1584
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1585
-            // NOTE: we're just sending the first default row
1586
-            // (decaf can't manage default tickets so this should be sufficient);
1587
-        }
1588
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1589
-            'event_editor_event_datetimes_help_tab'
1590
-        );
1591
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1592
-        $template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1593
-        $template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1594
-        $template_args['ticket_js_structure'] = $this->_get_ticket_row(
1595
-            EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1596
-            true
1597
-        );
1598
-        $template = apply_filters(
1599
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1600
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1601
-        );
1602
-        EEH_Template::display_template($template, $template_args);
1603
-    }
1604
-
1605
-
1606
-    /**
1607
-     * Setup an individual ticket form for the decaf event editor page
1608
-     *
1609
-     * @access private
1610
-     * @param  EE_Ticket $ticket   the ticket object
1611
-     * @param  boolean   $skeleton whether we're generating a skeleton for js manipulation
1612
-     * @param int        $row
1613
-     * @return string generated html for the ticket row.
1614
-     */
1615
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1616
-    {
1617
-        $template_args = array(
1618
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1619
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1620
-                : '',
1621
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1622
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1623
-            'TKT_name'            => $ticket->get('TKT_name'),
1624
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1625
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1626
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1627
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1628
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1629
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1630
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1631
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1632
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1633
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1634
-                : ' disabled=disabled',
1635
-        );
1636
-        $price = $ticket->ID() !== 0
1637
-            ? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1638
-            : EE_Registry::instance()->load_model('Price')->create_default_object();
1639
-        $price_args = array(
1640
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1641
-            'PRC_amount'            => $price->get('PRC_amount'),
1642
-            'PRT_ID'                => $price->get('PRT_ID'),
1643
-            'PRC_ID'                => $price->get('PRC_ID'),
1644
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1645
-        );
1646
-        // make sure we have default start and end dates if skeleton
1647
-        // handle rows that should NOT be empty
1648
-        if (empty($template_args['TKT_start_date'])) {
1649
-            // if empty then the start date will be now.
1650
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1651
-        }
1652
-        if (empty($template_args['TKT_end_date'])) {
1653
-            // get the earliest datetime (if present);
1654
-            $earliest_dtt = $this->_cpt_model_obj->ID() > 0
1655
-                ? $this->_cpt_model_obj->get_first_related(
1656
-                    'Datetime',
1657
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1658
-                )
1659
-                : null;
1660
-            if (! empty($earliest_dtt)) {
1661
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1662
-            } else {
1663
-                $template_args['TKT_end_date'] = date(
1664
-                    'Y-m-d h:i a',
1665
-                    mktime(0, 0, 0, date("m"), date("d") + 7, date("Y"))
1666
-                );
1667
-            }
1668
-        }
1669
-        $template_args = array_merge($template_args, $price_args);
1670
-        $template = apply_filters(
1671
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1672
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1673
-            $ticket
1674
-        );
1675
-        return EEH_Template::display_template($template, $template_args, true);
1676
-    }
1677
-
1678
-
1679
-    /**
1680
-     * @throws DomainException
1681
-     */
1682
-    public function registration_options_meta_box()
1683
-    {
1684
-        $yes_no_values = array(
1685
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1686
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1687
-        );
1688
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1689
-            array(
1690
-                EEM_Registration::status_id_cancelled,
1691
-                EEM_Registration::status_id_declined,
1692
-                EEM_Registration::status_id_incomplete,
1693
-            ),
1694
-            true
1695
-        );
1696
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1697
-        $template_args['_event'] = $this->_cpt_model_obj;
1698
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1699
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1700
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1701
-            'default_reg_status',
1702
-            $default_reg_status_values,
1703
-            $this->_cpt_model_obj->default_registration_status()
1704
-        );
1705
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
1706
-            'display_desc',
1707
-            $yes_no_values,
1708
-            $this->_cpt_model_obj->display_description()
1709
-        );
1710
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1711
-            'display_ticket_selector',
1712
-            $yes_no_values,
1713
-            $this->_cpt_model_obj->display_ticket_selector(),
1714
-            '',
1715
-            '',
1716
-            false
1717
-        );
1718
-        $template_args['additional_registration_options'] = apply_filters(
1719
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1720
-            '',
1721
-            $template_args,
1722
-            $yes_no_values,
1723
-            $default_reg_status_values
1724
-        );
1725
-        EEH_Template::display_template(
1726
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1727
-            $template_args
1728
-        );
1729
-    }
1730
-
1731
-
1732
-    /**
1733
-     * _get_events()
1734
-     * This method simply returns all the events (for the given _view and paging)
1735
-     *
1736
-     * @access public
1737
-     * @param int  $per_page     count of items per page (20 default);
1738
-     * @param int  $current_page what is the current page being viewed.
1739
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1740
-     *                           If FALSE then we return an array of event objects
1741
-     *                           that match the given _view and paging parameters.
1742
-     * @return array an array of event objects.
1743
-     */
1744
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1745
-    {
1746
-        $EEME = $this->_event_model();
1747
-        $offset = ($current_page - 1) * $per_page;
1748
-        $limit = $count ? null : $offset . ',' . $per_page;
1749
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1750
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1751
-        if (isset($this->_req_data['month_range'])) {
1752
-            $pieces = explode(' ', $this->_req_data['month_range'], 3);
1753
-            // simulate the FIRST day of the month, that fixes issues for months like February
1754
-            // where PHP doesn't know what to assume for date.
1755
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1756
-            $month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1757
-            $year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1758
-        }
1759
-        $where = array();
1760
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1761
-        // determine what post_status our condition will have for the query.
1762
-        switch ($status) {
1763
-            case 'month':
1764
-            case 'today':
1765
-            case null:
1766
-            case 'all':
1767
-                break;
1768
-            case 'draft':
1769
-                $where['status'] = array('IN', array('draft', 'auto-draft'));
1770
-                break;
1771
-            default:
1772
-                $where['status'] = $status;
1773
-        }
1774
-        // categories?
1775
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1776
-            ? $this->_req_data['EVT_CAT'] : null;
1777
-        if (! empty($category)) {
1778
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1779
-            $where['Term_Taxonomy.term_id'] = $category;
1780
-        }
1781
-        // date where conditions
1782
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1783
-        if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1784
-            $DateTime = new DateTime(
1785
-                $year_r . '-' . $month_r . '-01 00:00:00',
1786
-                new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1787
-            );
1788
-            $start = $DateTime->format(implode(' ', $start_formats));
1789
-            $end = $DateTime->setDate(
1790
-                $year_r,
1791
-                $month_r,
1792
-                $DateTime
1793
-                    ->format('t')
1794
-            )->setTime(23, 59, 59)
1795
-                            ->format(implode(' ', $start_formats));
1796
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1797
-        } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') {
1798
-            $DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1799
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1800
-            $end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1801
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1802
-        } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') {
1803
-            $now = date('Y-m-01');
1804
-            $DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1805
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1806
-            $end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1807
-                            ->setTime(23, 59, 59)
1808
-                            ->format(implode(' ', $start_formats));
1809
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1810
-        }
1811
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1812
-            $where['EVT_wp_user'] = get_current_user_id();
1813
-        } else {
1814
-            if (! isset($where['status'])) {
1815
-                if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1816
-                    $where['OR'] = array(
1817
-                        'status*restrict_private' => array('!=', 'private'),
1818
-                        'AND'                     => array(
1819
-                            'status*inclusive' => array('=', 'private'),
1820
-                            'EVT_wp_user'      => get_current_user_id(),
1821
-                        ),
1822
-                    );
1823
-                }
1824
-            }
1825
-        }
1826
-        if (isset($this->_req_data['EVT_wp_user'])) {
1827
-            if ($this->_req_data['EVT_wp_user'] != get_current_user_id()
1828
-                && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1829
-            ) {
1830
-                $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1831
-            }
1832
-        }
1833
-        // search query handling
1834
-        if (isset($this->_req_data['s'])) {
1835
-            $search_string = '%' . $this->_req_data['s'] . '%';
1836
-            $where['OR'] = array(
1837
-                'EVT_name'       => array('LIKE', $search_string),
1838
-                'EVT_desc'       => array('LIKE', $search_string),
1839
-                'EVT_short_desc' => array('LIKE', $search_string),
1840
-            );
1841
-        }
1842
-        // filter events by venue.
1843
-        if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) {
1844
-            $where['Venue.VNU_ID'] = absint($this->_req_data['venue']);
1845
-        }
1846
-        $where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1847
-        $query_params = apply_filters(
1848
-            'FHEE__Events_Admin_Page__get_events__query_params',
1849
-            array(
1850
-                $where,
1851
-                'limit'    => $limit,
1852
-                'order_by' => $orderby,
1853
-                'order'    => $order,
1854
-                'group_by' => 'EVT_ID',
1855
-            ),
1856
-            $this->_req_data
1857
-        );
1858
-        // let's first check if we have special requests coming in.
1859
-        if (isset($this->_req_data['active_status'])) {
1860
-            switch ($this->_req_data['active_status']) {
1861
-                case 'upcoming':
1862
-                    return $EEME->get_upcoming_events($query_params, $count);
1863
-                    break;
1864
-                case 'expired':
1865
-                    return $EEME->get_expired_events($query_params, $count);
1866
-                    break;
1867
-                case 'active':
1868
-                    return $EEME->get_active_events($query_params, $count);
1869
-                    break;
1870
-                case 'inactive':
1871
-                    return $EEME->get_inactive_events($query_params, $count);
1872
-                    break;
1873
-            }
1874
-        }
1875
-
1876
-        $events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1877
-        return $events;
1878
-    }
1879
-
1880
-
1881
-    /**
1882
-     * handling for WordPress CPT actions (trash, restore, delete)
1883
-     *
1884
-     * @param string $post_id
1885
-     */
1886
-    public function trash_cpt_item($post_id)
1887
-    {
1888
-        $this->_req_data['EVT_ID'] = $post_id;
1889
-        $this->_trash_or_restore_event('trash', false);
1890
-    }
1891
-
1892
-
1893
-    /**
1894
-     * @param string $post_id
1895
-     */
1896
-    public function restore_cpt_item($post_id)
1897
-    {
1898
-        $this->_req_data['EVT_ID'] = $post_id;
1899
-        $this->_trash_or_restore_event('draft', false);
1900
-    }
1901
-
1902
-
1903
-    /**
1904
-     * @param string $post_id
1905
-     */
1906
-    public function delete_cpt_item($post_id)
1907
-    {
1908
-        $this->_req_data['EVT_ID'] = $post_id;
1909
-        $this->_delete_event(false);
1910
-    }
1911
-
1912
-
1913
-    /**
1914
-     * _trash_or_restore_event
1915
-     *
1916
-     * @access protected
1917
-     * @param  string $event_status
1918
-     * @param bool    $redirect_after
1919
-     */
1920
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
1921
-    {
1922
-        // determine the event id and set to array.
1923
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
1924
-        // loop thru events
1925
-        if ($EVT_ID) {
1926
-            // clean status
1927
-            $event_status = sanitize_key($event_status);
1928
-            // grab status
1929
-            if (! empty($event_status)) {
1930
-                $success = $this->_change_event_status($EVT_ID, $event_status);
1931
-            } else {
1932
-                $success = false;
1933
-                $msg = esc_html__(
1934
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1935
-                    'event_espresso'
1936
-                );
1937
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1938
-            }
1939
-        } else {
1940
-            $success = false;
1941
-            $msg = esc_html__(
1942
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
1943
-                'event_espresso'
1944
-            );
1945
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1946
-        }
1947
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1948
-        if ($redirect_after) {
1949
-            $this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
1950
-        }
1951
-    }
1952
-
1953
-
1954
-    /**
1955
-     * _trash_or_restore_events
1956
-     *
1957
-     * @access protected
1958
-     * @param  string $event_status
1959
-     * @return void
1960
-     */
1961
-    protected function _trash_or_restore_events($event_status = 'trash')
1962
-    {
1963
-        // clean status
1964
-        $event_status = sanitize_key($event_status);
1965
-        // grab status
1966
-        if (! empty($event_status)) {
1967
-            $success = true;
1968
-            // determine the event id and set to array.
1969
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
1970
-            // loop thru events
1971
-            foreach ($EVT_IDs as $EVT_ID) {
1972
-                if ($EVT_ID = absint($EVT_ID)) {
1973
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
1974
-                    $success = $results !== false ? $success : false;
1975
-                } else {
1976
-                    $msg = sprintf(
1977
-                        esc_html__(
1978
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
1979
-                            'event_espresso'
1980
-                        ),
1981
-                        $EVT_ID
1982
-                    );
1983
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1984
-                    $success = false;
1985
-                }
1986
-            }
1987
-        } else {
1988
-            $success = false;
1989
-            $msg = esc_html__(
1990
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1991
-                'event_espresso'
1992
-            );
1993
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1994
-        }
1995
-        // in order to force a pluralized result message we need to send back a success status greater than 1
1996
-        $success = $success ? 2 : false;
1997
-        $action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1998
-        $this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
1999
-    }
2000
-
2001
-
2002
-    /**
2003
-     * _trash_or_restore_events
2004
-     *
2005
-     * @access  private
2006
-     * @param  int    $EVT_ID
2007
-     * @param  string $event_status
2008
-     * @return bool
2009
-     */
2010
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2011
-    {
2012
-        // grab event id
2013
-        if (! $EVT_ID) {
2014
-            $msg = esc_html__(
2015
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2016
-                'event_espresso'
2017
-            );
2018
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2019
-            return false;
2020
-        }
2021
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2022
-        // clean status
2023
-        $event_status = sanitize_key($event_status);
2024
-        // grab status
2025
-        if (empty($event_status)) {
2026
-            $msg = esc_html__(
2027
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2028
-                'event_espresso'
2029
-            );
2030
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2031
-            return false;
2032
-        }
2033
-        // was event trashed or restored ?
2034
-        switch ($event_status) {
2035
-            case 'draft':
2036
-                $action = 'restored from the trash';
2037
-                $hook = 'AHEE_event_restored_from_trash';
2038
-                break;
2039
-            case 'trash':
2040
-                $action = 'moved to the trash';
2041
-                $hook = 'AHEE_event_moved_to_trash';
2042
-                break;
2043
-            default:
2044
-                $action = 'updated';
2045
-                $hook = false;
2046
-        }
2047
-        // use class to change status
2048
-        $this->_cpt_model_obj->set_status($event_status);
2049
-        $success = $this->_cpt_model_obj->save();
2050
-        if ($success === false) {
2051
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2052
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2053
-            return false;
2054
-        }
2055
-        if ($hook) {
2056
-            do_action($hook);
2057
-        }
2058
-        return true;
2059
-    }
2060
-
2061
-
2062
-    /**
2063
-     * _delete_event
2064
-     *
2065
-     * @access protected
2066
-     * @param bool $redirect_after
2067
-     */
2068
-    protected function _delete_event($redirect_after = true)
2069
-    {
2070
-        // determine the event id and set to array.
2071
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2072
-        $EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2073
-        // loop thru events
2074
-        if ($EVT_ID) {
2075
-            $success = $this->_permanently_delete_event($EVT_ID);
2076
-            // get list of events with no prices
2077
-            $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2078
-            // remove this event from the list of events with no prices
2079
-            if (isset($espresso_no_ticket_prices[ $EVT_ID ])) {
2080
-                unset($espresso_no_ticket_prices[ $EVT_ID ]);
2081
-            }
2082
-            update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2083
-        } else {
2084
-            $success = false;
2085
-            $msg = esc_html__(
2086
-                'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2087
-                'event_espresso'
2088
-            );
2089
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2090
-        }
2091
-        if ($redirect_after) {
2092
-            $this->_redirect_after_action(
2093
-                $success,
2094
-                'Event',
2095
-                'deleted',
2096
-                array('action' => 'default', 'status' => 'trash')
2097
-            );
2098
-        }
2099
-    }
2100
-
2101
-
2102
-    /**
2103
-     * _delete_events
2104
-     *
2105
-     * @access protected
2106
-     * @return void
2107
-     */
2108
-    protected function _delete_events()
2109
-    {
2110
-        $success = true;
2111
-        // get list of events with no prices
2112
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2113
-        // determine the event id and set to array.
2114
-        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2115
-        // loop thru events
2116
-        foreach ($EVT_IDs as $EVT_ID) {
2117
-            $EVT_ID = absint($EVT_ID);
2118
-            if ($EVT_ID) {
2119
-                $results = $this->_permanently_delete_event($EVT_ID);
2120
-                $success = $results !== false ? $success : false;
2121
-                // remove this event from the list of events with no prices
2122
-                unset($espresso_no_ticket_prices[ $EVT_ID ]);
2123
-            } else {
2124
-                $success = false;
2125
-                $msg = esc_html__(
2126
-                    'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2127
-                    'event_espresso'
2128
-                );
2129
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2130
-            }
2131
-        }
2132
-        update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2133
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2134
-        $success = $success ? 2 : false;
2135
-        $this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2136
-    }
2137
-
2138
-
2139
-    /**
2140
-     * _permanently_delete_event
2141
-     *
2142
-     * @access  private
2143
-     * @param  int $EVT_ID
2144
-     * @return bool
2145
-     */
2146
-    private function _permanently_delete_event($EVT_ID = 0)
2147
-    {
2148
-        // grab event id
2149
-        if (! $EVT_ID) {
2150
-            $msg = esc_html__(
2151
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2152
-                'event_espresso'
2153
-            );
2154
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2155
-            return false;
2156
-        }
2157
-        if (! $this->_cpt_model_obj instanceof EE_Event
2158
-            || $this->_cpt_model_obj->ID() !== $EVT_ID
2159
-        ) {
2160
-            $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2161
-        }
2162
-        if (! $this->_cpt_model_obj instanceof EE_Event) {
2163
-            return false;
2164
-        }
2165
-        // need to delete related tickets and prices first.
2166
-        $datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2167
-        foreach ($datetimes as $datetime) {
2168
-            $this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2169
-            $tickets = $datetime->get_many_related('Ticket');
2170
-            foreach ($tickets as $ticket) {
2171
-                $ticket->_remove_relation_to($datetime, 'Datetime');
2172
-                $ticket->delete_related_permanently('Price');
2173
-                $ticket->delete_permanently();
2174
-            }
2175
-            $datetime->delete();
2176
-        }
2177
-        // what about related venues or terms?
2178
-        $venues = $this->_cpt_model_obj->get_many_related('Venue');
2179
-        foreach ($venues as $venue) {
2180
-            $this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2181
-        }
2182
-        // any attached question groups?
2183
-        $question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2184
-        if (! empty($question_groups)) {
2185
-            foreach ($question_groups as $question_group) {
2186
-                $this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2187
-            }
2188
-        }
2189
-        // Message Template Groups
2190
-        $this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2191
-        /** @type EE_Term_Taxonomy[] $term_taxonomies */
2192
-        $term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2193
-        foreach ($term_taxonomies as $term_taxonomy) {
2194
-            $this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2195
-        }
2196
-        $success = $this->_cpt_model_obj->delete_permanently();
2197
-        // did it all go as planned ?
2198
-        if ($success) {
2199
-            $msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2200
-            EE_Error::add_success($msg);
2201
-        } else {
2202
-            $msg = sprintf(
2203
-                esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2204
-                $EVT_ID
2205
-            );
2206
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2207
-            return false;
2208
-        }
2209
-        do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2210
-        return true;
2211
-    }
2212
-
2213
-
2214
-    /**
2215
-     * get total number of events
2216
-     *
2217
-     * @access public
2218
-     * @return int
2219
-     */
2220
-    public function total_events()
2221
-    {
2222
-        $count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2223
-        return $count;
2224
-    }
2225
-
2226
-
2227
-    /**
2228
-     * get total number of draft events
2229
-     *
2230
-     * @access public
2231
-     * @return int
2232
-     */
2233
-    public function total_events_draft()
2234
-    {
2235
-        $where = array(
2236
-            'status' => array('IN', array('draft', 'auto-draft')),
2237
-        );
2238
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2239
-        return $count;
2240
-    }
2241
-
2242
-
2243
-    /**
2244
-     * get total number of trashed events
2245
-     *
2246
-     * @access public
2247
-     * @return int
2248
-     */
2249
-    public function total_trashed_events()
2250
-    {
2251
-        $where = array(
2252
-            'status' => 'trash',
2253
-        );
2254
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2255
-        return $count;
2256
-    }
2257
-
2258
-
2259
-    /**
2260
-     *    _default_event_settings
2261
-     *    This generates the Default Settings Tab
2262
-     *
2263
-     * @return void
2264
-     * @throws EE_Error
2265
-     */
2266
-    protected function _default_event_settings()
2267
-    {
2268
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2269
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2270
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2271
-        $this->display_admin_page_with_sidebar();
2272
-    }
2273
-
2274
-
2275
-    /**
2276
-     * Return the form for event settings.
2277
-     *
2278
-     * @return EE_Form_Section_Proper
2279
-     * @throws EE_Error
2280
-     */
2281
-    protected function _default_event_settings_form()
2282
-    {
2283
-        $registration_config = EE_Registry::instance()->CFG->registration;
2284
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2285
-            // exclude
2286
-            array(
2287
-                EEM_Registration::status_id_cancelled,
2288
-                EEM_Registration::status_id_declined,
2289
-                EEM_Registration::status_id_incomplete,
2290
-                EEM_Registration::status_id_wait_list,
2291
-            ),
2292
-            true
2293
-        );
2294
-        return new EE_Form_Section_Proper(
2295
-            array(
2296
-                'name'            => 'update_default_event_settings',
2297
-                'html_id'         => 'update_default_event_settings',
2298
-                'html_class'      => 'form-table',
2299
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2300
-                'subsections'     => apply_filters(
2301
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2302
-                    array(
2303
-                        'default_reg_status'  => new EE_Select_Input(
2304
-                            $registration_stati_for_selection,
2305
-                            array(
2306
-                                'default'         => isset($registration_config->default_STS_ID)
2307
-                                                     && array_key_exists(
2308
-                                                         $registration_config->default_STS_ID,
2309
-                                                         $registration_stati_for_selection
2310
-                                                     )
2311
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2312
-                                    : EEM_Registration::status_id_pending_payment,
2313
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2314
-                                                     . EEH_Template::get_help_tab_link(
2315
-                                                         'default_settings_status_help_tab'
2316
-                                                     ),
2317
-                                'html_help_text'  => esc_html__(
2318
-                                    'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2319
-                                    'event_espresso'
2320
-                                ),
2321
-                            )
2322
-                        ),
2323
-                        'default_max_tickets' => new EE_Integer_Input(
2324
-                            array(
2325
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2326
-                                    ? $registration_config->default_maximum_number_of_tickets
2327
-                                    : EEM_Event::get_default_additional_limit(),
2328
-                                'html_label_text' => esc_html__(
2329
-                                    'Default Maximum Tickets Allowed Per Order:',
2330
-                                    'event_espresso'
2331
-                                )
2332
-                                                     . EEH_Template::get_help_tab_link(
2333
-                                                         'default_maximum_tickets_help_tab"'
2334
-                                                     ),
2335
-                                'html_help_text'  => esc_html__(
2336
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2337
-                                    'event_espresso'
2338
-                                ),
2339
-                            )
2340
-                        ),
2341
-                    )
2342
-                ),
2343
-            )
2344
-        );
2345
-    }
2346
-
2347
-
2348
-    /**
2349
-     * @return void
2350
-     * @throws EE_Error
2351
-     * @throws InvalidArgumentException
2352
-     * @throws InvalidDataTypeException
2353
-     * @throws InvalidInterfaceException
2354
-     */
2355
-    protected function _update_default_event_settings()
2356
-    {
2357
-        $form = $this->_default_event_settings_form();
2358
-        if ($form->was_submitted()) {
2359
-            $form->receive_form_submission();
2360
-            if ($form->is_valid()) {
2361
-                $registration_config = EE_Registry::instance()->CFG->registration;
2362
-                $valid_data = $form->valid_data();
2363
-                if (isset($valid_data['default_reg_status'])) {
2364
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2365
-                }
2366
-                if (isset($valid_data['default_max_tickets'])) {
2367
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2368
-                }
2369
-                do_action(
2370
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2371
-                    $valid_data,
2372
-                    EE_Registry::instance()->CFG,
2373
-                    $this
2374
-                );
2375
-                // update because data was valid!
2376
-                EE_Registry::instance()->CFG->update_espresso_config();
2377
-                EE_Error::overwrite_success();
2378
-                EE_Error::add_success(
2379
-                    __('Default Event Settings were updated', 'event_espresso')
2380
-                );
2381
-            }
2382
-        }
2383
-        $this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true);
2384
-    }
2385
-
2386
-
2387
-    /*************        Templates        *************/
2388
-    protected function _template_settings()
2389
-    {
2390
-        $this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2391
-        $this->_template_args['preview_img'] = '<img src="'
2392
-                                               . EVENTS_ASSETS_URL
2393
-                                               . '/images/'
2394
-                                               . 'caffeinated_template_features.jpg" alt="'
2395
-                                               . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2396
-                                               . '" />';
2397
-        $this->_template_args['preview_text'] = '<strong>'
2398
-                                                . esc_html__(
2399
-                                                    'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2400
-                                                    'event_espresso'
2401
-                                                ) . '</strong>';
2402
-        $this->display_admin_caf_preview_page('template_settings_tab');
2403
-    }
2404
-
2405
-
2406
-    /** Event Category Stuff **/
2407
-    /**
2408
-     * set the _category property with the category object for the loaded page.
2409
-     *
2410
-     * @access private
2411
-     * @return void
2412
-     */
2413
-    private function _set_category_object()
2414
-    {
2415
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2416
-            return;
2417
-        } //already have the category object so get out.
2418
-        // set default category object
2419
-        $this->_set_empty_category_object();
2420
-        // only set if we've got an id
2421
-        if (! isset($this->_req_data['EVT_CAT_ID'])) {
2422
-            return;
2423
-        }
2424
-        $category_id = absint($this->_req_data['EVT_CAT_ID']);
2425
-        $term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2426
-        if (! empty($term)) {
2427
-            $this->_category->category_name = $term->name;
2428
-            $this->_category->category_identifier = $term->slug;
2429
-            $this->_category->category_desc = $term->description;
2430
-            $this->_category->id = $term->term_id;
2431
-            $this->_category->parent = $term->parent;
2432
-        }
2433
-    }
2434
-
2435
-
2436
-    /**
2437
-     * Clears out category properties.
2438
-     */
2439
-    private function _set_empty_category_object()
2440
-    {
2441
-        $this->_category = new stdClass();
2442
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2443
-        $this->_category->id = $this->_category->parent = 0;
2444
-    }
2445
-
2446
-
2447
-    /**
2448
-     * @throws EE_Error
2449
-     */
2450
-    protected function _category_list_table()
2451
-    {
2452
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2453
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2454
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2455
-            'add_category',
2456
-            'add_category',
2457
-            array(),
2458
-            'add-new-h2'
2459
-        );
2460
-        $this->display_admin_list_table_page_with_sidebar();
2461
-    }
2462
-
2463
-
2464
-    /**
2465
-     * Output category details view.
2466
-     */
2467
-    protected function _category_details($view)
2468
-    {
2469
-        // load formatter helper
2470
-        // load field generator helper
2471
-        $route = $view == 'edit' ? 'update_category' : 'insert_category';
2472
-        $this->_set_add_edit_form_tags($route);
2473
-        $this->_set_category_object();
2474
-        $id = ! empty($this->_category->id) ? $this->_category->id : '';
2475
-        $delete_action = 'delete_category';
2476
-        // custom redirect
2477
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2478
-            array('action' => 'category_list'),
2479
-            $this->_admin_base_url
2480
-        );
2481
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2482
-        // take care of contents
2483
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2484
-        $this->display_admin_page_with_sidebar();
2485
-    }
2486
-
2487
-
2488
-    /**
2489
-     * Output category details content.
2490
-     */
2491
-    protected function _category_details_content()
2492
-    {
2493
-        $editor_args['category_desc'] = array(
2494
-            'type'          => 'wp_editor',
2495
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2496
-            'class'         => 'my_editor_custom',
2497
-            'wpeditor_args' => array('media_buttons' => false),
2498
-        );
2499
-        $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2500
-        $all_terms = get_terms(
2501
-            array(EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY),
2502
-            array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2503
-        );
2504
-        // setup category select for term parents.
2505
-        $category_select_values[] = array(
2506
-            'text' => esc_html__('No Parent', 'event_espresso'),
2507
-            'id'   => 0,
2508
-        );
2509
-        foreach ($all_terms as $term) {
2510
-            $category_select_values[] = array(
2511
-                'text' => $term->name,
2512
-                'id'   => $term->term_id,
2513
-            );
2514
-        }
2515
-        $category_select = EEH_Form_Fields::select_input(
2516
-            'category_parent',
2517
-            $category_select_values,
2518
-            $this->_category->parent
2519
-        );
2520
-        $template_args = array(
2521
-            'category'                 => $this->_category,
2522
-            'category_select'          => $category_select,
2523
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2524
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2525
-            'disable'                  => '',
2526
-            'disabled_message'         => false,
2527
-        );
2528
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2529
-        return EEH_Template::display_template($template, $template_args, true);
2530
-    }
2531
-
2532
-
2533
-    /**
2534
-     * Handles deleting categories.
2535
-     */
2536
-    protected function _delete_categories()
2537
-    {
2538
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2539
-            : (array) $this->_req_data['category_id'];
2540
-        foreach ($cat_ids as $cat_id) {
2541
-            $this->_delete_category($cat_id);
2542
-        }
2543
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2544
-        $query_args = array(
2545
-            'action' => 'category_list',
2546
-        );
2547
-        $this->_redirect_after_action(0, '', '', $query_args);
2548
-    }
2549
-
2550
-
2551
-    /**
2552
-     * Handles deleting specific category.
2553
-     *
2554
-     * @param int $cat_id
2555
-     */
2556
-    protected function _delete_category($cat_id)
2557
-    {
2558
-        $cat_id = absint($cat_id);
2559
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2560
-    }
2561
-
2562
-
2563
-    /**
2564
-     * Handles triggering the update or insertion of a new category.
2565
-     *
2566
-     * @param bool $new_category true means we're triggering the insert of a new category.
2567
-     */
2568
-    protected function _insert_or_update_category($new_category)
2569
-    {
2570
-        $cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2571
-        $success = 0; // we already have a success message so lets not send another.
2572
-        if ($cat_id) {
2573
-            $query_args = array(
2574
-                'action'     => 'edit_category',
2575
-                'EVT_CAT_ID' => $cat_id,
2576
-            );
2577
-        } else {
2578
-            $query_args = array('action' => 'add_category');
2579
-        }
2580
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2581
-    }
2582
-
2583
-
2584
-    /**
2585
-     * Inserts or updates category
2586
-     *
2587
-     * @param bool $update (true indicates we're updating a category).
2588
-     * @return bool|mixed|string
2589
-     */
2590
-    private function _insert_category($update = false)
2591
-    {
2592
-        $cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2593
-        $category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2594
-        $category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2595
-        $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2596
-        if (empty($category_name)) {
2597
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2598
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2599
-            return false;
2600
-        }
2601
-        $term_args = array(
2602
-            'name'        => $category_name,
2603
-            'description' => $category_desc,
2604
-            'parent'      => $category_parent,
2605
-        );
2606
-        // was the category_identifier input disabled?
2607
-        if (isset($this->_req_data['category_identifier'])) {
2608
-            $term_args['slug'] = $this->_req_data['category_identifier'];
2609
-        }
2610
-        $insert_ids = $update
2611
-            ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2612
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2613
-        if (! is_array($insert_ids)) {
2614
-            $msg = esc_html__(
2615
-                'An error occurred and the category has not been saved to the database.',
2616
-                'event_espresso'
2617
-            );
2618
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2619
-        } else {
2620
-            $cat_id = $insert_ids['term_id'];
2621
-            $msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2622
-            EE_Error::add_success($msg);
2623
-        }
2624
-        return $cat_id;
2625
-    }
2626
-
2627
-
2628
-    /**
2629
-     * Gets categories or count of categories matching the arguments in the request.
2630
-     *
2631
-     * @param int  $per_page
2632
-     * @param int  $current_page
2633
-     * @param bool $count
2634
-     * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int
2635
-     */
2636
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2637
-    {
2638
-        // testing term stuff
2639
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2640
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2641
-        $limit = ($current_page - 1) * $per_page;
2642
-        $where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2643
-        if (isset($this->_req_data['s'])) {
2644
-            $sstr = '%' . $this->_req_data['s'] . '%';
2645
-            $where['OR'] = array(
2646
-                'Term.name'   => array('LIKE', $sstr),
2647
-                'description' => array('LIKE', $sstr),
2648
-            );
2649
-        }
2650
-        $query_params = array(
2651
-            $where,
2652
-            'order_by'   => array($orderby => $order),
2653
-            'limit'      => $limit . ',' . $per_page,
2654
-            'force_join' => array('Term'),
2655
-        );
2656
-        $categories = $count
2657
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2658
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2659
-        return $categories;
2660
-    }
2661
-
2662
-    /* end category stuff */
2663
-    /**************/
2664
-
2665
-
2666
-    /**
2667
-     * Callback for the `ee_save_timezone_setting` ajax action.
2668
-     *
2669
-     * @throws EE_Error
2670
-     */
2671
-    public function save_timezonestring_setting()
2672
-    {
2673
-        $timezone_string = isset($this->_req_data['timezone_selected'])
2674
-            ? $this->_req_data['timezone_selected']
2675
-            : '';
2676
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2677
-            EE_Error::add_error(
2678
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2679
-                __FILE__,
2680
-                __FUNCTION__,
2681
-                __LINE__
2682
-            );
2683
-            $this->_template_args['error'] = true;
2684
-            $this->_return_json();
2685
-        }
2686
-
2687
-        update_option('timezone_string', $timezone_string);
2688
-        EE_Error::add_success(
2689
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2690
-        );
2691
-        $this->_template_args['success'] = true;
2692
-        $this->_return_json(true, array('action' => 'create_new'));
2693
-    }
18
+	/**
19
+	 * This will hold the event object for event_details screen.
20
+	 *
21
+	 * @access protected
22
+	 * @var EE_Event $_event
23
+	 */
24
+	protected $_event;
25
+
26
+
27
+	/**
28
+	 * This will hold the category object for category_details screen.
29
+	 *
30
+	 * @var stdClass $_category
31
+	 */
32
+	protected $_category;
33
+
34
+
35
+	/**
36
+	 * This will hold the event model instance
37
+	 *
38
+	 * @var EEM_Event $_event_model
39
+	 */
40
+	protected $_event_model;
41
+
42
+
43
+	/**
44
+	 * @var EE_Event
45
+	 */
46
+	protected $_cpt_model_obj = false;
47
+
48
+
49
+	/**
50
+	 * Initialize page props for this admin page group.
51
+	 */
52
+	protected function _init_page_props()
53
+	{
54
+		$this->page_slug = EVENTS_PG_SLUG;
55
+		$this->page_label = EVENTS_LABEL;
56
+		$this->_admin_base_url = EVENTS_ADMIN_URL;
57
+		$this->_admin_base_path = EVENTS_ADMIN;
58
+		$this->_cpt_model_names = array(
59
+			'create_new' => 'EEM_Event',
60
+			'edit'       => 'EEM_Event',
61
+		);
62
+		$this->_cpt_edit_routes = array(
63
+			'espresso_events' => 'edit',
64
+		);
65
+		add_action(
66
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
67
+			array($this, 'verify_event_edit'),
68
+			10,
69
+			2
70
+		);
71
+	}
72
+
73
+
74
+	/**
75
+	 * Sets the ajax hooks used for this admin page group.
76
+	 */
77
+	protected function _ajax_hooks()
78
+	{
79
+		add_action('wp_ajax_ee_save_timezone_setting', array($this, 'save_timezonestring_setting'));
80
+	}
81
+
82
+
83
+	/**
84
+	 * Sets the page properties for this admin page group.
85
+	 */
86
+	protected function _define_page_props()
87
+	{
88
+		$this->_admin_page_title = EVENTS_LABEL;
89
+		$this->_labels = array(
90
+			'buttons'      => array(
91
+				'add'             => esc_html__('Add New Event', 'event_espresso'),
92
+				'edit'            => esc_html__('Edit Event', 'event_espresso'),
93
+				'delete'          => esc_html__('Delete Event', 'event_espresso'),
94
+				'add_category'    => esc_html__('Add New Category', 'event_espresso'),
95
+				'edit_category'   => esc_html__('Edit Category', 'event_espresso'),
96
+				'delete_category' => esc_html__('Delete Category', 'event_espresso'),
97
+			),
98
+			'editor_title' => array(
99
+				'espresso_events' => esc_html__('Enter event title here', 'event_espresso'),
100
+			),
101
+			'publishbox'   => array(
102
+				'create_new'        => esc_html__('Save New Event', 'event_espresso'),
103
+				'edit'              => esc_html__('Update Event', 'event_espresso'),
104
+				'add_category'      => esc_html__('Save New Category', 'event_espresso'),
105
+				'edit_category'     => esc_html__('Update Category', 'event_espresso'),
106
+				'template_settings' => esc_html__('Update Settings', 'event_espresso'),
107
+			),
108
+		);
109
+	}
110
+
111
+
112
+	/**
113
+	 * Sets the page routes property for this admin page group.
114
+	 */
115
+	protected function _set_page_routes()
116
+	{
117
+		// load formatter helper
118
+		// load field generator helper
119
+		// is there a evt_id in the request?
120
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
121
+			? $this->_req_data['EVT_ID']
122
+			: 0;
123
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
124
+		$this->_page_routes = array(
125
+			'default'                       => array(
126
+				'func'       => '_events_overview_list_table',
127
+				'capability' => 'ee_read_events',
128
+			),
129
+			'create_new'                    => array(
130
+				'func'       => '_create_new_cpt_item',
131
+				'capability' => 'ee_edit_events',
132
+			),
133
+			'edit'                          => array(
134
+				'func'       => '_edit_cpt_item',
135
+				'capability' => 'ee_edit_event',
136
+				'obj_id'     => $evt_id,
137
+			),
138
+			'copy_event'                    => array(
139
+				'func'       => '_copy_events',
140
+				'capability' => 'ee_edit_event',
141
+				'obj_id'     => $evt_id,
142
+				'noheader'   => true,
143
+			),
144
+			'trash_event'                   => array(
145
+				'func'       => '_trash_or_restore_event',
146
+				'args'       => array('event_status' => 'trash'),
147
+				'capability' => 'ee_delete_event',
148
+				'obj_id'     => $evt_id,
149
+				'noheader'   => true,
150
+			),
151
+			'trash_events'                  => array(
152
+				'func'       => '_trash_or_restore_events',
153
+				'args'       => array('event_status' => 'trash'),
154
+				'capability' => 'ee_delete_events',
155
+				'noheader'   => true,
156
+			),
157
+			'restore_event'                 => array(
158
+				'func'       => '_trash_or_restore_event',
159
+				'args'       => array('event_status' => 'draft'),
160
+				'capability' => 'ee_delete_event',
161
+				'obj_id'     => $evt_id,
162
+				'noheader'   => true,
163
+			),
164
+			'restore_events'                => array(
165
+				'func'       => '_trash_or_restore_events',
166
+				'args'       => array('event_status' => 'draft'),
167
+				'capability' => 'ee_delete_events',
168
+				'noheader'   => true,
169
+			),
170
+			'delete_event'                  => array(
171
+				'func'       => '_delete_event',
172
+				'capability' => 'ee_delete_event',
173
+				'obj_id'     => $evt_id,
174
+				'noheader'   => true,
175
+			),
176
+			'delete_events'                 => array(
177
+				'func'       => '_delete_events',
178
+				'capability' => 'ee_delete_events',
179
+				'noheader'   => true,
180
+			),
181
+			'view_report'                   => array(
182
+				'func'      => '_view_report',
183
+				'capablity' => 'ee_edit_events',
184
+			),
185
+			'default_event_settings'        => array(
186
+				'func'       => '_default_event_settings',
187
+				'capability' => 'manage_options',
188
+			),
189
+			'update_default_event_settings' => array(
190
+				'func'       => '_update_default_event_settings',
191
+				'capability' => 'manage_options',
192
+				'noheader'   => true,
193
+			),
194
+			'template_settings'             => array(
195
+				'func'       => '_template_settings',
196
+				'capability' => 'manage_options',
197
+			),
198
+			// event category tab related
199
+			'add_category'                  => array(
200
+				'func'       => '_category_details',
201
+				'capability' => 'ee_edit_event_category',
202
+				'args'       => array('add'),
203
+			),
204
+			'edit_category'                 => array(
205
+				'func'       => '_category_details',
206
+				'capability' => 'ee_edit_event_category',
207
+				'args'       => array('edit'),
208
+			),
209
+			'delete_categories'             => array(
210
+				'func'       => '_delete_categories',
211
+				'capability' => 'ee_delete_event_category',
212
+				'noheader'   => true,
213
+			),
214
+			'delete_category'               => array(
215
+				'func'       => '_delete_categories',
216
+				'capability' => 'ee_delete_event_category',
217
+				'noheader'   => true,
218
+			),
219
+			'insert_category'               => array(
220
+				'func'       => '_insert_or_update_category',
221
+				'args'       => array('new_category' => true),
222
+				'capability' => 'ee_edit_event_category',
223
+				'noheader'   => true,
224
+			),
225
+			'update_category'               => array(
226
+				'func'       => '_insert_or_update_category',
227
+				'args'       => array('new_category' => false),
228
+				'capability' => 'ee_edit_event_category',
229
+				'noheader'   => true,
230
+			),
231
+			'category_list'                 => array(
232
+				'func'       => '_category_list_table',
233
+				'capability' => 'ee_manage_event_categories',
234
+			),
235
+		);
236
+	}
237
+
238
+
239
+	/**
240
+	 * Set the _page_config property for this admin page group.
241
+	 */
242
+	protected function _set_page_config()
243
+	{
244
+		$this->_page_config = array(
245
+			'default'                => array(
246
+				'nav'           => array(
247
+					'label' => esc_html__('Overview', 'event_espresso'),
248
+					'order' => 10,
249
+				),
250
+				'list_table'    => 'Events_Admin_List_Table',
251
+				'help_tabs'     => array(
252
+					'events_overview_help_tab'                       => array(
253
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
254
+						'filename' => 'events_overview',
255
+					),
256
+					'events_overview_table_column_headings_help_tab' => array(
257
+						'title'    => esc_html__('Events Overview Table Column Headings', 'event_espresso'),
258
+						'filename' => 'events_overview_table_column_headings',
259
+					),
260
+					'events_overview_filters_help_tab'               => array(
261
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
262
+						'filename' => 'events_overview_filters',
263
+					),
264
+					'events_overview_view_help_tab'                  => array(
265
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
266
+						'filename' => 'events_overview_views',
267
+					),
268
+					'events_overview_other_help_tab'                 => array(
269
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
270
+						'filename' => 'events_overview_other',
271
+					),
272
+				),
273
+				'help_tour'     => array(
274
+					'Event_Overview_Help_Tour',
275
+					// 'New_Features_Test_Help_Tour' for testing multiple help tour
276
+				),
277
+				'qtips'         => array(
278
+					'EE_Event_List_Table_Tips',
279
+				),
280
+				'require_nonce' => false,
281
+			),
282
+			'create_new'             => array(
283
+				'nav'           => array(
284
+					'label'      => esc_html__('Add Event', 'event_espresso'),
285
+					'order'      => 5,
286
+					'persistent' => false,
287
+				),
288
+				'metaboxes'     => array('_register_event_editor_meta_boxes'),
289
+				'help_tabs'     => array(
290
+					'event_editor_help_tab'                            => array(
291
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
292
+						'filename' => 'event_editor',
293
+					),
294
+					'event_editor_title_richtexteditor_help_tab'       => array(
295
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
296
+						'filename' => 'event_editor_title_richtexteditor',
297
+					),
298
+					'event_editor_venue_details_help_tab'              => array(
299
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
300
+						'filename' => 'event_editor_venue_details',
301
+					),
302
+					'event_editor_event_datetimes_help_tab'            => array(
303
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
304
+						'filename' => 'event_editor_event_datetimes',
305
+					),
306
+					'event_editor_event_tickets_help_tab'              => array(
307
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
308
+						'filename' => 'event_editor_event_tickets',
309
+					),
310
+					'event_editor_event_registration_options_help_tab' => array(
311
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
312
+						'filename' => 'event_editor_event_registration_options',
313
+					),
314
+					'event_editor_tags_categories_help_tab'            => array(
315
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
316
+						'filename' => 'event_editor_tags_categories',
317
+					),
318
+					'event_editor_questions_registrants_help_tab'      => array(
319
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
320
+						'filename' => 'event_editor_questions_registrants',
321
+					),
322
+					'event_editor_save_new_event_help_tab'             => array(
323
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
324
+						'filename' => 'event_editor_save_new_event',
325
+					),
326
+					'event_editor_other_help_tab'                      => array(
327
+						'title'    => esc_html__('Event Other', 'event_espresso'),
328
+						'filename' => 'event_editor_other',
329
+					),
330
+				),
331
+				'help_tour'     => array(
332
+					'Event_Editor_Help_Tour',
333
+				),
334
+				'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
335
+				'require_nonce' => false,
336
+			),
337
+			'edit'                   => array(
338
+				'nav'           => array(
339
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
340
+					'order'      => 5,
341
+					'persistent' => false,
342
+					'url'        => isset($this->_req_data['post'])
343
+						? EE_Admin_Page::add_query_args_and_nonce(
344
+							array('post' => $this->_req_data['post'], 'action' => 'edit'),
345
+							$this->_current_page_view_url
346
+						)
347
+						: $this->_admin_base_url,
348
+				),
349
+				'metaboxes'     => array('_register_event_editor_meta_boxes'),
350
+				'help_tabs'     => array(
351
+					'event_editor_help_tab'                            => array(
352
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
353
+						'filename' => 'event_editor',
354
+					),
355
+					'event_editor_title_richtexteditor_help_tab'       => array(
356
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
357
+						'filename' => 'event_editor_title_richtexteditor',
358
+					),
359
+					'event_editor_venue_details_help_tab'              => array(
360
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
361
+						'filename' => 'event_editor_venue_details',
362
+					),
363
+					'event_editor_event_datetimes_help_tab'            => array(
364
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
365
+						'filename' => 'event_editor_event_datetimes',
366
+					),
367
+					'event_editor_event_tickets_help_tab'              => array(
368
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
369
+						'filename' => 'event_editor_event_tickets',
370
+					),
371
+					'event_editor_event_registration_options_help_tab' => array(
372
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
373
+						'filename' => 'event_editor_event_registration_options',
374
+					),
375
+					'event_editor_tags_categories_help_tab'            => array(
376
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
377
+						'filename' => 'event_editor_tags_categories',
378
+					),
379
+					'event_editor_questions_registrants_help_tab'      => array(
380
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
381
+						'filename' => 'event_editor_questions_registrants',
382
+					),
383
+					'event_editor_save_new_event_help_tab'             => array(
384
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
385
+						'filename' => 'event_editor_save_new_event',
386
+					),
387
+					'event_editor_other_help_tab'                      => array(
388
+						'title'    => esc_html__('Event Other', 'event_espresso'),
389
+						'filename' => 'event_editor_other',
390
+					),
391
+				),
392
+				'qtips'         => array('EE_Event_Editor_Decaf_Tips'),
393
+				'require_nonce' => false,
394
+			),
395
+			'default_event_settings' => array(
396
+				'nav'           => array(
397
+					'label' => esc_html__('Default Settings', 'event_espresso'),
398
+					'order' => 40,
399
+				),
400
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
401
+				'labels'        => array(
402
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
403
+				),
404
+				'help_tabs'     => array(
405
+					'default_settings_help_tab'        => array(
406
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
407
+						'filename' => 'events_default_settings',
408
+					),
409
+					'default_settings_status_help_tab' => array(
410
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
411
+						'filename' => 'events_default_settings_status',
412
+					),
413
+					'default_maximum_tickets_help_tab' => array(
414
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
415
+						'filename' => 'events_default_settings_max_tickets',
416
+					),
417
+				),
418
+				'help_tour'     => array('Event_Default_Settings_Help_Tour'),
419
+				'require_nonce' => false,
420
+			),
421
+			// template settings
422
+			'template_settings'      => array(
423
+				'nav'           => array(
424
+					'label' => esc_html__('Templates', 'event_espresso'),
425
+					'order' => 30,
426
+				),
427
+				'metaboxes'     => $this->_default_espresso_metaboxes,
428
+				'help_tabs'     => array(
429
+					'general_settings_templates_help_tab' => array(
430
+						'title'    => esc_html__('Templates', 'event_espresso'),
431
+						'filename' => 'general_settings_templates',
432
+					),
433
+				),
434
+				'help_tour'     => array('Templates_Help_Tour'),
435
+				'require_nonce' => false,
436
+			),
437
+			// event category stuff
438
+			'add_category'           => array(
439
+				'nav'           => array(
440
+					'label'      => esc_html__('Add Category', 'event_espresso'),
441
+					'order'      => 15,
442
+					'persistent' => false,
443
+				),
444
+				'help_tabs'     => array(
445
+					'add_category_help_tab' => array(
446
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
447
+						'filename' => 'events_add_category',
448
+					),
449
+				),
450
+				'help_tour'     => array('Event_Add_Category_Help_Tour'),
451
+				'metaboxes'     => array('_publish_post_box'),
452
+				'require_nonce' => false,
453
+			),
454
+			'edit_category'          => array(
455
+				'nav'           => array(
456
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
457
+					'order'      => 15,
458
+					'persistent' => false,
459
+					'url'        => isset($this->_req_data['EVT_CAT_ID'])
460
+						? add_query_arg(
461
+							array('EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']),
462
+							$this->_current_page_view_url
463
+						)
464
+						: $this->_admin_base_url,
465
+				),
466
+				'help_tabs'     => array(
467
+					'edit_category_help_tab' => array(
468
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
469
+						'filename' => 'events_edit_category',
470
+					),
471
+				),
472
+				/*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
473
+				'metaboxes'     => array('_publish_post_box'),
474
+				'require_nonce' => false,
475
+			),
476
+			'category_list'          => array(
477
+				'nav'           => array(
478
+					'label' => esc_html__('Categories', 'event_espresso'),
479
+					'order' => 20,
480
+				),
481
+				'list_table'    => 'Event_Categories_Admin_List_Table',
482
+				'help_tabs'     => array(
483
+					'events_categories_help_tab'                       => array(
484
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
485
+						'filename' => 'events_categories',
486
+					),
487
+					'events_categories_table_column_headings_help_tab' => array(
488
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
489
+						'filename' => 'events_categories_table_column_headings',
490
+					),
491
+					'events_categories_view_help_tab'                  => array(
492
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
493
+						'filename' => 'events_categories_views',
494
+					),
495
+					'events_categories_other_help_tab'                 => array(
496
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
497
+						'filename' => 'events_categories_other',
498
+					),
499
+				),
500
+				'help_tour'     => array(
501
+					'Event_Categories_Help_Tour',
502
+				),
503
+				'metaboxes'     => $this->_default_espresso_metaboxes,
504
+				'require_nonce' => false,
505
+			),
506
+		);
507
+	}
508
+
509
+
510
+	/**
511
+	 * Used to register any global screen options if necessary for every route in this admin page group.
512
+	 */
513
+	protected function _add_screen_options()
514
+	{
515
+	}
516
+
517
+
518
+	/**
519
+	 * Implementing the screen options for the 'default' route.
520
+	 */
521
+	protected function _add_screen_options_default()
522
+	{
523
+		$this->_per_page_screen_option();
524
+	}
525
+
526
+
527
+	/**
528
+	 * Implementing screen options for the category list route.
529
+	 */
530
+	protected function _add_screen_options_category_list()
531
+	{
532
+		$page_title = $this->_admin_page_title;
533
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
534
+		$this->_per_page_screen_option();
535
+		$this->_admin_page_title = $page_title;
536
+	}
537
+
538
+
539
+	/**
540
+	 * Used to register any global feature pointers for the admin page group.
541
+	 */
542
+	protected function _add_feature_pointers()
543
+	{
544
+	}
545
+
546
+
547
+	/**
548
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
549
+	 */
550
+	public function load_scripts_styles()
551
+	{
552
+		wp_register_style(
553
+			'events-admin-css',
554
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
555
+			array(),
556
+			EVENT_ESPRESSO_VERSION
557
+		);
558
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
559
+		wp_enqueue_style('events-admin-css');
560
+		wp_enqueue_style('ee-cat-admin');
561
+		// todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
562
+		// registers for all views
563
+		// scripts
564
+		wp_register_script(
565
+			'event_editor_js',
566
+			EVENTS_ASSETS_URL . 'event_editor.js',
567
+			array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
568
+			EVENT_ESPRESSO_VERSION,
569
+			true
570
+		);
571
+	}
572
+
573
+
574
+	/**
575
+	 * Enqueuing scripts and styles specific to this view
576
+	 */
577
+	public function load_scripts_styles_create_new()
578
+	{
579
+		$this->load_scripts_styles_edit();
580
+	}
581
+
582
+
583
+	/**
584
+	 * Enqueuing scripts and styles specific to this view
585
+	 */
586
+	public function load_scripts_styles_edit()
587
+	{
588
+		// styles
589
+		wp_enqueue_style('espresso-ui-theme');
590
+		wp_register_style(
591
+			'event-editor-css',
592
+			EVENTS_ASSETS_URL . 'event-editor.css',
593
+			array('ee-admin-css'),
594
+			EVENT_ESPRESSO_VERSION
595
+		);
596
+		wp_enqueue_style('event-editor-css');
597
+		// scripts
598
+		wp_register_script(
599
+			'event-datetime-metabox',
600
+			EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
601
+			array('event_editor_js', 'ee-datepicker'),
602
+			EVENT_ESPRESSO_VERSION
603
+		);
604
+		wp_enqueue_script('event-datetime-metabox');
605
+	}
606
+
607
+
608
+	/**
609
+	 * Populating the _views property for the category list table view.
610
+	 */
611
+	protected function _set_list_table_views_category_list()
612
+	{
613
+		$this->_views = array(
614
+			'all' => array(
615
+				'slug'        => 'all',
616
+				'label'       => esc_html__('All', 'event_espresso'),
617
+				'count'       => 0,
618
+				'bulk_action' => array(
619
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
620
+				),
621
+			),
622
+		);
623
+	}
624
+
625
+
626
+	/**
627
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
628
+	 */
629
+	public function admin_init()
630
+	{
631
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
632
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
633
+			'event_espresso'
634
+		);
635
+	}
636
+
637
+
638
+	/**
639
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
640
+	 * group.
641
+	 */
642
+	public function admin_notices()
643
+	{
644
+	}
645
+
646
+
647
+	/**
648
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
649
+	 * this admin page group.
650
+	 */
651
+	public function admin_footer_scripts()
652
+	{
653
+	}
654
+
655
+
656
+	/**
657
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
658
+	 * warning (via EE_Error::add_error());
659
+	 *
660
+	 * @param  EE_Event $event Event object
661
+	 * @param string    $req_type
662
+	 * @return void
663
+	 * @throws EE_Error
664
+	 * @access public
665
+	 */
666
+	public function verify_event_edit($event = null, $req_type = '')
667
+	{
668
+		// don't need to do this when processing
669
+		if (! empty($req_type)) {
670
+			return;
671
+		}
672
+		// no event?
673
+		if (empty($event)) {
674
+			// set event
675
+			$event = $this->_cpt_model_obj;
676
+		}
677
+		// STILL no event?
678
+		if (! $event instanceof EE_Event) {
679
+			return;
680
+		}
681
+		$orig_status = $event->status();
682
+		// first check if event is active.
683
+		if ($orig_status === EEM_Event::cancelled
684
+			|| $orig_status === EEM_Event::postponed
685
+			|| $event->is_expired()
686
+			|| $event->is_inactive()
687
+		) {
688
+			return;
689
+		}
690
+		// made it here so it IS active... next check that any of the tickets are sold.
691
+		if ($event->is_sold_out(true)) {
692
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
693
+				EE_Error::add_attention(
694
+					sprintf(
695
+						esc_html__(
696
+							'Please note that the Event Status has automatically been changed to %s because there are no more spaces available for this event.  However, this change is not permanent until you update the event.  You can change the status back to something else before updating if you wish.',
697
+							'event_espresso'
698
+						),
699
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
700
+					)
701
+				);
702
+			}
703
+			return;
704
+		} elseif ($orig_status === EEM_Event::sold_out) {
705
+			EE_Error::add_attention(
706
+				sprintf(
707
+					esc_html__(
708
+						'Please note that the Event Status has automatically been changed to %s because more spaces have become available for this event, most likely due to abandoned transactions freeing up reserved tickets.  However, this change is not permanent until you update the event. If you wish, you can change the status back to something else before updating.',
709
+						'event_espresso'
710
+					),
711
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
712
+				)
713
+			);
714
+		}
715
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
716
+		if (! $event->tickets_on_sale()) {
717
+			return;
718
+		}
719
+		// made it here so show warning
720
+		$this->_edit_event_warning();
721
+	}
722
+
723
+
724
+	/**
725
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
726
+	 * When needed, hook this into a EE_Error::add_error() notice.
727
+	 *
728
+	 * @access protected
729
+	 * @return void
730
+	 */
731
+	protected function _edit_event_warning()
732
+	{
733
+		// we don't want to add warnings during these requests
734
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
735
+			return;
736
+		}
737
+		EE_Error::add_attention(
738
+			sprintf(
739
+				esc_html__(
740
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
741
+					'event_espresso'
742
+				),
743
+				'<a class="espresso-help-tab-lnk">',
744
+				'</a>'
745
+			)
746
+		);
747
+	}
748
+
749
+
750
+	/**
751
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
752
+	 * Otherwise, do the normal logic
753
+	 *
754
+	 * @return string
755
+	 * @throws \EE_Error
756
+	 */
757
+	protected function _create_new_cpt_item()
758
+	{
759
+		$has_timezone_string = get_option('timezone_string');
760
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
761
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) {
762
+			EE_Error::add_attention(
763
+				sprintf(
764
+					__(
765
+						'Your website\'s timezone is currently set to a UTC offset. We recommend updating your timezone to a city or region near you before you create an event. Change your timezone now:%1$s%2$s%3$sChange Timezone%4$s',
766
+						'event_espresso'
767
+					),
768
+					'<br>',
769
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
770
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
771
+					. '</select>',
772
+					'<button class="button button-secondary timezone-submit">',
773
+					'</button><span class="spinner"></span>'
774
+				),
775
+				__FILE__,
776
+				__FUNCTION__,
777
+				__LINE__
778
+			);
779
+		}
780
+		return parent::_create_new_cpt_item();
781
+	}
782
+
783
+
784
+	/**
785
+	 * Sets the _views property for the default route in this admin page group.
786
+	 */
787
+	protected function _set_list_table_views_default()
788
+	{
789
+		$this->_views = array(
790
+			'all'   => array(
791
+				'slug'        => 'all',
792
+				'label'       => esc_html__('View All Events', 'event_espresso'),
793
+				'count'       => 0,
794
+				'bulk_action' => array(
795
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
796
+				),
797
+			),
798
+			'draft' => array(
799
+				'slug'        => 'draft',
800
+				'label'       => esc_html__('Draft', 'event_espresso'),
801
+				'count'       => 0,
802
+				'bulk_action' => array(
803
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
804
+				),
805
+			),
806
+		);
807
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
808
+			$this->_views['trash'] = array(
809
+				'slug'        => 'trash',
810
+				'label'       => esc_html__('Trash', 'event_espresso'),
811
+				'count'       => 0,
812
+				'bulk_action' => array(
813
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
814
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
815
+				),
816
+			);
817
+		}
818
+	}
819
+
820
+
821
+	/**
822
+	 * Provides the legend item array for the default list table view.
823
+	 *
824
+	 * @return array
825
+	 */
826
+	protected function _event_legend_items()
827
+	{
828
+		$items = array(
829
+			'view_details'   => array(
830
+				'class' => 'dashicons dashicons-search',
831
+				'desc'  => esc_html__('View Event', 'event_espresso'),
832
+			),
833
+			'edit_event'     => array(
834
+				'class' => 'ee-icon ee-icon-calendar-edit',
835
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
836
+			),
837
+			'view_attendees' => array(
838
+				'class' => 'dashicons dashicons-groups',
839
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
840
+			),
841
+		);
842
+		$items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
843
+		$statuses = array(
844
+			'sold_out_status'  => array(
845
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
846
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
847
+			),
848
+			'active_status'    => array(
849
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
850
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
851
+			),
852
+			'upcoming_status'  => array(
853
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
854
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
855
+			),
856
+			'postponed_status' => array(
857
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
858
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
859
+			),
860
+			'cancelled_status' => array(
861
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
862
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
863
+			),
864
+			'expired_status'   => array(
865
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
866
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
867
+			),
868
+			'inactive_status'  => array(
869
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
870
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
871
+			),
872
+		);
873
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
874
+		return array_merge($items, $statuses);
875
+	}
876
+
877
+
878
+	/**
879
+	 * @return EEM_Event
880
+	 */
881
+	private function _event_model()
882
+	{
883
+		if (! $this->_event_model instanceof EEM_Event) {
884
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
885
+		}
886
+		return $this->_event_model;
887
+	}
888
+
889
+
890
+	/**
891
+	 * Adds extra buttons to the WP CPT permalink field row.
892
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
893
+	 *
894
+	 * @param  string $return    the current html
895
+	 * @param  int    $id        the post id for the page
896
+	 * @param  string $new_title What the title is
897
+	 * @param  string $new_slug  what the slug is
898
+	 * @return string            The new html string for the permalink area
899
+	 */
900
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
901
+	{
902
+		// make sure this is only when editing
903
+		if (! empty($id)) {
904
+			$post = get_post($id);
905
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
906
+					   . esc_html__('Shortcode', 'event_espresso')
907
+					   . '</a> ';
908
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
909
+					   . $post->ID
910
+					   . ']">';
911
+		}
912
+		return $return;
913
+	}
914
+
915
+
916
+	/**
917
+	 * _events_overview_list_table
918
+	 * This contains the logic for showing the events_overview list
919
+	 *
920
+	 * @access protected
921
+	 * @return void
922
+	 * @throws \EE_Error
923
+	 */
924
+	protected function _events_overview_list_table()
925
+	{
926
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
927
+		$this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
928
+			? (array) $this->_template_args['after_list_table']
929
+			: array();
930
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
931
+				. EEH_Template::get_button_or_link(
932
+					get_post_type_archive_link('espresso_events'),
933
+					esc_html__("View Event Archive Page", "event_espresso"),
934
+					'button'
935
+				);
936
+		$this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
937
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
938
+			'create_new',
939
+			'add',
940
+			array(),
941
+			'add-new-h2'
942
+		);
943
+		$this->display_admin_list_table_page_with_no_sidebar();
944
+	}
945
+
946
+
947
+	/**
948
+	 * this allows for extra misc actions in the default WP publish box
949
+	 *
950
+	 * @return void
951
+	 */
952
+	public function extra_misc_actions_publish_box()
953
+	{
954
+		$this->_generate_publish_box_extra_content();
955
+	}
956
+
957
+
958
+	/**
959
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
960
+	 * saved.
961
+	 * Typically you would use this to save any additional data.
962
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
963
+	 * ALSO very important.  When a post transitions from scheduled to published,
964
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
965
+	 * other meta saves. So MAKE sure that you handle this accordingly.
966
+	 *
967
+	 * @access protected
968
+	 * @abstract
969
+	 * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
970
+	 * @param  object $post    The post object of the cpt that was saved.
971
+	 * @return void
972
+	 * @throws \EE_Error
973
+	 */
974
+	protected function _insert_update_cpt_item($post_id, $post)
975
+	{
976
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
977
+			// get out we're not processing an event save.
978
+			return;
979
+		}
980
+		$event_values = array(
981
+			'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
982
+			'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
983
+			'EVT_additional_limit'            => min(
984
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
985
+				! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
986
+			),
987
+			'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
988
+				? $this->_req_data['EVT_default_registration_status']
989
+				: EE_Registry::instance()->CFG->registration->default_STS_ID,
990
+			'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
991
+			'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
992
+			'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
993
+				? $this->_req_data['timezone_string'] : null,
994
+			'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
995
+				? $this->_req_data['externalURL'] : null,
996
+			'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
997
+				? $this->_req_data['event_phone'] : null,
998
+		);
999
+		// update event
1000
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1001
+		// get event_object for other metaboxes... though it would seem to make sense to just use $this->_event_model()->get_one_by_ID( $post_id ).. i have to setup where conditions to override the filters in the model that filter out autodraft and inherit statuses so we GET the inherit id!
1002
+		$get_one_where = array(
1003
+			$this->_event_model()->primary_key_name() => $post_id,
1004
+			'OR'                                      => array(
1005
+				'status'   => $post->post_status,
1006
+				// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1007
+				// but the returned object here has a status of "publish", so use the original post status as well
1008
+				'status*1' => $this->_req_data['original_post_status'],
1009
+			),
1010
+		);
1011
+		$event = $this->_event_model()->get_one(array($get_one_where));
1012
+		// the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1013
+		$event_update_callbacks = apply_filters(
1014
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1015
+			array(
1016
+				array($this, '_default_venue_update'),
1017
+				array($this, '_default_tickets_update'),
1018
+			)
1019
+		);
1020
+		$att_success = true;
1021
+		foreach ($event_update_callbacks as $e_callback) {
1022
+			$_success = is_callable($e_callback)
1023
+				? call_user_func($e_callback, $event, $this->_req_data)
1024
+				: false;
1025
+			// if ANY of these updates fail then we want the appropriate global error message
1026
+			$att_success = ! $att_success ? $att_success : $_success;
1027
+		}
1028
+		// any errors?
1029
+		if ($success && false === $att_success) {
1030
+			EE_Error::add_error(
1031
+				esc_html__(
1032
+					'Event Details saved successfully but something went wrong with saving attachments.',
1033
+					'event_espresso'
1034
+				),
1035
+				__FILE__,
1036
+				__FUNCTION__,
1037
+				__LINE__
1038
+			);
1039
+		} elseif ($success === false) {
1040
+			EE_Error::add_error(
1041
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1042
+				__FILE__,
1043
+				__FUNCTION__,
1044
+				__LINE__
1045
+			);
1046
+		}
1047
+	}
1048
+
1049
+
1050
+	/**
1051
+	 * @see parent::restore_item()
1052
+	 * @param int $post_id
1053
+	 * @param int $revision_id
1054
+	 */
1055
+	protected function _restore_cpt_item($post_id, $revision_id)
1056
+	{
1057
+		// copy existing event meta to new post
1058
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1059
+		if ($post_evt instanceof EE_Event) {
1060
+			// meta revision restore
1061
+			$post_evt->restore_revision($revision_id);
1062
+			// related objs restore
1063
+			$post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1064
+		}
1065
+	}
1066
+
1067
+
1068
+	/**
1069
+	 * Attach the venue to the Event
1070
+	 *
1071
+	 * @param  \EE_Event $evtobj Event Object to add the venue to
1072
+	 * @param  array     $data   The request data from the form
1073
+	 * @return bool           Success or fail.
1074
+	 */
1075
+	protected function _default_venue_update(\EE_Event $evtobj, $data)
1076
+	{
1077
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1078
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1079
+		$rows_affected = null;
1080
+		$venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1081
+		// very important.  If we don't have a venue name...
1082
+		// then we'll get out because not necessary to create empty venue
1083
+		if (empty($data['venue_title'])) {
1084
+			return false;
1085
+		}
1086
+		$venue_array = array(
1087
+			'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1088
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1089
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1090
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1091
+			'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1092
+				: null,
1093
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1094
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1095
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1096
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1097
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1098
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1099
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1100
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1101
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1102
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1103
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1104
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1105
+			'status'              => 'publish',
1106
+		);
1107
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1108
+		if (! empty($venue_id)) {
1109
+			$update_where = array($venue_model->primary_key_name() => $venue_id);
1110
+			$rows_affected = $venue_model->update($venue_array, array($update_where));
1111
+			// we've gotta make sure that the venue is always attached to a revision.. add_relation_to should take care of making sure that the relation is already present.
1112
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1113
+			return $rows_affected > 0 ? true : false;
1114
+		} else {
1115
+			// we insert the venue
1116
+			$venue_id = $venue_model->insert($venue_array);
1117
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1118
+			return ! empty($venue_id) ? true : false;
1119
+		}
1120
+		// when we have the ancestor come in it's already been handled by the revision save.
1121
+	}
1122
+
1123
+
1124
+	/**
1125
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1126
+	 *
1127
+	 * @param  EE_Event $evtobj The Event object we're attaching data to
1128
+	 * @param  array    $data   The request data from the form
1129
+	 * @return array
1130
+	 */
1131
+	protected function _default_tickets_update(EE_Event $evtobj, $data)
1132
+	{
1133
+		$success = true;
1134
+		$saved_dtt = null;
1135
+		$saved_tickets = array();
1136
+		$incoming_date_formats = array('Y-m-d', 'h:i a');
1137
+		foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1138
+			// trim all values to ensure any excess whitespace is removed.
1139
+			$dtt = array_map('trim', $dtt);
1140
+			$dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1141
+				: $dtt['DTT_EVT_start'];
1142
+			$datetime_values = array(
1143
+				'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1144
+				'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1145
+				'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1146
+				'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1147
+				'DTT_order'     => $row,
1148
+			);
1149
+			// if we have an id then let's get existing object first and then set the new values.  Otherwise we instantiate a new object for save.
1150
+			if (! empty($dtt['DTT_ID'])) {
1151
+				$DTM = EE_Registry::instance()
1152
+								  ->load_model('Datetime', array($evtobj->get_timezone()))
1153
+								  ->get_one_by_ID($dtt['DTT_ID']);
1154
+				$DTM->set_date_format($incoming_date_formats[0]);
1155
+				$DTM->set_time_format($incoming_date_formats[1]);
1156
+				foreach ($datetime_values as $field => $value) {
1157
+					$DTM->set($field, $value);
1158
+				}
1159
+				// make sure the $dtt_id here is saved just in case after the add_relation_to() the autosave replaces it.  We need to do this so we dont' TRASH the parent DTT.
1160
+				$saved_dtts[ $DTM->ID() ] = $DTM;
1161
+			} else {
1162
+				$DTM = EE_Registry::instance()->load_class(
1163
+					'Datetime',
1164
+					array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1165
+					false,
1166
+					false
1167
+				);
1168
+				foreach ($datetime_values as $field => $value) {
1169
+					$DTM->set($field, $value);
1170
+				}
1171
+			}
1172
+			$DTM->save();
1173
+			$DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1174
+			// load DTT helper
1175
+			// before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1176
+			if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1177
+				$DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1178
+				$DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1179
+				$DTT->save();
1180
+			}
1181
+			// now we got to make sure we add the new DTT_ID to the $saved_dtts array  because it is possible there was a new one created for the autosave.
1182
+			$saved_dtt = $DTT;
1183
+			$success = ! $success ? $success : $DTT;
1184
+			// if ANY of these updates fail then we want the appropriate global error message.
1185
+			// //todo this is actually sucky we need a better error message but this is what it is for now.
1186
+		}
1187
+		// no dtts get deleted so we don't do any of that logic here.
1188
+		// update tickets next
1189
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1190
+		foreach ($data['edit_tickets'] as $row => $tkt) {
1191
+			$incoming_date_formats = array('Y-m-d', 'h:i a');
1192
+			$update_prices = false;
1193
+			$ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1194
+				? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0;
1195
+			// trim inputs to ensure any excess whitespace is removed.
1196
+			$tkt = array_map('trim', $tkt);
1197
+			if (empty($tkt['TKT_start_date'])) {
1198
+				// let's use now in the set timezone.
1199
+				$now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1200
+				$tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1201
+			}
1202
+			if (empty($tkt['TKT_end_date'])) {
1203
+				// use the start date of the first datetime
1204
+				$dtt = $evtobj->first_datetime();
1205
+				$tkt['TKT_end_date'] = $dtt->start_date_and_time(
1206
+					$incoming_date_formats[0],
1207
+					$incoming_date_formats[1]
1208
+				);
1209
+			}
1210
+			$TKT_values = array(
1211
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1212
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1213
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1214
+				'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1215
+				'TKT_start_date'  => $tkt['TKT_start_date'],
1216
+				'TKT_end_date'    => $tkt['TKT_end_date'],
1217
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1218
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1219
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1220
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1221
+				'TKT_row'         => $row,
1222
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1223
+				'TKT_price'       => $ticket_price,
1224
+			);
1225
+			// if this is a default TKT, then we need to set the TKT_ID to 0 and update accordingly, which means in turn that the prices will become new prices as well.
1226
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1227
+				$TKT_values['TKT_ID'] = 0;
1228
+				$TKT_values['TKT_is_default'] = 0;
1229
+				$TKT_values['TKT_price'] = $ticket_price;
1230
+				$update_prices = true;
1231
+			}
1232
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1233
+			// we actually do our saves a head of doing any add_relations to because its entirely possible that this ticket didn't removed or added to any datetime in the session but DID have it's items modified.
1234
+			// keep in mind that if the TKT has been sold (and we have changed pricing information), then we won't be updating the tkt but instead a new tkt will be created and the old one archived.
1235
+			if (! empty($tkt['TKT_ID'])) {
1236
+				$TKT = EE_Registry::instance()
1237
+								  ->load_model('Ticket', array($evtobj->get_timezone()))
1238
+								  ->get_one_by_ID($tkt['TKT_ID']);
1239
+				if ($TKT instanceof EE_Ticket) {
1240
+					$ticket_sold = $TKT->count_related(
1241
+						'Registration',
1242
+						array(
1243
+							array(
1244
+								'STS_ID' => array(
1245
+									'NOT IN',
1246
+									array(EEM_Registration::status_id_incomplete),
1247
+								),
1248
+							),
1249
+						)
1250
+					) > 0 ? true : false;
1251
+					// let's just check the total price for the existing ticket and determine if it matches the new total price.  if they are different then we create a new ticket (if tkts sold) if they aren't different then we go ahead and modify existing ticket.
1252
+					$create_new_TKT = $ticket_sold && $ticket_price != $TKT->get('TKT_price')
1253
+									  && ! $TKT->get('TKT_deleted');
1254
+					$TKT->set_date_format($incoming_date_formats[0]);
1255
+					$TKT->set_time_format($incoming_date_formats[1]);
1256
+					// set new values
1257
+					foreach ($TKT_values as $field => $value) {
1258
+						if ($field == 'TKT_qty') {
1259
+							$TKT->set_qty($value);
1260
+						} else {
1261
+							$TKT->set($field, $value);
1262
+						}
1263
+					}
1264
+					// if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1265
+					if ($create_new_TKT) {
1266
+						// archive the old ticket first
1267
+						$TKT->set('TKT_deleted', 1);
1268
+						$TKT->save();
1269
+						// make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1270
+						$saved_tickets[ $TKT->ID() ] = $TKT;
1271
+						// create new ticket that's a copy of the existing except a new id of course (and not archived) AND has the new TKT_price associated with it.
1272
+						$TKT = clone $TKT;
1273
+						$TKT->set('TKT_ID', 0);
1274
+						$TKT->set('TKT_deleted', 0);
1275
+						$TKT->set('TKT_price', $ticket_price);
1276
+						$TKT->set('TKT_sold', 0);
1277
+						// now we need to make sure that $new prices are created as well and attached to new ticket.
1278
+						$update_prices = true;
1279
+					}
1280
+					// make sure price is set if it hasn't been already
1281
+					$TKT->set('TKT_price', $ticket_price);
1282
+				}
1283
+			} else {
1284
+				// no TKT_id so a new TKT
1285
+				$TKT_values['TKT_price'] = $ticket_price;
1286
+				$TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1287
+				if ($TKT instanceof EE_Ticket) {
1288
+					// need to reset values to properly account for the date formats
1289
+					$TKT->set_date_format($incoming_date_formats[0]);
1290
+					$TKT->set_time_format($incoming_date_formats[1]);
1291
+					$TKT->set_timezone($evtobj->get_timezone());
1292
+					// set new values
1293
+					foreach ($TKT_values as $field => $value) {
1294
+						if ($field == 'TKT_qty') {
1295
+							$TKT->set_qty($value);
1296
+						} else {
1297
+							$TKT->set($field, $value);
1298
+						}
1299
+					}
1300
+					$update_prices = true;
1301
+				}
1302
+			}
1303
+			// cap ticket qty by datetime reg limits
1304
+			$TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1305
+			// update ticket.
1306
+			$TKT->save();
1307
+			// before going any further make sure our dates are setup correctly so that the end date is always equal or greater than the start date.
1308
+			if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1309
+				$TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1310
+				$TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1311
+				$TKT->save();
1312
+			}
1313
+			// initially let's add the ticket to the dtt
1314
+			$saved_dtt->_add_relation_to($TKT, 'Ticket');
1315
+			$saved_tickets[ $TKT->ID() ] = $TKT;
1316
+			// add prices to ticket
1317
+			$this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1318
+		}
1319
+		// however now we need to handle permanently deleting tickets via the ui.  Keep in mind that the ui does not allow deleting/archiving tickets that have ticket sold.  However, it does allow for deleting tickets that have no tickets sold, in which case we want to get rid of permanently because there is no need to save in db.
1320
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] == '' ? array() : $old_tickets;
1321
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1322
+		foreach ($tickets_removed as $id) {
1323
+			$id = absint($id);
1324
+			// get the ticket for this id
1325
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1326
+			// need to get all the related datetimes on this ticket and remove from every single one of them (remember this process can ONLY kick off if there are NO tkts_sold)
1327
+			$dtts = $tkt_to_remove->get_many_related('Datetime');
1328
+			foreach ($dtts as $dtt) {
1329
+				$tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1330
+			}
1331
+			// need to do the same for prices (except these prices can also be deleted because again, tickets can only be trashed if they don't have any TKTs sold (otherwise they are just archived))
1332
+			$tkt_to_remove->delete_related_permanently('Price');
1333
+			// finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1334
+			$tkt_to_remove->delete_permanently();
1335
+		}
1336
+		return array($saved_dtt, $saved_tickets);
1337
+	}
1338
+
1339
+
1340
+	/**
1341
+	 * This attaches a list of given prices to a ticket.
1342
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1343
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1344
+	 * price info and prices are automatically "archived" via the ticket.
1345
+	 *
1346
+	 * @access  private
1347
+	 * @param array     $prices     Array of prices from the form.
1348
+	 * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1349
+	 * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1350
+	 * @return  void
1351
+	 */
1352
+	private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1353
+	{
1354
+		foreach ($prices as $row => $prc) {
1355
+			$PRC_values = array(
1356
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1357
+				'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1358
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1359
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1360
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1361
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1362
+				'PRC_order'      => $row,
1363
+			);
1364
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
1365
+				$PRC_values['PRC_ID'] = 0;
1366
+				$PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1367
+			} else {
1368
+				$PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1369
+				// update this price with new values
1370
+				foreach ($PRC_values as $field => $newprc) {
1371
+					$PRC->set($field, $newprc);
1372
+				}
1373
+				$PRC->save();
1374
+			}
1375
+			$ticket->_add_relation_to($PRC, 'Price');
1376
+		}
1377
+	}
1378
+
1379
+
1380
+	/**
1381
+	 * Add in our autosave ajax handlers
1382
+	 *
1383
+	 */
1384
+	protected function _ee_autosave_create_new()
1385
+	{
1386
+	}
1387
+
1388
+
1389
+	/**
1390
+	 * More autosave handlers.
1391
+	 */
1392
+	protected function _ee_autosave_edit()
1393
+	{
1394
+		return; // TEMPORARILY EXITING CAUSE THIS IS A TODO
1395
+	}
1396
+
1397
+
1398
+	/**
1399
+	 *    _generate_publish_box_extra_content
1400
+	 */
1401
+	private function _generate_publish_box_extra_content()
1402
+	{
1403
+		// load formatter helper
1404
+		// args for getting related registrations
1405
+		$approved_query_args = array(
1406
+			array(
1407
+				'REG_deleted' => 0,
1408
+				'STS_ID'      => EEM_Registration::status_id_approved,
1409
+			),
1410
+		);
1411
+		$not_approved_query_args = array(
1412
+			array(
1413
+				'REG_deleted' => 0,
1414
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1415
+			),
1416
+		);
1417
+		$pending_payment_query_args = array(
1418
+			array(
1419
+				'REG_deleted' => 0,
1420
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1421
+			),
1422
+		);
1423
+		// publish box
1424
+		$publish_box_extra_args = array(
1425
+			'view_approved_reg_url'        => add_query_arg(
1426
+				array(
1427
+					'action'      => 'default',
1428
+					'event_id'    => $this->_cpt_model_obj->ID(),
1429
+					'_reg_status' => EEM_Registration::status_id_approved,
1430
+				),
1431
+				REG_ADMIN_URL
1432
+			),
1433
+			'view_not_approved_reg_url'    => add_query_arg(
1434
+				array(
1435
+					'action'      => 'default',
1436
+					'event_id'    => $this->_cpt_model_obj->ID(),
1437
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1438
+				),
1439
+				REG_ADMIN_URL
1440
+			),
1441
+			'view_pending_payment_reg_url' => add_query_arg(
1442
+				array(
1443
+					'action'      => 'default',
1444
+					'event_id'    => $this->_cpt_model_obj->ID(),
1445
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1446
+				),
1447
+				REG_ADMIN_URL
1448
+			),
1449
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1450
+				'Registration',
1451
+				$approved_query_args
1452
+			),
1453
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1454
+				'Registration',
1455
+				$not_approved_query_args
1456
+			),
1457
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1458
+				'Registration',
1459
+				$pending_payment_query_args
1460
+			),
1461
+			'misc_pub_section_class'       => apply_filters(
1462
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1463
+				'misc-pub-section'
1464
+			),
1465
+		);
1466
+		ob_start();
1467
+		do_action(
1468
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1469
+			$this->_cpt_model_obj
1470
+		);
1471
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1472
+		// load template
1473
+		EEH_Template::display_template(
1474
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1475
+			$publish_box_extra_args
1476
+		);
1477
+	}
1478
+
1479
+
1480
+	/**
1481
+	 * @return EE_Event
1482
+	 */
1483
+	public function get_event_object()
1484
+	{
1485
+		return $this->_cpt_model_obj;
1486
+	}
1487
+
1488
+
1489
+
1490
+
1491
+	/** METABOXES * */
1492
+	/**
1493
+	 * _register_event_editor_meta_boxes
1494
+	 * add all metaboxes related to the event_editor
1495
+	 *
1496
+	 * @return void
1497
+	 */
1498
+	protected function _register_event_editor_meta_boxes()
1499
+	{
1500
+		$this->verify_cpt_object();
1501
+		// add_meta_box(
1502
+		//     'espresso_event_editor_tickets',
1503
+		//     esc_html__('Event Datetime & Ticket', 'event_espresso'),
1504
+		//     array($this, 'ticket_metabox'),
1505
+		//     $this->page_slug,
1506
+		//     'normal',
1507
+		//     'high'
1508
+		// );
1509
+		add_meta_box(
1510
+			'espresso_event_editor_event_options',
1511
+			esc_html__('Event Registration Options', 'event_espresso'),
1512
+			array($this, 'registration_options_meta_box'),
1513
+			$this->page_slug,
1514
+			'side',
1515
+			'default'
1516
+		);
1517
+		// NOTE: if you're looking for other metaboxes in here,
1518
+		// where a metabox has a related management page in the admin
1519
+		// you will find it setup in the related management page's "_Hooks" file.
1520
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1521
+	}
1522
+
1523
+
1524
+	/**
1525
+	 * @throws DomainException
1526
+	 * @throws EE_Error
1527
+	 */
1528
+	public function ticket_metabox()
1529
+	{
1530
+		$existing_datetime_ids = $existing_ticket_ids = array();
1531
+		// defaults for template args
1532
+		$template_args = array(
1533
+			'existing_datetime_ids'    => '',
1534
+			'event_datetime_help_link' => '',
1535
+			'ticket_options_help_link' => '',
1536
+			'time'                     => null,
1537
+			'ticket_rows'              => '',
1538
+			'existing_ticket_ids'      => '',
1539
+			'total_ticket_rows'        => 1,
1540
+			'ticket_js_structure'      => '',
1541
+			'trash_icon'               => 'ee-lock-icon',
1542
+			'disabled'                 => '',
1543
+		);
1544
+		$event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1545
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1546
+		/**
1547
+		 * 1. Start with retrieving Datetimes
1548
+		 * 2. Fore each datetime get related tickets
1549
+		 * 3. For each ticket get related prices
1550
+		 */
1551
+		$times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1552
+		/** @type EE_Datetime $first_datetime */
1553
+		$first_datetime = reset($times);
1554
+		// do we get related tickets?
1555
+		if ($first_datetime instanceof EE_Datetime
1556
+			&& $first_datetime->ID() !== 0
1557
+		) {
1558
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1559
+			$template_args['time'] = $first_datetime;
1560
+			$related_tickets = $first_datetime->tickets(
1561
+				array(
1562
+					array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1563
+					'default_where_conditions' => 'none',
1564
+				)
1565
+			);
1566
+			if (! empty($related_tickets)) {
1567
+				$template_args['total_ticket_rows'] = count($related_tickets);
1568
+				$row = 0;
1569
+				foreach ($related_tickets as $ticket) {
1570
+					$existing_ticket_ids[] = $ticket->get('TKT_ID');
1571
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1572
+					$row++;
1573
+				}
1574
+			} else {
1575
+				$template_args['total_ticket_rows'] = 1;
1576
+				/** @type EE_Ticket $ticket */
1577
+				$ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1578
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1579
+			}
1580
+		} else {
1581
+			$template_args['time'] = $times[0];
1582
+			/** @type EE_Ticket $ticket */
1583
+			$ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1584
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1585
+			// NOTE: we're just sending the first default row
1586
+			// (decaf can't manage default tickets so this should be sufficient);
1587
+		}
1588
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1589
+			'event_editor_event_datetimes_help_tab'
1590
+		);
1591
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1592
+		$template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1593
+		$template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1594
+		$template_args['ticket_js_structure'] = $this->_get_ticket_row(
1595
+			EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1596
+			true
1597
+		);
1598
+		$template = apply_filters(
1599
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1600
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1601
+		);
1602
+		EEH_Template::display_template($template, $template_args);
1603
+	}
1604
+
1605
+
1606
+	/**
1607
+	 * Setup an individual ticket form for the decaf event editor page
1608
+	 *
1609
+	 * @access private
1610
+	 * @param  EE_Ticket $ticket   the ticket object
1611
+	 * @param  boolean   $skeleton whether we're generating a skeleton for js manipulation
1612
+	 * @param int        $row
1613
+	 * @return string generated html for the ticket row.
1614
+	 */
1615
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1616
+	{
1617
+		$template_args = array(
1618
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1619
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1620
+				: '',
1621
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1622
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1623
+			'TKT_name'            => $ticket->get('TKT_name'),
1624
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1625
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1626
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1627
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1628
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1629
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1630
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1631
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1632
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1633
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1634
+				: ' disabled=disabled',
1635
+		);
1636
+		$price = $ticket->ID() !== 0
1637
+			? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1638
+			: EE_Registry::instance()->load_model('Price')->create_default_object();
1639
+		$price_args = array(
1640
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1641
+			'PRC_amount'            => $price->get('PRC_amount'),
1642
+			'PRT_ID'                => $price->get('PRT_ID'),
1643
+			'PRC_ID'                => $price->get('PRC_ID'),
1644
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1645
+		);
1646
+		// make sure we have default start and end dates if skeleton
1647
+		// handle rows that should NOT be empty
1648
+		if (empty($template_args['TKT_start_date'])) {
1649
+			// if empty then the start date will be now.
1650
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1651
+		}
1652
+		if (empty($template_args['TKT_end_date'])) {
1653
+			// get the earliest datetime (if present);
1654
+			$earliest_dtt = $this->_cpt_model_obj->ID() > 0
1655
+				? $this->_cpt_model_obj->get_first_related(
1656
+					'Datetime',
1657
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1658
+				)
1659
+				: null;
1660
+			if (! empty($earliest_dtt)) {
1661
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1662
+			} else {
1663
+				$template_args['TKT_end_date'] = date(
1664
+					'Y-m-d h:i a',
1665
+					mktime(0, 0, 0, date("m"), date("d") + 7, date("Y"))
1666
+				);
1667
+			}
1668
+		}
1669
+		$template_args = array_merge($template_args, $price_args);
1670
+		$template = apply_filters(
1671
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1672
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1673
+			$ticket
1674
+		);
1675
+		return EEH_Template::display_template($template, $template_args, true);
1676
+	}
1677
+
1678
+
1679
+	/**
1680
+	 * @throws DomainException
1681
+	 */
1682
+	public function registration_options_meta_box()
1683
+	{
1684
+		$yes_no_values = array(
1685
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1686
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1687
+		);
1688
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1689
+			array(
1690
+				EEM_Registration::status_id_cancelled,
1691
+				EEM_Registration::status_id_declined,
1692
+				EEM_Registration::status_id_incomplete,
1693
+			),
1694
+			true
1695
+		);
1696
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1697
+		$template_args['_event'] = $this->_cpt_model_obj;
1698
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1699
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1700
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1701
+			'default_reg_status',
1702
+			$default_reg_status_values,
1703
+			$this->_cpt_model_obj->default_registration_status()
1704
+		);
1705
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
1706
+			'display_desc',
1707
+			$yes_no_values,
1708
+			$this->_cpt_model_obj->display_description()
1709
+		);
1710
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1711
+			'display_ticket_selector',
1712
+			$yes_no_values,
1713
+			$this->_cpt_model_obj->display_ticket_selector(),
1714
+			'',
1715
+			'',
1716
+			false
1717
+		);
1718
+		$template_args['additional_registration_options'] = apply_filters(
1719
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1720
+			'',
1721
+			$template_args,
1722
+			$yes_no_values,
1723
+			$default_reg_status_values
1724
+		);
1725
+		EEH_Template::display_template(
1726
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1727
+			$template_args
1728
+		);
1729
+	}
1730
+
1731
+
1732
+	/**
1733
+	 * _get_events()
1734
+	 * This method simply returns all the events (for the given _view and paging)
1735
+	 *
1736
+	 * @access public
1737
+	 * @param int  $per_page     count of items per page (20 default);
1738
+	 * @param int  $current_page what is the current page being viewed.
1739
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1740
+	 *                           If FALSE then we return an array of event objects
1741
+	 *                           that match the given _view and paging parameters.
1742
+	 * @return array an array of event objects.
1743
+	 */
1744
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1745
+	{
1746
+		$EEME = $this->_event_model();
1747
+		$offset = ($current_page - 1) * $per_page;
1748
+		$limit = $count ? null : $offset . ',' . $per_page;
1749
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1750
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : "DESC";
1751
+		if (isset($this->_req_data['month_range'])) {
1752
+			$pieces = explode(' ', $this->_req_data['month_range'], 3);
1753
+			// simulate the FIRST day of the month, that fixes issues for months like February
1754
+			// where PHP doesn't know what to assume for date.
1755
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1756
+			$month_r = ! empty($pieces[0]) ? date('m', \EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1757
+			$year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1758
+		}
1759
+		$where = array();
1760
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1761
+		// determine what post_status our condition will have for the query.
1762
+		switch ($status) {
1763
+			case 'month':
1764
+			case 'today':
1765
+			case null:
1766
+			case 'all':
1767
+				break;
1768
+			case 'draft':
1769
+				$where['status'] = array('IN', array('draft', 'auto-draft'));
1770
+				break;
1771
+			default:
1772
+				$where['status'] = $status;
1773
+		}
1774
+		// categories?
1775
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1776
+			? $this->_req_data['EVT_CAT'] : null;
1777
+		if (! empty($category)) {
1778
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1779
+			$where['Term_Taxonomy.term_id'] = $category;
1780
+		}
1781
+		// date where conditions
1782
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1783
+		if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] != '') {
1784
+			$DateTime = new DateTime(
1785
+				$year_r . '-' . $month_r . '-01 00:00:00',
1786
+				new DateTimeZone(EEM_Datetime::instance()->get_timezone())
1787
+			);
1788
+			$start = $DateTime->format(implode(' ', $start_formats));
1789
+			$end = $DateTime->setDate(
1790
+				$year_r,
1791
+				$month_r,
1792
+				$DateTime
1793
+					->format('t')
1794
+			)->setTime(23, 59, 59)
1795
+							->format(implode(' ', $start_formats));
1796
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1797
+		} elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'today') {
1798
+			$DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1799
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1800
+			$end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1801
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1802
+		} elseif (isset($this->_req_data['status']) && $this->_req_data['status'] == 'month') {
1803
+			$now = date('Y-m-01');
1804
+			$DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1805
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1806
+			$end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1807
+							->setTime(23, 59, 59)
1808
+							->format(implode(' ', $start_formats));
1809
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1810
+		}
1811
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1812
+			$where['EVT_wp_user'] = get_current_user_id();
1813
+		} else {
1814
+			if (! isset($where['status'])) {
1815
+				if (! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')) {
1816
+					$where['OR'] = array(
1817
+						'status*restrict_private' => array('!=', 'private'),
1818
+						'AND'                     => array(
1819
+							'status*inclusive' => array('=', 'private'),
1820
+							'EVT_wp_user'      => get_current_user_id(),
1821
+						),
1822
+					);
1823
+				}
1824
+			}
1825
+		}
1826
+		if (isset($this->_req_data['EVT_wp_user'])) {
1827
+			if ($this->_req_data['EVT_wp_user'] != get_current_user_id()
1828
+				&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1829
+			) {
1830
+				$where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1831
+			}
1832
+		}
1833
+		// search query handling
1834
+		if (isset($this->_req_data['s'])) {
1835
+			$search_string = '%' . $this->_req_data['s'] . '%';
1836
+			$where['OR'] = array(
1837
+				'EVT_name'       => array('LIKE', $search_string),
1838
+				'EVT_desc'       => array('LIKE', $search_string),
1839
+				'EVT_short_desc' => array('LIKE', $search_string),
1840
+			);
1841
+		}
1842
+		// filter events by venue.
1843
+		if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) {
1844
+			$where['Venue.VNU_ID'] = absint($this->_req_data['venue']);
1845
+		}
1846
+		$where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1847
+		$query_params = apply_filters(
1848
+			'FHEE__Events_Admin_Page__get_events__query_params',
1849
+			array(
1850
+				$where,
1851
+				'limit'    => $limit,
1852
+				'order_by' => $orderby,
1853
+				'order'    => $order,
1854
+				'group_by' => 'EVT_ID',
1855
+			),
1856
+			$this->_req_data
1857
+		);
1858
+		// let's first check if we have special requests coming in.
1859
+		if (isset($this->_req_data['active_status'])) {
1860
+			switch ($this->_req_data['active_status']) {
1861
+				case 'upcoming':
1862
+					return $EEME->get_upcoming_events($query_params, $count);
1863
+					break;
1864
+				case 'expired':
1865
+					return $EEME->get_expired_events($query_params, $count);
1866
+					break;
1867
+				case 'active':
1868
+					return $EEME->get_active_events($query_params, $count);
1869
+					break;
1870
+				case 'inactive':
1871
+					return $EEME->get_inactive_events($query_params, $count);
1872
+					break;
1873
+			}
1874
+		}
1875
+
1876
+		$events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1877
+		return $events;
1878
+	}
1879
+
1880
+
1881
+	/**
1882
+	 * handling for WordPress CPT actions (trash, restore, delete)
1883
+	 *
1884
+	 * @param string $post_id
1885
+	 */
1886
+	public function trash_cpt_item($post_id)
1887
+	{
1888
+		$this->_req_data['EVT_ID'] = $post_id;
1889
+		$this->_trash_or_restore_event('trash', false);
1890
+	}
1891
+
1892
+
1893
+	/**
1894
+	 * @param string $post_id
1895
+	 */
1896
+	public function restore_cpt_item($post_id)
1897
+	{
1898
+		$this->_req_data['EVT_ID'] = $post_id;
1899
+		$this->_trash_or_restore_event('draft', false);
1900
+	}
1901
+
1902
+
1903
+	/**
1904
+	 * @param string $post_id
1905
+	 */
1906
+	public function delete_cpt_item($post_id)
1907
+	{
1908
+		$this->_req_data['EVT_ID'] = $post_id;
1909
+		$this->_delete_event(false);
1910
+	}
1911
+
1912
+
1913
+	/**
1914
+	 * _trash_or_restore_event
1915
+	 *
1916
+	 * @access protected
1917
+	 * @param  string $event_status
1918
+	 * @param bool    $redirect_after
1919
+	 */
1920
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
1921
+	{
1922
+		// determine the event id and set to array.
1923
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
1924
+		// loop thru events
1925
+		if ($EVT_ID) {
1926
+			// clean status
1927
+			$event_status = sanitize_key($event_status);
1928
+			// grab status
1929
+			if (! empty($event_status)) {
1930
+				$success = $this->_change_event_status($EVT_ID, $event_status);
1931
+			} else {
1932
+				$success = false;
1933
+				$msg = esc_html__(
1934
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1935
+					'event_espresso'
1936
+				);
1937
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1938
+			}
1939
+		} else {
1940
+			$success = false;
1941
+			$msg = esc_html__(
1942
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
1943
+				'event_espresso'
1944
+			);
1945
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1946
+		}
1947
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1948
+		if ($redirect_after) {
1949
+			$this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
1950
+		}
1951
+	}
1952
+
1953
+
1954
+	/**
1955
+	 * _trash_or_restore_events
1956
+	 *
1957
+	 * @access protected
1958
+	 * @param  string $event_status
1959
+	 * @return void
1960
+	 */
1961
+	protected function _trash_or_restore_events($event_status = 'trash')
1962
+	{
1963
+		// clean status
1964
+		$event_status = sanitize_key($event_status);
1965
+		// grab status
1966
+		if (! empty($event_status)) {
1967
+			$success = true;
1968
+			// determine the event id and set to array.
1969
+			$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
1970
+			// loop thru events
1971
+			foreach ($EVT_IDs as $EVT_ID) {
1972
+				if ($EVT_ID = absint($EVT_ID)) {
1973
+					$results = $this->_change_event_status($EVT_ID, $event_status);
1974
+					$success = $results !== false ? $success : false;
1975
+				} else {
1976
+					$msg = sprintf(
1977
+						esc_html__(
1978
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
1979
+							'event_espresso'
1980
+						),
1981
+						$EVT_ID
1982
+					);
1983
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1984
+					$success = false;
1985
+				}
1986
+			}
1987
+		} else {
1988
+			$success = false;
1989
+			$msg = esc_html__(
1990
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
1991
+				'event_espresso'
1992
+			);
1993
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1994
+		}
1995
+		// in order to force a pluralized result message we need to send back a success status greater than 1
1996
+		$success = $success ? 2 : false;
1997
+		$action = $event_status == 'trash' ? 'moved to the trash' : 'restored from the trash';
1998
+		$this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
1999
+	}
2000
+
2001
+
2002
+	/**
2003
+	 * _trash_or_restore_events
2004
+	 *
2005
+	 * @access  private
2006
+	 * @param  int    $EVT_ID
2007
+	 * @param  string $event_status
2008
+	 * @return bool
2009
+	 */
2010
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2011
+	{
2012
+		// grab event id
2013
+		if (! $EVT_ID) {
2014
+			$msg = esc_html__(
2015
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2016
+				'event_espresso'
2017
+			);
2018
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2019
+			return false;
2020
+		}
2021
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2022
+		// clean status
2023
+		$event_status = sanitize_key($event_status);
2024
+		// grab status
2025
+		if (empty($event_status)) {
2026
+			$msg = esc_html__(
2027
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2028
+				'event_espresso'
2029
+			);
2030
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2031
+			return false;
2032
+		}
2033
+		// was event trashed or restored ?
2034
+		switch ($event_status) {
2035
+			case 'draft':
2036
+				$action = 'restored from the trash';
2037
+				$hook = 'AHEE_event_restored_from_trash';
2038
+				break;
2039
+			case 'trash':
2040
+				$action = 'moved to the trash';
2041
+				$hook = 'AHEE_event_moved_to_trash';
2042
+				break;
2043
+			default:
2044
+				$action = 'updated';
2045
+				$hook = false;
2046
+		}
2047
+		// use class to change status
2048
+		$this->_cpt_model_obj->set_status($event_status);
2049
+		$success = $this->_cpt_model_obj->save();
2050
+		if ($success === false) {
2051
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2052
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2053
+			return false;
2054
+		}
2055
+		if ($hook) {
2056
+			do_action($hook);
2057
+		}
2058
+		return true;
2059
+	}
2060
+
2061
+
2062
+	/**
2063
+	 * _delete_event
2064
+	 *
2065
+	 * @access protected
2066
+	 * @param bool $redirect_after
2067
+	 */
2068
+	protected function _delete_event($redirect_after = true)
2069
+	{
2070
+		// determine the event id and set to array.
2071
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2072
+		$EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2073
+		// loop thru events
2074
+		if ($EVT_ID) {
2075
+			$success = $this->_permanently_delete_event($EVT_ID);
2076
+			// get list of events with no prices
2077
+			$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2078
+			// remove this event from the list of events with no prices
2079
+			if (isset($espresso_no_ticket_prices[ $EVT_ID ])) {
2080
+				unset($espresso_no_ticket_prices[ $EVT_ID ]);
2081
+			}
2082
+			update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2083
+		} else {
2084
+			$success = false;
2085
+			$msg = esc_html__(
2086
+				'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2087
+				'event_espresso'
2088
+			);
2089
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2090
+		}
2091
+		if ($redirect_after) {
2092
+			$this->_redirect_after_action(
2093
+				$success,
2094
+				'Event',
2095
+				'deleted',
2096
+				array('action' => 'default', 'status' => 'trash')
2097
+			);
2098
+		}
2099
+	}
2100
+
2101
+
2102
+	/**
2103
+	 * _delete_events
2104
+	 *
2105
+	 * @access protected
2106
+	 * @return void
2107
+	 */
2108
+	protected function _delete_events()
2109
+	{
2110
+		$success = true;
2111
+		// get list of events with no prices
2112
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2113
+		// determine the event id and set to array.
2114
+		$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2115
+		// loop thru events
2116
+		foreach ($EVT_IDs as $EVT_ID) {
2117
+			$EVT_ID = absint($EVT_ID);
2118
+			if ($EVT_ID) {
2119
+				$results = $this->_permanently_delete_event($EVT_ID);
2120
+				$success = $results !== false ? $success : false;
2121
+				// remove this event from the list of events with no prices
2122
+				unset($espresso_no_ticket_prices[ $EVT_ID ]);
2123
+			} else {
2124
+				$success = false;
2125
+				$msg = esc_html__(
2126
+					'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2127
+					'event_espresso'
2128
+				);
2129
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2130
+			}
2131
+		}
2132
+		update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2133
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2134
+		$success = $success ? 2 : false;
2135
+		$this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2136
+	}
2137
+
2138
+
2139
+	/**
2140
+	 * _permanently_delete_event
2141
+	 *
2142
+	 * @access  private
2143
+	 * @param  int $EVT_ID
2144
+	 * @return bool
2145
+	 */
2146
+	private function _permanently_delete_event($EVT_ID = 0)
2147
+	{
2148
+		// grab event id
2149
+		if (! $EVT_ID) {
2150
+			$msg = esc_html__(
2151
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2152
+				'event_espresso'
2153
+			);
2154
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2155
+			return false;
2156
+		}
2157
+		if (! $this->_cpt_model_obj instanceof EE_Event
2158
+			|| $this->_cpt_model_obj->ID() !== $EVT_ID
2159
+		) {
2160
+			$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2161
+		}
2162
+		if (! $this->_cpt_model_obj instanceof EE_Event) {
2163
+			return false;
2164
+		}
2165
+		// need to delete related tickets and prices first.
2166
+		$datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2167
+		foreach ($datetimes as $datetime) {
2168
+			$this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2169
+			$tickets = $datetime->get_many_related('Ticket');
2170
+			foreach ($tickets as $ticket) {
2171
+				$ticket->_remove_relation_to($datetime, 'Datetime');
2172
+				$ticket->delete_related_permanently('Price');
2173
+				$ticket->delete_permanently();
2174
+			}
2175
+			$datetime->delete();
2176
+		}
2177
+		// what about related venues or terms?
2178
+		$venues = $this->_cpt_model_obj->get_many_related('Venue');
2179
+		foreach ($venues as $venue) {
2180
+			$this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2181
+		}
2182
+		// any attached question groups?
2183
+		$question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2184
+		if (! empty($question_groups)) {
2185
+			foreach ($question_groups as $question_group) {
2186
+				$this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2187
+			}
2188
+		}
2189
+		// Message Template Groups
2190
+		$this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2191
+		/** @type EE_Term_Taxonomy[] $term_taxonomies */
2192
+		$term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2193
+		foreach ($term_taxonomies as $term_taxonomy) {
2194
+			$this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2195
+		}
2196
+		$success = $this->_cpt_model_obj->delete_permanently();
2197
+		// did it all go as planned ?
2198
+		if ($success) {
2199
+			$msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2200
+			EE_Error::add_success($msg);
2201
+		} else {
2202
+			$msg = sprintf(
2203
+				esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2204
+				$EVT_ID
2205
+			);
2206
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2207
+			return false;
2208
+		}
2209
+		do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2210
+		return true;
2211
+	}
2212
+
2213
+
2214
+	/**
2215
+	 * get total number of events
2216
+	 *
2217
+	 * @access public
2218
+	 * @return int
2219
+	 */
2220
+	public function total_events()
2221
+	{
2222
+		$count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2223
+		return $count;
2224
+	}
2225
+
2226
+
2227
+	/**
2228
+	 * get total number of draft events
2229
+	 *
2230
+	 * @access public
2231
+	 * @return int
2232
+	 */
2233
+	public function total_events_draft()
2234
+	{
2235
+		$where = array(
2236
+			'status' => array('IN', array('draft', 'auto-draft')),
2237
+		);
2238
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2239
+		return $count;
2240
+	}
2241
+
2242
+
2243
+	/**
2244
+	 * get total number of trashed events
2245
+	 *
2246
+	 * @access public
2247
+	 * @return int
2248
+	 */
2249
+	public function total_trashed_events()
2250
+	{
2251
+		$where = array(
2252
+			'status' => 'trash',
2253
+		);
2254
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2255
+		return $count;
2256
+	}
2257
+
2258
+
2259
+	/**
2260
+	 *    _default_event_settings
2261
+	 *    This generates the Default Settings Tab
2262
+	 *
2263
+	 * @return void
2264
+	 * @throws EE_Error
2265
+	 */
2266
+	protected function _default_event_settings()
2267
+	{
2268
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2269
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2270
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2271
+		$this->display_admin_page_with_sidebar();
2272
+	}
2273
+
2274
+
2275
+	/**
2276
+	 * Return the form for event settings.
2277
+	 *
2278
+	 * @return EE_Form_Section_Proper
2279
+	 * @throws EE_Error
2280
+	 */
2281
+	protected function _default_event_settings_form()
2282
+	{
2283
+		$registration_config = EE_Registry::instance()->CFG->registration;
2284
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2285
+			// exclude
2286
+			array(
2287
+				EEM_Registration::status_id_cancelled,
2288
+				EEM_Registration::status_id_declined,
2289
+				EEM_Registration::status_id_incomplete,
2290
+				EEM_Registration::status_id_wait_list,
2291
+			),
2292
+			true
2293
+		);
2294
+		return new EE_Form_Section_Proper(
2295
+			array(
2296
+				'name'            => 'update_default_event_settings',
2297
+				'html_id'         => 'update_default_event_settings',
2298
+				'html_class'      => 'form-table',
2299
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2300
+				'subsections'     => apply_filters(
2301
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2302
+					array(
2303
+						'default_reg_status'  => new EE_Select_Input(
2304
+							$registration_stati_for_selection,
2305
+							array(
2306
+								'default'         => isset($registration_config->default_STS_ID)
2307
+													 && array_key_exists(
2308
+														 $registration_config->default_STS_ID,
2309
+														 $registration_stati_for_selection
2310
+													 )
2311
+									? sanitize_text_field($registration_config->default_STS_ID)
2312
+									: EEM_Registration::status_id_pending_payment,
2313
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2314
+													 . EEH_Template::get_help_tab_link(
2315
+														 'default_settings_status_help_tab'
2316
+													 ),
2317
+								'html_help_text'  => esc_html__(
2318
+									'This setting allows you to preselect what the default registration status setting is when creating an event.  Note that changing this setting does NOT retroactively apply it to existing events.',
2319
+									'event_espresso'
2320
+								),
2321
+							)
2322
+						),
2323
+						'default_max_tickets' => new EE_Integer_Input(
2324
+							array(
2325
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2326
+									? $registration_config->default_maximum_number_of_tickets
2327
+									: EEM_Event::get_default_additional_limit(),
2328
+								'html_label_text' => esc_html__(
2329
+									'Default Maximum Tickets Allowed Per Order:',
2330
+									'event_espresso'
2331
+								)
2332
+													 . EEH_Template::get_help_tab_link(
2333
+														 'default_maximum_tickets_help_tab"'
2334
+													 ),
2335
+								'html_help_text'  => esc_html__(
2336
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2337
+									'event_espresso'
2338
+								),
2339
+							)
2340
+						),
2341
+					)
2342
+				),
2343
+			)
2344
+		);
2345
+	}
2346
+
2347
+
2348
+	/**
2349
+	 * @return void
2350
+	 * @throws EE_Error
2351
+	 * @throws InvalidArgumentException
2352
+	 * @throws InvalidDataTypeException
2353
+	 * @throws InvalidInterfaceException
2354
+	 */
2355
+	protected function _update_default_event_settings()
2356
+	{
2357
+		$form = $this->_default_event_settings_form();
2358
+		if ($form->was_submitted()) {
2359
+			$form->receive_form_submission();
2360
+			if ($form->is_valid()) {
2361
+				$registration_config = EE_Registry::instance()->CFG->registration;
2362
+				$valid_data = $form->valid_data();
2363
+				if (isset($valid_data['default_reg_status'])) {
2364
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2365
+				}
2366
+				if (isset($valid_data['default_max_tickets'])) {
2367
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2368
+				}
2369
+				do_action(
2370
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2371
+					$valid_data,
2372
+					EE_Registry::instance()->CFG,
2373
+					$this
2374
+				);
2375
+				// update because data was valid!
2376
+				EE_Registry::instance()->CFG->update_espresso_config();
2377
+				EE_Error::overwrite_success();
2378
+				EE_Error::add_success(
2379
+					__('Default Event Settings were updated', 'event_espresso')
2380
+				);
2381
+			}
2382
+		}
2383
+		$this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true);
2384
+	}
2385
+
2386
+
2387
+	/*************        Templates        *************/
2388
+	protected function _template_settings()
2389
+	{
2390
+		$this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2391
+		$this->_template_args['preview_img'] = '<img src="'
2392
+											   . EVENTS_ASSETS_URL
2393
+											   . '/images/'
2394
+											   . 'caffeinated_template_features.jpg" alt="'
2395
+											   . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2396
+											   . '" />';
2397
+		$this->_template_args['preview_text'] = '<strong>'
2398
+												. esc_html__(
2399
+													'Template Settings is a feature that is only available in the premium version of Event Espresso 4 which is available with a support license purchase on EventEspresso.com. Template Settings allow you to configure some of the appearance options for both the Event List and Event Details pages.',
2400
+													'event_espresso'
2401
+												) . '</strong>';
2402
+		$this->display_admin_caf_preview_page('template_settings_tab');
2403
+	}
2404
+
2405
+
2406
+	/** Event Category Stuff **/
2407
+	/**
2408
+	 * set the _category property with the category object for the loaded page.
2409
+	 *
2410
+	 * @access private
2411
+	 * @return void
2412
+	 */
2413
+	private function _set_category_object()
2414
+	{
2415
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2416
+			return;
2417
+		} //already have the category object so get out.
2418
+		// set default category object
2419
+		$this->_set_empty_category_object();
2420
+		// only set if we've got an id
2421
+		if (! isset($this->_req_data['EVT_CAT_ID'])) {
2422
+			return;
2423
+		}
2424
+		$category_id = absint($this->_req_data['EVT_CAT_ID']);
2425
+		$term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2426
+		if (! empty($term)) {
2427
+			$this->_category->category_name = $term->name;
2428
+			$this->_category->category_identifier = $term->slug;
2429
+			$this->_category->category_desc = $term->description;
2430
+			$this->_category->id = $term->term_id;
2431
+			$this->_category->parent = $term->parent;
2432
+		}
2433
+	}
2434
+
2435
+
2436
+	/**
2437
+	 * Clears out category properties.
2438
+	 */
2439
+	private function _set_empty_category_object()
2440
+	{
2441
+		$this->_category = new stdClass();
2442
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2443
+		$this->_category->id = $this->_category->parent = 0;
2444
+	}
2445
+
2446
+
2447
+	/**
2448
+	 * @throws EE_Error
2449
+	 */
2450
+	protected function _category_list_table()
2451
+	{
2452
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2453
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2454
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2455
+			'add_category',
2456
+			'add_category',
2457
+			array(),
2458
+			'add-new-h2'
2459
+		);
2460
+		$this->display_admin_list_table_page_with_sidebar();
2461
+	}
2462
+
2463
+
2464
+	/**
2465
+	 * Output category details view.
2466
+	 */
2467
+	protected function _category_details($view)
2468
+	{
2469
+		// load formatter helper
2470
+		// load field generator helper
2471
+		$route = $view == 'edit' ? 'update_category' : 'insert_category';
2472
+		$this->_set_add_edit_form_tags($route);
2473
+		$this->_set_category_object();
2474
+		$id = ! empty($this->_category->id) ? $this->_category->id : '';
2475
+		$delete_action = 'delete_category';
2476
+		// custom redirect
2477
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2478
+			array('action' => 'category_list'),
2479
+			$this->_admin_base_url
2480
+		);
2481
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2482
+		// take care of contents
2483
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2484
+		$this->display_admin_page_with_sidebar();
2485
+	}
2486
+
2487
+
2488
+	/**
2489
+	 * Output category details content.
2490
+	 */
2491
+	protected function _category_details_content()
2492
+	{
2493
+		$editor_args['category_desc'] = array(
2494
+			'type'          => 'wp_editor',
2495
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2496
+			'class'         => 'my_editor_custom',
2497
+			'wpeditor_args' => array('media_buttons' => false),
2498
+		);
2499
+		$_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2500
+		$all_terms = get_terms(
2501
+			array(EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY),
2502
+			array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2503
+		);
2504
+		// setup category select for term parents.
2505
+		$category_select_values[] = array(
2506
+			'text' => esc_html__('No Parent', 'event_espresso'),
2507
+			'id'   => 0,
2508
+		);
2509
+		foreach ($all_terms as $term) {
2510
+			$category_select_values[] = array(
2511
+				'text' => $term->name,
2512
+				'id'   => $term->term_id,
2513
+			);
2514
+		}
2515
+		$category_select = EEH_Form_Fields::select_input(
2516
+			'category_parent',
2517
+			$category_select_values,
2518
+			$this->_category->parent
2519
+		);
2520
+		$template_args = array(
2521
+			'category'                 => $this->_category,
2522
+			'category_select'          => $category_select,
2523
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2524
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2525
+			'disable'                  => '',
2526
+			'disabled_message'         => false,
2527
+		);
2528
+		$template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2529
+		return EEH_Template::display_template($template, $template_args, true);
2530
+	}
2531
+
2532
+
2533
+	/**
2534
+	 * Handles deleting categories.
2535
+	 */
2536
+	protected function _delete_categories()
2537
+	{
2538
+		$cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2539
+			: (array) $this->_req_data['category_id'];
2540
+		foreach ($cat_ids as $cat_id) {
2541
+			$this->_delete_category($cat_id);
2542
+		}
2543
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2544
+		$query_args = array(
2545
+			'action' => 'category_list',
2546
+		);
2547
+		$this->_redirect_after_action(0, '', '', $query_args);
2548
+	}
2549
+
2550
+
2551
+	/**
2552
+	 * Handles deleting specific category.
2553
+	 *
2554
+	 * @param int $cat_id
2555
+	 */
2556
+	protected function _delete_category($cat_id)
2557
+	{
2558
+		$cat_id = absint($cat_id);
2559
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2560
+	}
2561
+
2562
+
2563
+	/**
2564
+	 * Handles triggering the update or insertion of a new category.
2565
+	 *
2566
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2567
+	 */
2568
+	protected function _insert_or_update_category($new_category)
2569
+	{
2570
+		$cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2571
+		$success = 0; // we already have a success message so lets not send another.
2572
+		if ($cat_id) {
2573
+			$query_args = array(
2574
+				'action'     => 'edit_category',
2575
+				'EVT_CAT_ID' => $cat_id,
2576
+			);
2577
+		} else {
2578
+			$query_args = array('action' => 'add_category');
2579
+		}
2580
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2581
+	}
2582
+
2583
+
2584
+	/**
2585
+	 * Inserts or updates category
2586
+	 *
2587
+	 * @param bool $update (true indicates we're updating a category).
2588
+	 * @return bool|mixed|string
2589
+	 */
2590
+	private function _insert_category($update = false)
2591
+	{
2592
+		$cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2593
+		$category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2594
+		$category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2595
+		$category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2596
+		if (empty($category_name)) {
2597
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2598
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2599
+			return false;
2600
+		}
2601
+		$term_args = array(
2602
+			'name'        => $category_name,
2603
+			'description' => $category_desc,
2604
+			'parent'      => $category_parent,
2605
+		);
2606
+		// was the category_identifier input disabled?
2607
+		if (isset($this->_req_data['category_identifier'])) {
2608
+			$term_args['slug'] = $this->_req_data['category_identifier'];
2609
+		}
2610
+		$insert_ids = $update
2611
+			? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2612
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2613
+		if (! is_array($insert_ids)) {
2614
+			$msg = esc_html__(
2615
+				'An error occurred and the category has not been saved to the database.',
2616
+				'event_espresso'
2617
+			);
2618
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2619
+		} else {
2620
+			$cat_id = $insert_ids['term_id'];
2621
+			$msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2622
+			EE_Error::add_success($msg);
2623
+		}
2624
+		return $cat_id;
2625
+	}
2626
+
2627
+
2628
+	/**
2629
+	 * Gets categories or count of categories matching the arguments in the request.
2630
+	 *
2631
+	 * @param int  $per_page
2632
+	 * @param int  $current_page
2633
+	 * @param bool $count
2634
+	 * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int
2635
+	 */
2636
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2637
+	{
2638
+		// testing term stuff
2639
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2640
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2641
+		$limit = ($current_page - 1) * $per_page;
2642
+		$where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2643
+		if (isset($this->_req_data['s'])) {
2644
+			$sstr = '%' . $this->_req_data['s'] . '%';
2645
+			$where['OR'] = array(
2646
+				'Term.name'   => array('LIKE', $sstr),
2647
+				'description' => array('LIKE', $sstr),
2648
+			);
2649
+		}
2650
+		$query_params = array(
2651
+			$where,
2652
+			'order_by'   => array($orderby => $order),
2653
+			'limit'      => $limit . ',' . $per_page,
2654
+			'force_join' => array('Term'),
2655
+		);
2656
+		$categories = $count
2657
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2658
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2659
+		return $categories;
2660
+	}
2661
+
2662
+	/* end category stuff */
2663
+	/**************/
2664
+
2665
+
2666
+	/**
2667
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2668
+	 *
2669
+	 * @throws EE_Error
2670
+	 */
2671
+	public function save_timezonestring_setting()
2672
+	{
2673
+		$timezone_string = isset($this->_req_data['timezone_selected'])
2674
+			? $this->_req_data['timezone_selected']
2675
+			: '';
2676
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2677
+			EE_Error::add_error(
2678
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2679
+				__FILE__,
2680
+				__FUNCTION__,
2681
+				__LINE__
2682
+			);
2683
+			$this->_template_args['error'] = true;
2684
+			$this->_return_json();
2685
+		}
2686
+
2687
+		update_option('timezone_string', $timezone_string);
2688
+		EE_Error::add_success(
2689
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2690
+		);
2691
+		$this->_template_args['success'] = true;
2692
+		$this->_return_json(true, array('action' => 'create_new'));
2693
+	}
2694 2694
 }
Please login to merge, or discard this patch.
caffeinated/admin/extend/events/Extend_Events_Admin_Page.core.php 2 patches
Indentation   +1363 added lines, -1363 removed lines patch added patch discarded remove patch
@@ -15,1370 +15,1370 @@
 block discarded – undo
15 15
 class Extend_Events_Admin_Page extends Events_Admin_Page
16 16
 {
17 17
 
18
-    /**
19
-     * @var EE_Admin_Config
20
-     */
21
-    protected $admin_config;
22
-
23
-
24
-    /**
25
-     * Extend_Events_Admin_Page constructor.
26
-     *
27
-     * @param bool $routing
28
-     */
29
-    public function __construct($routing = true)
30
-    {
31
-        parent::__construct($routing);
32
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
33
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
34
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
35
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
36
-        }
37
-    }
38
-
39
-
40
-    /**
41
-     * Sets routes.
42
-     */
43
-    protected function _extend_page_config()
44
-    {
45
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
46
-        // is there a evt_id in the request?
47
-        $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
48
-            ? $this->_req_data['EVT_ID']
49
-            : 0;
50
-        $evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
51
-        // tkt_id?
52
-        $tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
53
-            ? $this->_req_data['TKT_ID']
54
-            : 0;
55
-        $new_page_routes = array(
56
-            'duplicate_event'          => array(
57
-                'func'       => '_duplicate_event',
58
-                'capability' => 'ee_edit_event',
59
-                'obj_id'     => $evt_id,
60
-                'noheader'   => true,
61
-            ),
62
-            'ticket_list_table'        => array(
63
-                'func'       => '_tickets_overview_list_table',
64
-                'capability' => 'ee_read_default_tickets',
65
-            ),
66
-            'trash_ticket'             => array(
67
-                'func'       => '_trash_or_restore_ticket',
68
-                'capability' => 'ee_delete_default_ticket',
69
-                'obj_id'     => $tkt_id,
70
-                'noheader'   => true,
71
-                'args'       => array('trash' => true),
72
-            ),
73
-            'trash_tickets'            => array(
74
-                'func'       => '_trash_or_restore_ticket',
75
-                'capability' => 'ee_delete_default_tickets',
76
-                'noheader'   => true,
77
-                'args'       => array('trash' => true),
78
-            ),
79
-            'restore_ticket'           => array(
80
-                'func'       => '_trash_or_restore_ticket',
81
-                'capability' => 'ee_delete_default_ticket',
82
-                'obj_id'     => $tkt_id,
83
-                'noheader'   => true,
84
-            ),
85
-            'restore_tickets'          => array(
86
-                'func'       => '_trash_or_restore_ticket',
87
-                'capability' => 'ee_delete_default_tickets',
88
-                'noheader'   => true,
89
-            ),
90
-            'delete_ticket'            => array(
91
-                'func'       => '_delete_ticket',
92
-                'capability' => 'ee_delete_default_ticket',
93
-                'obj_id'     => $tkt_id,
94
-                'noheader'   => true,
95
-            ),
96
-            'delete_tickets'           => array(
97
-                'func'       => '_delete_ticket',
98
-                'capability' => 'ee_delete_default_tickets',
99
-                'noheader'   => true,
100
-            ),
101
-            'import_page'              => array(
102
-                'func'       => '_import_page',
103
-                'capability' => 'import',
104
-            ),
105
-            'import'                   => array(
106
-                'func'       => '_import_events',
107
-                'capability' => 'import',
108
-                'noheader'   => true,
109
-            ),
110
-            'import_events'            => array(
111
-                'func'       => '_import_events',
112
-                'capability' => 'import',
113
-                'noheader'   => true,
114
-            ),
115
-            'export_events'            => array(
116
-                'func'       => '_events_export',
117
-                'capability' => 'export',
118
-                'noheader'   => true,
119
-            ),
120
-            'export_categories'        => array(
121
-                'func'       => '_categories_export',
122
-                'capability' => 'export',
123
-                'noheader'   => true,
124
-            ),
125
-            'sample_export_file'       => array(
126
-                'func'       => '_sample_export_file',
127
-                'capability' => 'export',
128
-                'noheader'   => true,
129
-            ),
130
-            'update_template_settings' => array(
131
-                'func'       => '_update_template_settings',
132
-                'capability' => 'manage_options',
133
-                'noheader'   => true,
134
-            ),
135
-        );
136
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
137
-        // partial route/config override
138
-        $this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
139
-        $this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
140
-        $this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
141
-        $this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
142
-        $this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
143
-        $this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
144
-        // add tickets tab but only if there are more than one default ticket!
145
-        $tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
146
-            array(array('TKT_is_default' => 1)),
147
-            'TKT_ID',
148
-            true
149
-        );
150
-        if ($tkt_count > 1) {
151
-            $new_page_config = array(
152
-                'ticket_list_table' => array(
153
-                    'nav'           => array(
154
-                        'label' => esc_html__('Default Tickets', 'event_espresso'),
155
-                        'order' => 60,
156
-                    ),
157
-                    'list_table'    => 'Tickets_List_Table',
158
-                    'require_nonce' => false,
159
-                ),
160
-            );
161
-        }
162
-        // template settings
163
-        $new_page_config['template_settings'] = array(
164
-            'nav'           => array(
165
-                'label' => esc_html__('Templates', 'event_espresso'),
166
-                'order' => 30,
167
-            ),
168
-            'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
169
-            'help_tabs'     => array(
170
-                'general_settings_templates_help_tab' => array(
171
-                    'title'    => esc_html__('Templates', 'event_espresso'),
172
-                    'filename' => 'general_settings_templates',
173
-                ),
174
-            ),
175
-            'help_tour'     => array('Templates_Help_Tour'),
176
-            'require_nonce' => false,
177
-        );
178
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
179
-        // add filters and actions
180
-        // modifying _views
181
-        add_filter(
182
-            'FHEE_event_datetime_metabox_add_additional_date_time_template',
183
-            array($this, 'add_additional_datetime_button'),
184
-            10,
185
-            2
186
-        );
187
-        add_filter(
188
-            'FHEE_event_datetime_metabox_clone_button_template',
189
-            array($this, 'add_datetime_clone_button'),
190
-            10,
191
-            2
192
-        );
193
-        add_filter(
194
-            'FHEE_event_datetime_metabox_timezones_template',
195
-            array($this, 'datetime_timezones_template'),
196
-            10,
197
-            2
198
-        );
199
-        // filters for event list table
200
-        add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
201
-        add_filter(
202
-            'FHEE__Events_Admin_List_Table__column_actions__action_links',
203
-            array($this, 'extra_list_table_actions'),
204
-            10,
205
-            2
206
-        );
207
-        // legend item
208
-        add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
209
-        add_action('admin_init', array($this, 'admin_init'));
210
-        $this->admin_config = EE_Registry::instance()->CFG->admin;
211
-        add_filter(
212
-            'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
213
-            [$this, 'advancedEditorAdminFormSection']
214
-        );
215
-        add_action(
216
-            'AHEE__Events_Admin_Page___update_default_event_settings',
217
-            [$this, 'updateAdvancedEditorAdminFormSettings'],
218
-            10,
219
-            2
220
-        );
221
-    }
222
-
223
-
224
-    /**
225
-     * admin_init
226
-     */
227
-    public function admin_init()
228
-    {
229
-        EE_Registry::$i18n_js_strings = array_merge(
230
-            EE_Registry::$i18n_js_strings,
231
-            array(
232
-                'image_confirm'          => esc_html__(
233
-                    'Do you really want to delete this image? Please remember to update your event to complete the removal.',
234
-                    'event_espresso'
235
-                ),
236
-                'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
237
-                'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
238
-                'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
239
-                'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
240
-                'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
241
-            )
242
-        );
243
-    }
244
-
245
-
246
-    /**
247
-     * Add per page screen options to the default ticket list table view.
248
-     */
249
-    protected function _add_screen_options_ticket_list_table()
250
-    {
251
-        $this->_per_page_screen_option();
252
-    }
253
-
254
-
255
-    /**
256
-     * @param string $return
257
-     * @param int    $id
258
-     * @param string $new_title
259
-     * @param string $new_slug
260
-     * @return string
261
-     */
262
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
263
-    {
264
-        $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
265
-        // make sure this is only when editing
266
-        if (! empty($id)) {
267
-            $href = EE_Admin_Page::add_query_args_and_nonce(
268
-                array('action' => 'duplicate_event', 'EVT_ID' => $id),
269
-                $this->_admin_base_url
270
-            );
271
-            $title = esc_attr__('Duplicate Event', 'event_espresso');
272
-            $return .= '<a href="'
273
-                       . $href
274
-                       . '" title="'
275
-                       . $title
276
-                       . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
277
-                       . $title
278
-                       . '</a>';
279
-        }
280
-        return $return;
281
-    }
282
-
283
-
284
-    /**
285
-     * Set the list table views for the default ticket list table view.
286
-     */
287
-    public function _set_list_table_views_ticket_list_table()
288
-    {
289
-        $this->_views = array(
290
-            'all'     => array(
291
-                'slug'        => 'all',
292
-                'label'       => esc_html__('All', 'event_espresso'),
293
-                'count'       => 0,
294
-                'bulk_action' => array(
295
-                    'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
296
-                ),
297
-            ),
298
-            'trashed' => array(
299
-                'slug'        => 'trashed',
300
-                'label'       => esc_html__('Trash', 'event_espresso'),
301
-                'count'       => 0,
302
-                'bulk_action' => array(
303
-                    'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
304
-                    'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
305
-                ),
306
-            ),
307
-        );
308
-    }
309
-
310
-
311
-    /**
312
-     * Enqueue scripts and styles for the event editor.
313
-     */
314
-    public function load_scripts_styles_edit()
315
-    {
316
-        wp_register_script(
317
-            'ee-event-editor-heartbeat',
318
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
319
-            array('ee_admin_js', 'heartbeat'),
320
-            EVENT_ESPRESSO_VERSION,
321
-            true
322
-        );
323
-        wp_enqueue_script('ee-accounting');
324
-        // styles
325
-        wp_enqueue_style('espresso-ui-theme');
326
-        wp_enqueue_script('event_editor_js');
327
-        wp_enqueue_script('ee-event-editor-heartbeat');
328
-        if ($this->admin_config->useAdvancedEditor()) {
329
-            add_action(
330
-                'admin_footer',
331
-                function () {
332
-                    $eventId = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : 0;
333
-                    if ($eventId) {
334
-                        echo '
18
+	/**
19
+	 * @var EE_Admin_Config
20
+	 */
21
+	protected $admin_config;
22
+
23
+
24
+	/**
25
+	 * Extend_Events_Admin_Page constructor.
26
+	 *
27
+	 * @param bool $routing
28
+	 */
29
+	public function __construct($routing = true)
30
+	{
31
+		parent::__construct($routing);
32
+		if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
33
+			define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
34
+			define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
35
+			define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
36
+		}
37
+	}
38
+
39
+
40
+	/**
41
+	 * Sets routes.
42
+	 */
43
+	protected function _extend_page_config()
44
+	{
45
+		$this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
46
+		// is there a evt_id in the request?
47
+		$evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
48
+			? $this->_req_data['EVT_ID']
49
+			: 0;
50
+		$evt_id = ! empty($this->_req_data['post']) ? $this->_req_data['post'] : $evt_id;
51
+		// tkt_id?
52
+		$tkt_id = ! empty($this->_req_data['TKT_ID']) && ! is_array($this->_req_data['TKT_ID'])
53
+			? $this->_req_data['TKT_ID']
54
+			: 0;
55
+		$new_page_routes = array(
56
+			'duplicate_event'          => array(
57
+				'func'       => '_duplicate_event',
58
+				'capability' => 'ee_edit_event',
59
+				'obj_id'     => $evt_id,
60
+				'noheader'   => true,
61
+			),
62
+			'ticket_list_table'        => array(
63
+				'func'       => '_tickets_overview_list_table',
64
+				'capability' => 'ee_read_default_tickets',
65
+			),
66
+			'trash_ticket'             => array(
67
+				'func'       => '_trash_or_restore_ticket',
68
+				'capability' => 'ee_delete_default_ticket',
69
+				'obj_id'     => $tkt_id,
70
+				'noheader'   => true,
71
+				'args'       => array('trash' => true),
72
+			),
73
+			'trash_tickets'            => array(
74
+				'func'       => '_trash_or_restore_ticket',
75
+				'capability' => 'ee_delete_default_tickets',
76
+				'noheader'   => true,
77
+				'args'       => array('trash' => true),
78
+			),
79
+			'restore_ticket'           => array(
80
+				'func'       => '_trash_or_restore_ticket',
81
+				'capability' => 'ee_delete_default_ticket',
82
+				'obj_id'     => $tkt_id,
83
+				'noheader'   => true,
84
+			),
85
+			'restore_tickets'          => array(
86
+				'func'       => '_trash_or_restore_ticket',
87
+				'capability' => 'ee_delete_default_tickets',
88
+				'noheader'   => true,
89
+			),
90
+			'delete_ticket'            => array(
91
+				'func'       => '_delete_ticket',
92
+				'capability' => 'ee_delete_default_ticket',
93
+				'obj_id'     => $tkt_id,
94
+				'noheader'   => true,
95
+			),
96
+			'delete_tickets'           => array(
97
+				'func'       => '_delete_ticket',
98
+				'capability' => 'ee_delete_default_tickets',
99
+				'noheader'   => true,
100
+			),
101
+			'import_page'              => array(
102
+				'func'       => '_import_page',
103
+				'capability' => 'import',
104
+			),
105
+			'import'                   => array(
106
+				'func'       => '_import_events',
107
+				'capability' => 'import',
108
+				'noheader'   => true,
109
+			),
110
+			'import_events'            => array(
111
+				'func'       => '_import_events',
112
+				'capability' => 'import',
113
+				'noheader'   => true,
114
+			),
115
+			'export_events'            => array(
116
+				'func'       => '_events_export',
117
+				'capability' => 'export',
118
+				'noheader'   => true,
119
+			),
120
+			'export_categories'        => array(
121
+				'func'       => '_categories_export',
122
+				'capability' => 'export',
123
+				'noheader'   => true,
124
+			),
125
+			'sample_export_file'       => array(
126
+				'func'       => '_sample_export_file',
127
+				'capability' => 'export',
128
+				'noheader'   => true,
129
+			),
130
+			'update_template_settings' => array(
131
+				'func'       => '_update_template_settings',
132
+				'capability' => 'manage_options',
133
+				'noheader'   => true,
134
+			),
135
+		);
136
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
137
+		// partial route/config override
138
+		$this->_page_config['import_events']['metaboxes'] = $this->_default_espresso_metaboxes;
139
+		$this->_page_config['create_new']['metaboxes'][] = '_premium_event_editor_meta_boxes';
140
+		$this->_page_config['create_new']['qtips'][] = 'EE_Event_Editor_Tips';
141
+		$this->_page_config['edit']['qtips'][] = 'EE_Event_Editor_Tips';
142
+		$this->_page_config['edit']['metaboxes'][] = '_premium_event_editor_meta_boxes';
143
+		$this->_page_config['default']['list_table'] = 'Extend_Events_Admin_List_Table';
144
+		// add tickets tab but only if there are more than one default ticket!
145
+		$tkt_count = EEM_Ticket::instance()->count_deleted_and_undeleted(
146
+			array(array('TKT_is_default' => 1)),
147
+			'TKT_ID',
148
+			true
149
+		);
150
+		if ($tkt_count > 1) {
151
+			$new_page_config = array(
152
+				'ticket_list_table' => array(
153
+					'nav'           => array(
154
+						'label' => esc_html__('Default Tickets', 'event_espresso'),
155
+						'order' => 60,
156
+					),
157
+					'list_table'    => 'Tickets_List_Table',
158
+					'require_nonce' => false,
159
+				),
160
+			);
161
+		}
162
+		// template settings
163
+		$new_page_config['template_settings'] = array(
164
+			'nav'           => array(
165
+				'label' => esc_html__('Templates', 'event_espresso'),
166
+				'order' => 30,
167
+			),
168
+			'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
169
+			'help_tabs'     => array(
170
+				'general_settings_templates_help_tab' => array(
171
+					'title'    => esc_html__('Templates', 'event_espresso'),
172
+					'filename' => 'general_settings_templates',
173
+				),
174
+			),
175
+			'help_tour'     => array('Templates_Help_Tour'),
176
+			'require_nonce' => false,
177
+		);
178
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
179
+		// add filters and actions
180
+		// modifying _views
181
+		add_filter(
182
+			'FHEE_event_datetime_metabox_add_additional_date_time_template',
183
+			array($this, 'add_additional_datetime_button'),
184
+			10,
185
+			2
186
+		);
187
+		add_filter(
188
+			'FHEE_event_datetime_metabox_clone_button_template',
189
+			array($this, 'add_datetime_clone_button'),
190
+			10,
191
+			2
192
+		);
193
+		add_filter(
194
+			'FHEE_event_datetime_metabox_timezones_template',
195
+			array($this, 'datetime_timezones_template'),
196
+			10,
197
+			2
198
+		);
199
+		// filters for event list table
200
+		add_filter('FHEE__Extend_Events_Admin_List_Table__filters', array($this, 'list_table_filters'), 10, 2);
201
+		add_filter(
202
+			'FHEE__Events_Admin_List_Table__column_actions__action_links',
203
+			array($this, 'extra_list_table_actions'),
204
+			10,
205
+			2
206
+		);
207
+		// legend item
208
+		add_filter('FHEE__Events_Admin_Page___event_legend_items__items', array($this, 'additional_legend_items'));
209
+		add_action('admin_init', array($this, 'admin_init'));
210
+		$this->admin_config = EE_Registry::instance()->CFG->admin;
211
+		add_filter(
212
+			'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
213
+			[$this, 'advancedEditorAdminFormSection']
214
+		);
215
+		add_action(
216
+			'AHEE__Events_Admin_Page___update_default_event_settings',
217
+			[$this, 'updateAdvancedEditorAdminFormSettings'],
218
+			10,
219
+			2
220
+		);
221
+	}
222
+
223
+
224
+	/**
225
+	 * admin_init
226
+	 */
227
+	public function admin_init()
228
+	{
229
+		EE_Registry::$i18n_js_strings = array_merge(
230
+			EE_Registry::$i18n_js_strings,
231
+			array(
232
+				'image_confirm'          => esc_html__(
233
+					'Do you really want to delete this image? Please remember to update your event to complete the removal.',
234
+					'event_espresso'
235
+				),
236
+				'event_starts_on'        => esc_html__('Event Starts on', 'event_espresso'),
237
+				'event_ends_on'          => esc_html__('Event Ends on', 'event_espresso'),
238
+				'event_datetime_actions' => esc_html__('Actions', 'event_espresso'),
239
+				'event_clone_dt_msg'     => esc_html__('Clone this Event Date and Time', 'event_espresso'),
240
+				'remove_event_dt_msg'    => esc_html__('Remove this Event Time', 'event_espresso'),
241
+			)
242
+		);
243
+	}
244
+
245
+
246
+	/**
247
+	 * Add per page screen options to the default ticket list table view.
248
+	 */
249
+	protected function _add_screen_options_ticket_list_table()
250
+	{
251
+		$this->_per_page_screen_option();
252
+	}
253
+
254
+
255
+	/**
256
+	 * @param string $return
257
+	 * @param int    $id
258
+	 * @param string $new_title
259
+	 * @param string $new_slug
260
+	 * @return string
261
+	 */
262
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
263
+	{
264
+		$return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
265
+		// make sure this is only when editing
266
+		if (! empty($id)) {
267
+			$href = EE_Admin_Page::add_query_args_and_nonce(
268
+				array('action' => 'duplicate_event', 'EVT_ID' => $id),
269
+				$this->_admin_base_url
270
+			);
271
+			$title = esc_attr__('Duplicate Event', 'event_espresso');
272
+			$return .= '<a href="'
273
+					   . $href
274
+					   . '" title="'
275
+					   . $title
276
+					   . '" id="ee-duplicate-event-button" class="button button-small"  value="duplicate_event">'
277
+					   . $title
278
+					   . '</a>';
279
+		}
280
+		return $return;
281
+	}
282
+
283
+
284
+	/**
285
+	 * Set the list table views for the default ticket list table view.
286
+	 */
287
+	public function _set_list_table_views_ticket_list_table()
288
+	{
289
+		$this->_views = array(
290
+			'all'     => array(
291
+				'slug'        => 'all',
292
+				'label'       => esc_html__('All', 'event_espresso'),
293
+				'count'       => 0,
294
+				'bulk_action' => array(
295
+					'trash_tickets' => esc_html__('Move to Trash', 'event_espresso'),
296
+				),
297
+			),
298
+			'trashed' => array(
299
+				'slug'        => 'trashed',
300
+				'label'       => esc_html__('Trash', 'event_espresso'),
301
+				'count'       => 0,
302
+				'bulk_action' => array(
303
+					'restore_tickets' => esc_html__('Restore from Trash', 'event_espresso'),
304
+					'delete_tickets'  => esc_html__('Delete Permanently', 'event_espresso'),
305
+				),
306
+			),
307
+		);
308
+	}
309
+
310
+
311
+	/**
312
+	 * Enqueue scripts and styles for the event editor.
313
+	 */
314
+	public function load_scripts_styles_edit()
315
+	{
316
+		wp_register_script(
317
+			'ee-event-editor-heartbeat',
318
+			EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
319
+			array('ee_admin_js', 'heartbeat'),
320
+			EVENT_ESPRESSO_VERSION,
321
+			true
322
+		);
323
+		wp_enqueue_script('ee-accounting');
324
+		// styles
325
+		wp_enqueue_style('espresso-ui-theme');
326
+		wp_enqueue_script('event_editor_js');
327
+		wp_enqueue_script('ee-event-editor-heartbeat');
328
+		if ($this->admin_config->useAdvancedEditor()) {
329
+			add_action(
330
+				'admin_footer',
331
+				function () {
332
+					$eventId = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : 0;
333
+					if ($eventId) {
334
+						echo '
335 335
         <script type="text/javascript">
336 336
             /* <![CDATA[ */ var eeEditorEventId = ' . $eventId . '; /* ]]> */
337 337
         </script>';
338
-                    }
339
-                }
340
-            );
341
-        }
342
-    }
343
-
344
-
345
-    /**
346
-     * Returns template for the additional datetime.
347
-     *
348
-     * @param $template
349
-     * @param $template_args
350
-     * @return mixed
351
-     * @throws DomainException
352
-     */
353
-    public function add_additional_datetime_button($template, $template_args)
354
-    {
355
-        return EEH_Template::display_template(
356
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
357
-            $template_args,
358
-            true
359
-        );
360
-    }
361
-
362
-
363
-    /**
364
-     * Returns the template for cloning a datetime.
365
-     *
366
-     * @param $template
367
-     * @param $template_args
368
-     * @return mixed
369
-     * @throws DomainException
370
-     */
371
-    public function add_datetime_clone_button($template, $template_args)
372
-    {
373
-        return EEH_Template::display_template(
374
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
375
-            $template_args,
376
-            true
377
-        );
378
-    }
379
-
380
-
381
-    /**
382
-     * Returns the template for datetime timezones.
383
-     *
384
-     * @param $template
385
-     * @param $template_args
386
-     * @return mixed
387
-     * @throws DomainException
388
-     */
389
-    public function datetime_timezones_template($template, $template_args)
390
-    {
391
-        return EEH_Template::display_template(
392
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
393
-            $template_args,
394
-            true
395
-        );
396
-    }
397
-
398
-
399
-    /**
400
-     * Sets the views for the default list table view.
401
-     */
402
-    protected function _set_list_table_views_default()
403
-    {
404
-        parent::_set_list_table_views_default();
405
-        $new_views = array(
406
-            'today' => array(
407
-                'slug'        => 'today',
408
-                'label'       => esc_html__('Today', 'event_espresso'),
409
-                'count'       => $this->total_events_today(),
410
-                'bulk_action' => array(
411
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
412
-                ),
413
-            ),
414
-            'month' => array(
415
-                'slug'        => 'month',
416
-                'label'       => esc_html__('This Month', 'event_espresso'),
417
-                'count'       => $this->total_events_this_month(),
418
-                'bulk_action' => array(
419
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
420
-                ),
421
-            ),
422
-        );
423
-        $this->_views = array_merge($this->_views, $new_views);
424
-    }
425
-
426
-
427
-    /**
428
-     * Returns the extra action links for the default list table view.
429
-     *
430
-     * @param array     $action_links
431
-     * @param \EE_Event $event
432
-     * @return array
433
-     * @throws EE_Error
434
-     */
435
-    public function extra_list_table_actions(array $action_links, \EE_Event $event)
436
-    {
437
-        if (EE_Registry::instance()->CAP->current_user_can(
438
-            'ee_read_registrations',
439
-            'espresso_registrations_reports',
440
-            $event->ID()
441
-        )
442
-        ) {
443
-            $reports_query_args = array(
444
-                'action' => 'reports',
445
-                'EVT_ID' => $event->ID(),
446
-            );
447
-            $reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
448
-            $action_links[] = '<a href="'
449
-                              . $reports_link
450
-                              . '" title="'
451
-                              . esc_attr__('View Report', 'event_espresso')
452
-                              . '"><div class="dashicons dashicons-chart-bar"></div></a>'
453
-                              . "\n\t";
454
-        }
455
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
456
-            EE_Registry::instance()->load_helper('MSG_Template');
457
-            $action_links[] = EEH_MSG_Template::get_message_action_link(
458
-                'see_notifications_for',
459
-                null,
460
-                array('EVT_ID' => $event->ID())
461
-            );
462
-        }
463
-        return $action_links;
464
-    }
465
-
466
-
467
-    /**
468
-     * @param $items
469
-     * @return mixed
470
-     */
471
-    public function additional_legend_items($items)
472
-    {
473
-        if (EE_Registry::instance()->CAP->current_user_can(
474
-            'ee_read_registrations',
475
-            'espresso_registrations_reports'
476
-        )
477
-        ) {
478
-            $items['reports'] = array(
479
-                'class' => 'dashicons dashicons-chart-bar',
480
-                'desc'  => esc_html__('Event Reports', 'event_espresso'),
481
-            );
482
-        }
483
-        if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
484
-            $related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
485
-            if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
486
-                $items['view_related_messages'] = array(
487
-                    'class' => $related_for_icon['css_class'],
488
-                    'desc'  => $related_for_icon['label'],
489
-                );
490
-            }
491
-        }
492
-        return $items;
493
-    }
494
-
495
-
496
-    /**
497
-     * This is the callback method for the duplicate event route
498
-     * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
499
-     * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
500
-     * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
501
-     * After duplication the redirect is to the new event edit page.
502
-     *
503
-     * @return void
504
-     * @access protected
505
-     * @throws EE_Error If EE_Event is not available with given ID
506
-     */
507
-    protected function _duplicate_event()
508
-    {
509
-        // first make sure the ID for the event is in the request.
510
-        //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
511
-        if (! isset($this->_req_data['EVT_ID'])) {
512
-            EE_Error::add_error(
513
-                esc_html__(
514
-                    'In order to duplicate an event an Event ID is required.  None was given.',
515
-                    'event_espresso'
516
-                ),
517
-                __FILE__,
518
-                __FUNCTION__,
519
-                __LINE__
520
-            );
521
-            $this->_redirect_after_action(false, '', '', array(), true);
522
-            return;
523
-        }
524
-        // k we've got EVT_ID so let's use that to get the event we'll duplicate
525
-        $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
526
-        if (! $orig_event instanceof EE_Event) {
527
-            throw new EE_Error(
528
-                sprintf(
529
-                    esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
530
-                    $this->_req_data['EVT_ID']
531
-                )
532
-            );
533
-        }
534
-        // k now let's clone the $orig_event before getting relations
535
-        $new_event = clone $orig_event;
536
-        // original datetimes
537
-        $orig_datetimes = $orig_event->get_many_related('Datetime');
538
-        // other original relations
539
-        $orig_ven = $orig_event->get_many_related('Venue');
540
-        // reset the ID and modify other details to make it clear this is a dupe
541
-        $new_event->set('EVT_ID', 0);
542
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
543
-        $new_event->set('EVT_name', $new_name);
544
-        $new_event->set(
545
-            'EVT_slug',
546
-            wp_unique_post_slug(
547
-                sanitize_title($orig_event->name()),
548
-                0,
549
-                'publish',
550
-                'espresso_events',
551
-                0
552
-            )
553
-        );
554
-        $new_event->set('status', 'draft');
555
-        // duplicate discussion settings
556
-        $new_event->set('comment_status', $orig_event->get('comment_status'));
557
-        $new_event->set('ping_status', $orig_event->get('ping_status'));
558
-        // save the new event
559
-        $new_event->save();
560
-        // venues
561
-        foreach ($orig_ven as $ven) {
562
-            $new_event->_add_relation_to($ven, 'Venue');
563
-        }
564
-        $new_event->save();
565
-        // now we need to get the question group relations and handle that
566
-        // first primary question groups
567
-        $orig_primary_qgs = $orig_event->get_many_related(
568
-            'Question_Group',
569
-            [['Event_Question_Group.EQG_primary' => true]]
570
-        );
571
-        if (! empty($orig_primary_qgs)) {
572
-            foreach ($orig_primary_qgs as $id => $obj) {
573
-                if ($obj instanceof EE_Question_Group) {
574
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
575
-                }
576
-            }
577
-        }
578
-        // next additional attendee question groups
579
-        $orig_additional_qgs = $orig_event->get_many_related(
580
-            'Question_Group',
581
-            [['Event_Question_Group.EQG_additional' => true]]
582
-        );
583
-        if (! empty($orig_additional_qgs)) {
584
-            foreach ($orig_additional_qgs as $id => $obj) {
585
-                if ($obj instanceof EE_Question_Group) {
586
-                    $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
587
-                }
588
-            }
589
-        }
590
-
591
-        $new_event->save();
592
-
593
-        // k now that we have the new event saved we can loop through the datetimes and start adding relations.
594
-        $cloned_tickets = array();
595
-        foreach ($orig_datetimes as $orig_dtt) {
596
-            if (! $orig_dtt instanceof EE_Datetime) {
597
-                continue;
598
-            }
599
-            $new_dtt = clone $orig_dtt;
600
-            $orig_tkts = $orig_dtt->tickets();
601
-            // save new dtt then add to event
602
-            $new_dtt->set('DTT_ID', 0);
603
-            $new_dtt->set('DTT_sold', 0);
604
-            $new_dtt->set_reserved(0);
605
-            $new_dtt->save();
606
-            $new_event->_add_relation_to($new_dtt, 'Datetime');
607
-            $new_event->save();
608
-            // now let's get the ticket relations setup.
609
-            foreach ((array) $orig_tkts as $orig_tkt) {
610
-                // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
611
-                if (! $orig_tkt instanceof EE_Ticket) {
612
-                    continue;
613
-                }
614
-                // is this ticket archived?  If it is then let's skip
615
-                if ($orig_tkt->get('TKT_deleted')) {
616
-                    continue;
617
-                }
618
-                // does this original ticket already exist in the clone_tickets cache?
619
-                //  If so we'll just use the new ticket from it.
620
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
621
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
622
-                } else {
623
-                    $new_tkt = clone $orig_tkt;
624
-                    // get relations on the $orig_tkt that we need to setup.
625
-                    $orig_prices = $orig_tkt->prices();
626
-                    $new_tkt->set('TKT_ID', 0);
627
-                    $new_tkt->set('TKT_sold', 0);
628
-                    $new_tkt->set('TKT_reserved', 0);
629
-                    $new_tkt->save(); // make sure new ticket has ID.
630
-                    // price relations on new ticket need to be setup.
631
-                    foreach ($orig_prices as $orig_price) {
632
-                        $new_price = clone $orig_price;
633
-                        $new_price->set('PRC_ID', 0);
634
-                        $new_price->save();
635
-                        $new_tkt->_add_relation_to($new_price, 'Price');
636
-                        $new_tkt->save();
637
-                    }
638
-
639
-                    do_action(
640
-                        'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
641
-                        $orig_tkt,
642
-                        $new_tkt,
643
-                        $orig_prices,
644
-                        $orig_event,
645
-                        $orig_dtt,
646
-                        $new_dtt
647
-                    );
648
-                }
649
-                // k now we can add the new ticket as a relation to the new datetime
650
-                // and make sure its added to our cached $cloned_tickets array
651
-                // for use with later datetimes that have the same ticket.
652
-                $new_dtt->_add_relation_to($new_tkt, 'Ticket');
653
-                $new_dtt->save();
654
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
655
-            }
656
-        }
657
-        // clone taxonomy information
658
-        $taxonomies_to_clone_with = apply_filters(
659
-            'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
660
-            array('espresso_event_categories', 'espresso_event_type', 'post_tag')
661
-        );
662
-        // get terms for original event (notice)
663
-        $orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
664
-        // loop through terms and add them to new event.
665
-        foreach ($orig_terms as $term) {
666
-            wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
667
-        }
668
-
669
-        // duplicate other core WP_Post items for this event.
670
-        // post thumbnail (feature image).
671
-        $feature_image_id = get_post_thumbnail_id($orig_event->ID());
672
-        if ($feature_image_id) {
673
-            update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
674
-        }
675
-
676
-        // duplicate page_template setting
677
-        $page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
678
-        if ($page_template) {
679
-            update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
680
-        }
681
-
682
-        do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
683
-        // now let's redirect to the edit page for this duplicated event if we have a new event id.
684
-        if ($new_event->ID()) {
685
-            $redirect_args = array(
686
-                'post'   => $new_event->ID(),
687
-                'action' => 'edit',
688
-            );
689
-            EE_Error::add_success(
690
-                esc_html__(
691
-                    'Event successfully duplicated.  Please review the details below and make any necessary edits',
692
-                    'event_espresso'
693
-                )
694
-            );
695
-        } else {
696
-            $redirect_args = array(
697
-                'action' => 'default',
698
-            );
699
-            EE_Error::add_error(
700
-                esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
701
-                __FILE__,
702
-                __FUNCTION__,
703
-                __LINE__
704
-            );
705
-        }
706
-        $this->_redirect_after_action(false, '', '', $redirect_args, true);
707
-    }
708
-
709
-
710
-    /**
711
-     * Generates output for the import page.
712
-     *
713
-     * @throws DomainException
714
-     */
715
-    protected function _import_page()
716
-    {
717
-        $title = esc_html__('Import', 'event_espresso');
718
-        $intro = esc_html__(
719
-            'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
720
-            'event_espresso'
721
-        );
722
-        $form_url = EVENTS_ADMIN_URL;
723
-        $action = 'import_events';
724
-        $type = 'csv';
725
-        $this->_template_args['form'] = EE_Import::instance()->upload_form(
726
-            $title,
727
-            $intro,
728
-            $form_url,
729
-            $action,
730
-            $type
731
-        );
732
-        $this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
733
-            array('action' => 'sample_export_file'),
734
-            $this->_admin_base_url
735
-        );
736
-        $content = EEH_Template::display_template(
737
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
738
-            $this->_template_args,
739
-            true
740
-        );
741
-        $this->_template_args['admin_page_content'] = $content;
742
-        $this->display_admin_page_with_sidebar();
743
-    }
744
-
745
-
746
-    /**
747
-     * _import_events
748
-     * This handles displaying the screen and running imports for importing events.
749
-     *
750
-     * @return void
751
-     */
752
-    protected function _import_events()
753
-    {
754
-        require_once(EE_CLASSES . 'EE_Import.class.php');
755
-        $success = EE_Import::instance()->import();
756
-        $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
757
-    }
758
-
759
-
760
-    /**
761
-     * _events_export
762
-     * Will export all (or just the given event) to a Excel compatible file.
763
-     *
764
-     * @access protected
765
-     * @return void
766
-     */
767
-    protected function _events_export()
768
-    {
769
-        if (isset($this->_req_data['EVT_ID'])) {
770
-            $event_ids = $this->_req_data['EVT_ID'];
771
-        } elseif (isset($this->_req_data['EVT_IDs'])) {
772
-            $event_ids = $this->_req_data['EVT_IDs'];
773
-        } else {
774
-            $event_ids = null;
775
-        }
776
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
777
-        $new_request_args = array(
778
-            'export' => 'report',
779
-            'action' => 'all_event_data',
780
-            'EVT_ID' => $event_ids,
781
-        );
782
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
783
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
784
-            require_once(EE_CLASSES . 'EE_Export.class.php');
785
-            $EE_Export = EE_Export::instance($this->_req_data);
786
-            $EE_Export->export();
787
-        }
788
-    }
789
-
790
-
791
-    /**
792
-     * handle category exports()
793
-     *
794
-     * @return void
795
-     */
796
-    protected function _categories_export()
797
-    {
798
-        // todo: I don't like doing this but it'll do until we modify EE_Export Class.
799
-        $new_request_args = array(
800
-            'export'       => 'report',
801
-            'action'       => 'categories',
802
-            'category_ids' => $this->_req_data['EVT_CAT_ID'],
803
-        );
804
-        $this->_req_data = array_merge($this->_req_data, $new_request_args);
805
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
806
-            require_once(EE_CLASSES . 'EE_Export.class.php');
807
-            $EE_Export = EE_Export::instance($this->_req_data);
808
-            $EE_Export->export();
809
-        }
810
-    }
811
-
812
-
813
-    /**
814
-     * Creates a sample CSV file for importing
815
-     */
816
-    protected function _sample_export_file()
817
-    {
818
-        // require_once(EE_CLASSES . 'EE_Export.class.php');
819
-        EE_Export::instance()->export_sample();
820
-    }
821
-
822
-
823
-    /*************        Template Settings        *************/
824
-    /**
825
-     * Generates template settings page output
826
-     *
827
-     * @throws DomainException
828
-     * @throws EE_Error
829
-     */
830
-    protected function _template_settings()
831
-    {
832
-        $this->_template_args['values'] = $this->_yes_no_values;
833
-        /**
834
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
835
-         * from General_Settings_Admin_Page to here.
836
-         */
837
-        $this->_template_args = apply_filters(
838
-            'FHEE__General_Settings_Admin_Page__template_settings__template_args',
839
-            $this->_template_args
840
-        );
841
-        $this->_set_add_edit_form_tags('update_template_settings');
842
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
843
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
844
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
845
-            $this->_template_args,
846
-            true
847
-        );
848
-        $this->display_admin_page_with_sidebar();
849
-    }
850
-
851
-
852
-    /**
853
-     * Handler for updating template settings.
854
-     *
855
-     * @throws InvalidInterfaceException
856
-     * @throws InvalidDataTypeException
857
-     * @throws InvalidArgumentException
858
-     */
859
-    protected function _update_template_settings()
860
-    {
861
-        /**
862
-         * Note leaving this filter in for backward compatibility this was moved in 4.6.x
863
-         * from General_Settings_Admin_Page to here.
864
-         */
865
-        EE_Registry::instance()->CFG->template_settings = apply_filters(
866
-            'FHEE__General_Settings_Admin_Page__update_template_settings__data',
867
-            EE_Registry::instance()->CFG->template_settings,
868
-            $this->_req_data
869
-        );
870
-        // update custom post type slugs and detect if we need to flush rewrite rules
871
-        $old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
872
-        EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
873
-            ? EE_Registry::instance()->CFG->core->event_cpt_slug
874
-            : EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
875
-        $what = 'Template Settings';
876
-        $success = $this->_update_espresso_configuration(
877
-            $what,
878
-            EE_Registry::instance()->CFG->template_settings,
879
-            __FILE__,
880
-            __FUNCTION__,
881
-            __LINE__
882
-        );
883
-        if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
884
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
885
-            $rewrite_rules = LoaderFactory::getLoader()->getShared(
886
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
887
-            );
888
-            $rewrite_rules->flush();
889
-        }
890
-        $this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
891
-    }
892
-
893
-
894
-    /**
895
-     * _premium_event_editor_meta_boxes
896
-     * add all metaboxes related to the event_editor
897
-     *
898
-     * @access protected
899
-     * @return void
900
-     * @throws EE_Error
901
-     */
902
-    protected function _premium_event_editor_meta_boxes()
903
-    {
904
-        $this->verify_cpt_object();
905
-        add_meta_box(
906
-            'espresso_event_editor_event_options',
907
-            esc_html__('Event Registration Options', 'event_espresso'),
908
-            array($this, 'registration_options_meta_box'),
909
-            $this->page_slug,
910
-            'side',
911
-            'core'
912
-        );
913
-    }
914
-
915
-
916
-    /**
917
-     * override caf metabox
918
-     *
919
-     * @return void
920
-     * @throws DomainException
921
-     */
922
-    public function registration_options_meta_box()
923
-    {
924
-        $yes_no_values = array(
925
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
926
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
927
-        );
928
-        $default_reg_status_values = EEM_Registration::reg_status_array(
929
-            array(
930
-                EEM_Registration::status_id_cancelled,
931
-                EEM_Registration::status_id_declined,
932
-                EEM_Registration::status_id_incomplete,
933
-                EEM_Registration::status_id_wait_list,
934
-            ),
935
-            true
936
-        );
937
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
938
-        $template_args['_event'] = $this->_cpt_model_obj;
939
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
940
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
941
-            'default_reg_status',
942
-            $default_reg_status_values,
943
-            $this->_cpt_model_obj->default_registration_status()
944
-        );
945
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
946
-            'display_desc',
947
-            $yes_no_values,
948
-            $this->_cpt_model_obj->display_description()
949
-        );
950
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
951
-            'display_ticket_selector',
952
-            $yes_no_values,
953
-            $this->_cpt_model_obj->display_ticket_selector(),
954
-            '',
955
-            '',
956
-            false
957
-        );
958
-        $template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
959
-            'EVT_default_registration_status',
960
-            $default_reg_status_values,
961
-            $this->_cpt_model_obj->default_registration_status()
962
-        );
963
-        $template_args['additional_registration_options'] = apply_filters(
964
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
965
-            '',
966
-            $template_args,
967
-            $yes_no_values,
968
-            $default_reg_status_values
969
-        );
970
-        EEH_Template::display_template(
971
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
972
-            $template_args
973
-        );
974
-    }
975
-
976
-
977
-
978
-    /**
979
-     * wp_list_table_mods for caf
980
-     * ============================
981
-     */
982
-    /**
983
-     * hook into list table filters and provide filters for caffeinated list table
984
-     *
985
-     * @param  array $old_filters    any existing filters present
986
-     * @param  array $list_table_obj the list table object
987
-     * @return array                  new filters
988
-     */
989
-    public function list_table_filters($old_filters, $list_table_obj)
990
-    {
991
-        $filters = array();
992
-        // first month/year filters
993
-        $filters[] = $this->espresso_event_months_dropdown();
994
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
995
-        // active status dropdown
996
-        if ($status !== 'draft') {
997
-            $filters[] = $this->active_status_dropdown(
998
-                isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
999
-            );
1000
-            $filters[] = $this->venuesDropdown(
1001
-                isset($this->_req_data['venue']) ? $this->_req_data['venue'] : ''
1002
-            );
1003
-        }
1004
-        // category filter
1005
-        $filters[] = $this->category_dropdown();
1006
-        return array_merge($old_filters, $filters);
1007
-    }
1008
-
1009
-
1010
-    /**
1011
-     * espresso_event_months_dropdown
1012
-     *
1013
-     * @access public
1014
-     * @return string                dropdown listing month/year selections for events.
1015
-     */
1016
-    public function espresso_event_months_dropdown()
1017
-    {
1018
-        // what we need to do is get all PRIMARY datetimes for all events to filter on.
1019
-        // Note we need to include any other filters that are set!
1020
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1021
-        // categories?
1022
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1023
-            ? $this->_req_data['EVT_CAT']
1024
-            : null;
1025
-        // active status?
1026
-        $active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1027
-        $cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1028
-        return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1029
-    }
1030
-
1031
-
1032
-    /**
1033
-     * returns a list of "active" statuses on the event
1034
-     *
1035
-     * @param  string $current_value whatever the current active status is
1036
-     * @return string
1037
-     */
1038
-    public function active_status_dropdown($current_value = '')
1039
-    {
1040
-        $select_name = 'active_status';
1041
-        $values = array(
1042
-            'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1043
-            'active'   => esc_html__('Active', 'event_espresso'),
1044
-            'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1045
-            'expired'  => esc_html__('Expired', 'event_espresso'),
1046
-            'inactive' => esc_html__('Inactive', 'event_espresso'),
1047
-        );
1048
-
1049
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1050
-    }
1051
-
1052
-    /**
1053
-     * returns a list of "venues"
1054
-     *
1055
-     * @param  string $current_value whatever the current active status is
1056
-     * @return string
1057
-     */
1058
-    protected function venuesDropdown($current_value = '')
1059
-    {
1060
-        $select_name = 'venue';
1061
-        $values = array(
1062
-            '' => esc_html__('All Venues', 'event_espresso'),
1063
-        );
1064
-        // populate the list of venues.
1065
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1066
-        $venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1067
-
1068
-        foreach ($venues as $venue) {
1069
-            $values[ $venue->ID() ] = $venue->name();
1070
-        }
1071
-
1072
-        return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1073
-    }
1074
-
1075
-
1076
-    /**
1077
-     * output a dropdown of the categories for the category filter on the event admin list table
1078
-     *
1079
-     * @access  public
1080
-     * @return string html
1081
-     */
1082
-    public function category_dropdown()
1083
-    {
1084
-        $cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1085
-        return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1086
-    }
1087
-
1088
-
1089
-    /**
1090
-     * get total number of events today
1091
-     *
1092
-     * @access public
1093
-     * @return int
1094
-     * @throws EE_Error
1095
-     */
1096
-    public function total_events_today()
1097
-    {
1098
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1099
-            'DTT_EVT_start',
1100
-            date('Y-m-d') . ' 00:00:00',
1101
-            'Y-m-d H:i:s',
1102
-            'UTC'
1103
-        );
1104
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1105
-            'DTT_EVT_start',
1106
-            date('Y-m-d') . ' 23:59:59',
1107
-            'Y-m-d H:i:s',
1108
-            'UTC'
1109
-        );
1110
-        $where = array(
1111
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1112
-        );
1113
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1114
-        return $count;
1115
-    }
1116
-
1117
-
1118
-    /**
1119
-     * get total number of events this month
1120
-     *
1121
-     * @access public
1122
-     * @return int
1123
-     * @throws EE_Error
1124
-     */
1125
-    public function total_events_this_month()
1126
-    {
1127
-        // Dates
1128
-        $this_year_r = date('Y');
1129
-        $this_month_r = date('m');
1130
-        $days_this_month = date('t');
1131
-        $start = EEM_Datetime::instance()->convert_datetime_for_query(
1132
-            'DTT_EVT_start',
1133
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1134
-            'Y-m-d H:i:s',
1135
-            'UTC'
1136
-        );
1137
-        $end = EEM_Datetime::instance()->convert_datetime_for_query(
1138
-            'DTT_EVT_start',
1139
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1140
-            'Y-m-d H:i:s',
1141
-            'UTC'
1142
-        );
1143
-        $where = array(
1144
-            'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1145
-        );
1146
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1147
-        return $count;
1148
-    }
1149
-
1150
-
1151
-    /** DEFAULT TICKETS STUFF **/
1152
-
1153
-    /**
1154
-     * Output default tickets list table view.
1155
-     */
1156
-    public function _tickets_overview_list_table()
1157
-    {
1158
-        $this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1159
-        $this->display_admin_list_table_page_with_no_sidebar();
1160
-    }
1161
-
1162
-
1163
-    /**
1164
-     * @param int  $per_page
1165
-     * @param bool $count
1166
-     * @param bool $trashed
1167
-     * @return \EE_Soft_Delete_Base_Class[]|int
1168
-     */
1169
-    public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1170
-    {
1171
-        $orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1172
-        $order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1173
-        switch ($orderby) {
1174
-            case 'TKT_name':
1175
-                $orderby = array('TKT_name' => $order);
1176
-                break;
1177
-            case 'TKT_price':
1178
-                $orderby = array('TKT_price' => $order);
1179
-                break;
1180
-            case 'TKT_uses':
1181
-                $orderby = array('TKT_uses' => $order);
1182
-                break;
1183
-            case 'TKT_min':
1184
-                $orderby = array('TKT_min' => $order);
1185
-                break;
1186
-            case 'TKT_max':
1187
-                $orderby = array('TKT_max' => $order);
1188
-                break;
1189
-            case 'TKT_qty':
1190
-                $orderby = array('TKT_qty' => $order);
1191
-                break;
1192
-        }
1193
-        $current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1194
-            ? $this->_req_data['paged']
1195
-            : 1;
1196
-        $per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1197
-            ? $this->_req_data['perpage']
1198
-            : $per_page;
1199
-        $_where = array(
1200
-            'TKT_is_default' => 1,
1201
-            'TKT_deleted'    => $trashed,
1202
-        );
1203
-        $offset = ($current_page - 1) * $per_page;
1204
-        $limit = array($offset, $per_page);
1205
-        if (isset($this->_req_data['s'])) {
1206
-            $sstr = '%' . $this->_req_data['s'] . '%';
1207
-            $_where['OR'] = array(
1208
-                'TKT_name'        => array('LIKE', $sstr),
1209
-                'TKT_description' => array('LIKE', $sstr),
1210
-            );
1211
-        }
1212
-        $query_params = array(
1213
-            $_where,
1214
-            'order_by' => $orderby,
1215
-            'limit'    => $limit,
1216
-            'group_by' => 'TKT_ID',
1217
-        );
1218
-        if ($count) {
1219
-            return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1220
-        } else {
1221
-            return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1222
-        }
1223
-    }
1224
-
1225
-
1226
-    /**
1227
-     * @param bool $trash
1228
-     * @throws EE_Error
1229
-     */
1230
-    protected function _trash_or_restore_ticket($trash = false)
1231
-    {
1232
-        $success = 1;
1233
-        $TKT = EEM_Ticket::instance();
1234
-        // checkboxes?
1235
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1236
-            // if array has more than one element then success message should be plural
1237
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1238
-            // cycle thru the boxes
1239
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1240
-                if ($trash) {
1241
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1242
-                        $success = 0;
1243
-                    }
1244
-                } else {
1245
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1246
-                        $success = 0;
1247
-                    }
1248
-                }
1249
-            }
1250
-        } else {
1251
-            // grab single id and trash
1252
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1253
-            if ($trash) {
1254
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1255
-                    $success = 0;
1256
-                }
1257
-            } else {
1258
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1259
-                    $success = 0;
1260
-                }
1261
-            }
1262
-        }
1263
-        $action_desc = $trash ? 'moved to the trash' : 'restored';
1264
-        $query_args = array(
1265
-            'action' => 'ticket_list_table',
1266
-            'status' => $trash ? '' : 'trashed',
1267
-        );
1268
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1269
-    }
1270
-
1271
-
1272
-    /**
1273
-     * Handles trashing default ticket.
1274
-     */
1275
-    protected function _delete_ticket()
1276
-    {
1277
-        $success = 1;
1278
-        // checkboxes?
1279
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1280
-            // if array has more than one element then success message should be plural
1281
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1282
-            // cycle thru the boxes
1283
-            while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1284
-                // delete
1285
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1286
-                    $success = 0;
1287
-                }
1288
-            }
1289
-        } else {
1290
-            // grab single id and trash
1291
-            $TKT_ID = absint($this->_req_data['TKT_ID']);
1292
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1293
-                $success = 0;
1294
-            }
1295
-        }
1296
-        $action_desc = 'deleted';
1297
-        $query_args = array(
1298
-            'action' => 'ticket_list_table',
1299
-            'status' => 'trashed',
1300
-        );
1301
-        // fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1302
-        if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1303
-            array(array('TKT_is_default' => 1)),
1304
-            'TKT_ID',
1305
-            true
1306
-        )
1307
-        ) {
1308
-            $query_args = array();
1309
-        }
1310
-        $this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1311
-    }
1312
-
1313
-
1314
-    /**
1315
-     * @param int $TKT_ID
1316
-     * @return bool|int
1317
-     * @throws EE_Error
1318
-     */
1319
-    protected function _delete_the_ticket($TKT_ID)
1320
-    {
1321
-        $tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1322
-        $tkt->_remove_relations('Datetime');
1323
-        // delete all related prices first
1324
-        $tkt->delete_related_permanently('Price');
1325
-        return $tkt->delete_permanently();
1326
-    }
1327
-
1328
-
1329
-    /**
1330
-     * @param array $default_event_settings_form_subsections
1331
-     * @return array
1332
-     * @since $VID:$
1333
-     */
1334
-    public function advancedEditorAdminFormSection(array $default_event_settings_form_subsections)
1335
-    {
1336
-        return [
1337
-            'use_advanced_editor'         => new EE_Select_Input(
1338
-                apply_filters(
1339
-                    'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_answer_options',
1340
-                    [
1341
-                        esc_html__('Legacy Editor', 'event_espresso'),
1342
-                        esc_html__('Advanced Editor', 'event_espresso'),
1343
-                    ]
1344
-                ),
1345
-                apply_filters(
1346
-                    'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_settings',
1347
-                    [
1348
-                        'default'         => $this->admin_config->useAdvancedEditor(),
1349
-                        'html_label_text' => esc_html__('Activate Advanced Editor?', 'event_espresso'),
1350
-                        'html_help_text'  => sprintf(
1351
-                            esc_html__(
1352
-                                'Controls whether the Event Espresso Event Editor continues to use the existing legacy editor that functions like the typical older WordPress admin you are used to,%1$sor uses the new Advanced Editor with a more powerful and easier to use interface. This may be automatically turned on in order to utilize advanced features from new addons.',
1353
-                                'event_espresso'
1354
-                            ),
1355
-                            '<br />'
1356
-                        ),
1357
-                    ]
1358
-                )
1359
-            ),
1360
-            'defaults_section_header' => new EE_Form_Section_HTML(
1361
-                EEH_HTML::h2(
1362
-                    esc_html__('Default Settings', 'event_espresso'),
1363
-                    '',
1364
-                    'ee-admin-settings-hdr'
1365
-                )
1366
-            ),
1367
-        ] + $default_event_settings_form_subsections;
1368
-    }
1369
-
1370
-
1371
-    /**
1372
-     * @param array     $valid_data
1373
-     * @param EE_Config $config
1374
-     * @since $VID:$
1375
-     */
1376
-    public function updateAdvancedEditorAdminFormSettings(array $valid_data, EE_Config $config)
1377
-    {
1378
-        $config->admin->setUseAdvancedEditor(
1379
-            isset($valid_data['use_advanced_editor'])
1380
-                ? $valid_data['use_advanced_editor']
1381
-                : false
1382
-        );
1383
-    }
338
+					}
339
+				}
340
+			);
341
+		}
342
+	}
343
+
344
+
345
+	/**
346
+	 * Returns template for the additional datetime.
347
+	 *
348
+	 * @param $template
349
+	 * @param $template_args
350
+	 * @return mixed
351
+	 * @throws DomainException
352
+	 */
353
+	public function add_additional_datetime_button($template, $template_args)
354
+	{
355
+		return EEH_Template::display_template(
356
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
357
+			$template_args,
358
+			true
359
+		);
360
+	}
361
+
362
+
363
+	/**
364
+	 * Returns the template for cloning a datetime.
365
+	 *
366
+	 * @param $template
367
+	 * @param $template_args
368
+	 * @return mixed
369
+	 * @throws DomainException
370
+	 */
371
+	public function add_datetime_clone_button($template, $template_args)
372
+	{
373
+		return EEH_Template::display_template(
374
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
375
+			$template_args,
376
+			true
377
+		);
378
+	}
379
+
380
+
381
+	/**
382
+	 * Returns the template for datetime timezones.
383
+	 *
384
+	 * @param $template
385
+	 * @param $template_args
386
+	 * @return mixed
387
+	 * @throws DomainException
388
+	 */
389
+	public function datetime_timezones_template($template, $template_args)
390
+	{
391
+		return EEH_Template::display_template(
392
+			EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
393
+			$template_args,
394
+			true
395
+		);
396
+	}
397
+
398
+
399
+	/**
400
+	 * Sets the views for the default list table view.
401
+	 */
402
+	protected function _set_list_table_views_default()
403
+	{
404
+		parent::_set_list_table_views_default();
405
+		$new_views = array(
406
+			'today' => array(
407
+				'slug'        => 'today',
408
+				'label'       => esc_html__('Today', 'event_espresso'),
409
+				'count'       => $this->total_events_today(),
410
+				'bulk_action' => array(
411
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
412
+				),
413
+			),
414
+			'month' => array(
415
+				'slug'        => 'month',
416
+				'label'       => esc_html__('This Month', 'event_espresso'),
417
+				'count'       => $this->total_events_this_month(),
418
+				'bulk_action' => array(
419
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
420
+				),
421
+			),
422
+		);
423
+		$this->_views = array_merge($this->_views, $new_views);
424
+	}
425
+
426
+
427
+	/**
428
+	 * Returns the extra action links for the default list table view.
429
+	 *
430
+	 * @param array     $action_links
431
+	 * @param \EE_Event $event
432
+	 * @return array
433
+	 * @throws EE_Error
434
+	 */
435
+	public function extra_list_table_actions(array $action_links, \EE_Event $event)
436
+	{
437
+		if (EE_Registry::instance()->CAP->current_user_can(
438
+			'ee_read_registrations',
439
+			'espresso_registrations_reports',
440
+			$event->ID()
441
+		)
442
+		) {
443
+			$reports_query_args = array(
444
+				'action' => 'reports',
445
+				'EVT_ID' => $event->ID(),
446
+			);
447
+			$reports_link = EE_Admin_Page::add_query_args_and_nonce($reports_query_args, REG_ADMIN_URL);
448
+			$action_links[] = '<a href="'
449
+							  . $reports_link
450
+							  . '" title="'
451
+							  . esc_attr__('View Report', 'event_espresso')
452
+							  . '"><div class="dashicons dashicons-chart-bar"></div></a>'
453
+							  . "\n\t";
454
+		}
455
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
456
+			EE_Registry::instance()->load_helper('MSG_Template');
457
+			$action_links[] = EEH_MSG_Template::get_message_action_link(
458
+				'see_notifications_for',
459
+				null,
460
+				array('EVT_ID' => $event->ID())
461
+			);
462
+		}
463
+		return $action_links;
464
+	}
465
+
466
+
467
+	/**
468
+	 * @param $items
469
+	 * @return mixed
470
+	 */
471
+	public function additional_legend_items($items)
472
+	{
473
+		if (EE_Registry::instance()->CAP->current_user_can(
474
+			'ee_read_registrations',
475
+			'espresso_registrations_reports'
476
+		)
477
+		) {
478
+			$items['reports'] = array(
479
+				'class' => 'dashicons dashicons-chart-bar',
480
+				'desc'  => esc_html__('Event Reports', 'event_espresso'),
481
+			);
482
+		}
483
+		if (EE_Registry::instance()->CAP->current_user_can('ee_read_global_messages', 'view_filtered_messages')) {
484
+			$related_for_icon = EEH_MSG_Template::get_message_action_icon('see_notifications_for');
485
+			if (isset($related_for_icon['css_class']) && isset($related_for_icon['label'])) {
486
+				$items['view_related_messages'] = array(
487
+					'class' => $related_for_icon['css_class'],
488
+					'desc'  => $related_for_icon['label'],
489
+				);
490
+			}
491
+		}
492
+		return $items;
493
+	}
494
+
495
+
496
+	/**
497
+	 * This is the callback method for the duplicate event route
498
+	 * Method looks for 'EVT_ID' in the request and retrieves that event and its details and duplicates them
499
+	 * into a new event.  We add a hook so that any plugins that add extra event details can hook into this
500
+	 * action.  Note that the dupe will have **DUPLICATE** as its title and slug.
501
+	 * After duplication the redirect is to the new event edit page.
502
+	 *
503
+	 * @return void
504
+	 * @access protected
505
+	 * @throws EE_Error If EE_Event is not available with given ID
506
+	 */
507
+	protected function _duplicate_event()
508
+	{
509
+		// first make sure the ID for the event is in the request.
510
+		//  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
511
+		if (! isset($this->_req_data['EVT_ID'])) {
512
+			EE_Error::add_error(
513
+				esc_html__(
514
+					'In order to duplicate an event an Event ID is required.  None was given.',
515
+					'event_espresso'
516
+				),
517
+				__FILE__,
518
+				__FUNCTION__,
519
+				__LINE__
520
+			);
521
+			$this->_redirect_after_action(false, '', '', array(), true);
522
+			return;
523
+		}
524
+		// k we've got EVT_ID so let's use that to get the event we'll duplicate
525
+		$orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
526
+		if (! $orig_event instanceof EE_Event) {
527
+			throw new EE_Error(
528
+				sprintf(
529
+					esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
530
+					$this->_req_data['EVT_ID']
531
+				)
532
+			);
533
+		}
534
+		// k now let's clone the $orig_event before getting relations
535
+		$new_event = clone $orig_event;
536
+		// original datetimes
537
+		$orig_datetimes = $orig_event->get_many_related('Datetime');
538
+		// other original relations
539
+		$orig_ven = $orig_event->get_many_related('Venue');
540
+		// reset the ID and modify other details to make it clear this is a dupe
541
+		$new_event->set('EVT_ID', 0);
542
+		$new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
543
+		$new_event->set('EVT_name', $new_name);
544
+		$new_event->set(
545
+			'EVT_slug',
546
+			wp_unique_post_slug(
547
+				sanitize_title($orig_event->name()),
548
+				0,
549
+				'publish',
550
+				'espresso_events',
551
+				0
552
+			)
553
+		);
554
+		$new_event->set('status', 'draft');
555
+		// duplicate discussion settings
556
+		$new_event->set('comment_status', $orig_event->get('comment_status'));
557
+		$new_event->set('ping_status', $orig_event->get('ping_status'));
558
+		// save the new event
559
+		$new_event->save();
560
+		// venues
561
+		foreach ($orig_ven as $ven) {
562
+			$new_event->_add_relation_to($ven, 'Venue');
563
+		}
564
+		$new_event->save();
565
+		// now we need to get the question group relations and handle that
566
+		// first primary question groups
567
+		$orig_primary_qgs = $orig_event->get_many_related(
568
+			'Question_Group',
569
+			[['Event_Question_Group.EQG_primary' => true]]
570
+		);
571
+		if (! empty($orig_primary_qgs)) {
572
+			foreach ($orig_primary_qgs as $id => $obj) {
573
+				if ($obj instanceof EE_Question_Group) {
574
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
575
+				}
576
+			}
577
+		}
578
+		// next additional attendee question groups
579
+		$orig_additional_qgs = $orig_event->get_many_related(
580
+			'Question_Group',
581
+			[['Event_Question_Group.EQG_additional' => true]]
582
+		);
583
+		if (! empty($orig_additional_qgs)) {
584
+			foreach ($orig_additional_qgs as $id => $obj) {
585
+				if ($obj instanceof EE_Question_Group) {
586
+					$new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
587
+				}
588
+			}
589
+		}
590
+
591
+		$new_event->save();
592
+
593
+		// k now that we have the new event saved we can loop through the datetimes and start adding relations.
594
+		$cloned_tickets = array();
595
+		foreach ($orig_datetimes as $orig_dtt) {
596
+			if (! $orig_dtt instanceof EE_Datetime) {
597
+				continue;
598
+			}
599
+			$new_dtt = clone $orig_dtt;
600
+			$orig_tkts = $orig_dtt->tickets();
601
+			// save new dtt then add to event
602
+			$new_dtt->set('DTT_ID', 0);
603
+			$new_dtt->set('DTT_sold', 0);
604
+			$new_dtt->set_reserved(0);
605
+			$new_dtt->save();
606
+			$new_event->_add_relation_to($new_dtt, 'Datetime');
607
+			$new_event->save();
608
+			// now let's get the ticket relations setup.
609
+			foreach ((array) $orig_tkts as $orig_tkt) {
610
+				// it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
611
+				if (! $orig_tkt instanceof EE_Ticket) {
612
+					continue;
613
+				}
614
+				// is this ticket archived?  If it is then let's skip
615
+				if ($orig_tkt->get('TKT_deleted')) {
616
+					continue;
617
+				}
618
+				// does this original ticket already exist in the clone_tickets cache?
619
+				//  If so we'll just use the new ticket from it.
620
+				if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
621
+					$new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
622
+				} else {
623
+					$new_tkt = clone $orig_tkt;
624
+					// get relations on the $orig_tkt that we need to setup.
625
+					$orig_prices = $orig_tkt->prices();
626
+					$new_tkt->set('TKT_ID', 0);
627
+					$new_tkt->set('TKT_sold', 0);
628
+					$new_tkt->set('TKT_reserved', 0);
629
+					$new_tkt->save(); // make sure new ticket has ID.
630
+					// price relations on new ticket need to be setup.
631
+					foreach ($orig_prices as $orig_price) {
632
+						$new_price = clone $orig_price;
633
+						$new_price->set('PRC_ID', 0);
634
+						$new_price->save();
635
+						$new_tkt->_add_relation_to($new_price, 'Price');
636
+						$new_tkt->save();
637
+					}
638
+
639
+					do_action(
640
+						'AHEE__Extend_Events_Admin_Page___duplicate_event__duplicate_ticket__after',
641
+						$orig_tkt,
642
+						$new_tkt,
643
+						$orig_prices,
644
+						$orig_event,
645
+						$orig_dtt,
646
+						$new_dtt
647
+					);
648
+				}
649
+				// k now we can add the new ticket as a relation to the new datetime
650
+				// and make sure its added to our cached $cloned_tickets array
651
+				// for use with later datetimes that have the same ticket.
652
+				$new_dtt->_add_relation_to($new_tkt, 'Ticket');
653
+				$new_dtt->save();
654
+				$cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
655
+			}
656
+		}
657
+		// clone taxonomy information
658
+		$taxonomies_to_clone_with = apply_filters(
659
+			'FHEE__Extend_Events_Admin_Page___duplicate_event__taxonomies_to_clone',
660
+			array('espresso_event_categories', 'espresso_event_type', 'post_tag')
661
+		);
662
+		// get terms for original event (notice)
663
+		$orig_terms = wp_get_object_terms($orig_event->ID(), $taxonomies_to_clone_with);
664
+		// loop through terms and add them to new event.
665
+		foreach ($orig_terms as $term) {
666
+			wp_set_object_terms($new_event->ID(), $term->term_id, $term->taxonomy, true);
667
+		}
668
+
669
+		// duplicate other core WP_Post items for this event.
670
+		// post thumbnail (feature image).
671
+		$feature_image_id = get_post_thumbnail_id($orig_event->ID());
672
+		if ($feature_image_id) {
673
+			update_post_meta($new_event->ID(), '_thumbnail_id', $feature_image_id);
674
+		}
675
+
676
+		// duplicate page_template setting
677
+		$page_template = get_post_meta($orig_event->ID(), '_wp_page_template', true);
678
+		if ($page_template) {
679
+			update_post_meta($new_event->ID(), '_wp_page_template', $page_template);
680
+		}
681
+
682
+		do_action('AHEE__Extend_Events_Admin_Page___duplicate_event__after', $new_event, $orig_event);
683
+		// now let's redirect to the edit page for this duplicated event if we have a new event id.
684
+		if ($new_event->ID()) {
685
+			$redirect_args = array(
686
+				'post'   => $new_event->ID(),
687
+				'action' => 'edit',
688
+			);
689
+			EE_Error::add_success(
690
+				esc_html__(
691
+					'Event successfully duplicated.  Please review the details below and make any necessary edits',
692
+					'event_espresso'
693
+				)
694
+			);
695
+		} else {
696
+			$redirect_args = array(
697
+				'action' => 'default',
698
+			);
699
+			EE_Error::add_error(
700
+				esc_html__('Not able to duplicate event.  Something went wrong.', 'event_espresso'),
701
+				__FILE__,
702
+				__FUNCTION__,
703
+				__LINE__
704
+			);
705
+		}
706
+		$this->_redirect_after_action(false, '', '', $redirect_args, true);
707
+	}
708
+
709
+
710
+	/**
711
+	 * Generates output for the import page.
712
+	 *
713
+	 * @throws DomainException
714
+	 */
715
+	protected function _import_page()
716
+	{
717
+		$title = esc_html__('Import', 'event_espresso');
718
+		$intro = esc_html__(
719
+			'If you have a previously exported Event Espresso 4 information in a Comma Separated Value (CSV) file format, you can upload the file here: ',
720
+			'event_espresso'
721
+		);
722
+		$form_url = EVENTS_ADMIN_URL;
723
+		$action = 'import_events';
724
+		$type = 'csv';
725
+		$this->_template_args['form'] = EE_Import::instance()->upload_form(
726
+			$title,
727
+			$intro,
728
+			$form_url,
729
+			$action,
730
+			$type
731
+		);
732
+		$this->_template_args['sample_file_link'] = EE_Admin_Page::add_query_args_and_nonce(
733
+			array('action' => 'sample_export_file'),
734
+			$this->_admin_base_url
735
+		);
736
+		$content = EEH_Template::display_template(
737
+			EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
738
+			$this->_template_args,
739
+			true
740
+		);
741
+		$this->_template_args['admin_page_content'] = $content;
742
+		$this->display_admin_page_with_sidebar();
743
+	}
744
+
745
+
746
+	/**
747
+	 * _import_events
748
+	 * This handles displaying the screen and running imports for importing events.
749
+	 *
750
+	 * @return void
751
+	 */
752
+	protected function _import_events()
753
+	{
754
+		require_once(EE_CLASSES . 'EE_Import.class.php');
755
+		$success = EE_Import::instance()->import();
756
+		$this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
757
+	}
758
+
759
+
760
+	/**
761
+	 * _events_export
762
+	 * Will export all (or just the given event) to a Excel compatible file.
763
+	 *
764
+	 * @access protected
765
+	 * @return void
766
+	 */
767
+	protected function _events_export()
768
+	{
769
+		if (isset($this->_req_data['EVT_ID'])) {
770
+			$event_ids = $this->_req_data['EVT_ID'];
771
+		} elseif (isset($this->_req_data['EVT_IDs'])) {
772
+			$event_ids = $this->_req_data['EVT_IDs'];
773
+		} else {
774
+			$event_ids = null;
775
+		}
776
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
777
+		$new_request_args = array(
778
+			'export' => 'report',
779
+			'action' => 'all_event_data',
780
+			'EVT_ID' => $event_ids,
781
+		);
782
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
783
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
784
+			require_once(EE_CLASSES . 'EE_Export.class.php');
785
+			$EE_Export = EE_Export::instance($this->_req_data);
786
+			$EE_Export->export();
787
+		}
788
+	}
789
+
790
+
791
+	/**
792
+	 * handle category exports()
793
+	 *
794
+	 * @return void
795
+	 */
796
+	protected function _categories_export()
797
+	{
798
+		// todo: I don't like doing this but it'll do until we modify EE_Export Class.
799
+		$new_request_args = array(
800
+			'export'       => 'report',
801
+			'action'       => 'categories',
802
+			'category_ids' => $this->_req_data['EVT_CAT_ID'],
803
+		);
804
+		$this->_req_data = array_merge($this->_req_data, $new_request_args);
805
+		if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
806
+			require_once(EE_CLASSES . 'EE_Export.class.php');
807
+			$EE_Export = EE_Export::instance($this->_req_data);
808
+			$EE_Export->export();
809
+		}
810
+	}
811
+
812
+
813
+	/**
814
+	 * Creates a sample CSV file for importing
815
+	 */
816
+	protected function _sample_export_file()
817
+	{
818
+		// require_once(EE_CLASSES . 'EE_Export.class.php');
819
+		EE_Export::instance()->export_sample();
820
+	}
821
+
822
+
823
+	/*************        Template Settings        *************/
824
+	/**
825
+	 * Generates template settings page output
826
+	 *
827
+	 * @throws DomainException
828
+	 * @throws EE_Error
829
+	 */
830
+	protected function _template_settings()
831
+	{
832
+		$this->_template_args['values'] = $this->_yes_no_values;
833
+		/**
834
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
835
+		 * from General_Settings_Admin_Page to here.
836
+		 */
837
+		$this->_template_args = apply_filters(
838
+			'FHEE__General_Settings_Admin_Page__template_settings__template_args',
839
+			$this->_template_args
840
+		);
841
+		$this->_set_add_edit_form_tags('update_template_settings');
842
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
843
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
844
+			EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
845
+			$this->_template_args,
846
+			true
847
+		);
848
+		$this->display_admin_page_with_sidebar();
849
+	}
850
+
851
+
852
+	/**
853
+	 * Handler for updating template settings.
854
+	 *
855
+	 * @throws InvalidInterfaceException
856
+	 * @throws InvalidDataTypeException
857
+	 * @throws InvalidArgumentException
858
+	 */
859
+	protected function _update_template_settings()
860
+	{
861
+		/**
862
+		 * Note leaving this filter in for backward compatibility this was moved in 4.6.x
863
+		 * from General_Settings_Admin_Page to here.
864
+		 */
865
+		EE_Registry::instance()->CFG->template_settings = apply_filters(
866
+			'FHEE__General_Settings_Admin_Page__update_template_settings__data',
867
+			EE_Registry::instance()->CFG->template_settings,
868
+			$this->_req_data
869
+		);
870
+		// update custom post type slugs and detect if we need to flush rewrite rules
871
+		$old_slug = EE_Registry::instance()->CFG->core->event_cpt_slug;
872
+		EE_Registry::instance()->CFG->core->event_cpt_slug = empty($this->_req_data['event_cpt_slug'])
873
+			? EE_Registry::instance()->CFG->core->event_cpt_slug
874
+			: EEH_URL::slugify($this->_req_data['event_cpt_slug'], 'events');
875
+		$what = 'Template Settings';
876
+		$success = $this->_update_espresso_configuration(
877
+			$what,
878
+			EE_Registry::instance()->CFG->template_settings,
879
+			__FILE__,
880
+			__FUNCTION__,
881
+			__LINE__
882
+		);
883
+		if (EE_Registry::instance()->CFG->core->event_cpt_slug != $old_slug) {
884
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
885
+			$rewrite_rules = LoaderFactory::getLoader()->getShared(
886
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
887
+			);
888
+			$rewrite_rules->flush();
889
+		}
890
+		$this->_redirect_after_action($success, $what, 'updated', array('action' => 'template_settings'));
891
+	}
892
+
893
+
894
+	/**
895
+	 * _premium_event_editor_meta_boxes
896
+	 * add all metaboxes related to the event_editor
897
+	 *
898
+	 * @access protected
899
+	 * @return void
900
+	 * @throws EE_Error
901
+	 */
902
+	protected function _premium_event_editor_meta_boxes()
903
+	{
904
+		$this->verify_cpt_object();
905
+		add_meta_box(
906
+			'espresso_event_editor_event_options',
907
+			esc_html__('Event Registration Options', 'event_espresso'),
908
+			array($this, 'registration_options_meta_box'),
909
+			$this->page_slug,
910
+			'side',
911
+			'core'
912
+		);
913
+	}
914
+
915
+
916
+	/**
917
+	 * override caf metabox
918
+	 *
919
+	 * @return void
920
+	 * @throws DomainException
921
+	 */
922
+	public function registration_options_meta_box()
923
+	{
924
+		$yes_no_values = array(
925
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
926
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
927
+		);
928
+		$default_reg_status_values = EEM_Registration::reg_status_array(
929
+			array(
930
+				EEM_Registration::status_id_cancelled,
931
+				EEM_Registration::status_id_declined,
932
+				EEM_Registration::status_id_incomplete,
933
+				EEM_Registration::status_id_wait_list,
934
+			),
935
+			true
936
+		);
937
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
938
+		$template_args['_event'] = $this->_cpt_model_obj;
939
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
940
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
941
+			'default_reg_status',
942
+			$default_reg_status_values,
943
+			$this->_cpt_model_obj->default_registration_status()
944
+		);
945
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
946
+			'display_desc',
947
+			$yes_no_values,
948
+			$this->_cpt_model_obj->display_description()
949
+		);
950
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
951
+			'display_ticket_selector',
952
+			$yes_no_values,
953
+			$this->_cpt_model_obj->display_ticket_selector(),
954
+			'',
955
+			'',
956
+			false
957
+		);
958
+		$template_args['EVT_default_registration_status'] = EEH_Form_Fields::select_input(
959
+			'EVT_default_registration_status',
960
+			$default_reg_status_values,
961
+			$this->_cpt_model_obj->default_registration_status()
962
+		);
963
+		$template_args['additional_registration_options'] = apply_filters(
964
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
965
+			'',
966
+			$template_args,
967
+			$yes_no_values,
968
+			$default_reg_status_values
969
+		);
970
+		EEH_Template::display_template(
971
+			EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
972
+			$template_args
973
+		);
974
+	}
975
+
976
+
977
+
978
+	/**
979
+	 * wp_list_table_mods for caf
980
+	 * ============================
981
+	 */
982
+	/**
983
+	 * hook into list table filters and provide filters for caffeinated list table
984
+	 *
985
+	 * @param  array $old_filters    any existing filters present
986
+	 * @param  array $list_table_obj the list table object
987
+	 * @return array                  new filters
988
+	 */
989
+	public function list_table_filters($old_filters, $list_table_obj)
990
+	{
991
+		$filters = array();
992
+		// first month/year filters
993
+		$filters[] = $this->espresso_event_months_dropdown();
994
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
995
+		// active status dropdown
996
+		if ($status !== 'draft') {
997
+			$filters[] = $this->active_status_dropdown(
998
+				isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : ''
999
+			);
1000
+			$filters[] = $this->venuesDropdown(
1001
+				isset($this->_req_data['venue']) ? $this->_req_data['venue'] : ''
1002
+			);
1003
+		}
1004
+		// category filter
1005
+		$filters[] = $this->category_dropdown();
1006
+		return array_merge($old_filters, $filters);
1007
+	}
1008
+
1009
+
1010
+	/**
1011
+	 * espresso_event_months_dropdown
1012
+	 *
1013
+	 * @access public
1014
+	 * @return string                dropdown listing month/year selections for events.
1015
+	 */
1016
+	public function espresso_event_months_dropdown()
1017
+	{
1018
+		// what we need to do is get all PRIMARY datetimes for all events to filter on.
1019
+		// Note we need to include any other filters that are set!
1020
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1021
+		// categories?
1022
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1023
+			? $this->_req_data['EVT_CAT']
1024
+			: null;
1025
+		// active status?
1026
+		$active_status = isset($this->_req_data['active_status']) ? $this->_req_data['active_status'] : null;
1027
+		$cur_date = isset($this->_req_data['month_range']) ? $this->_req_data['month_range'] : '';
1028
+		return EEH_Form_Fields::generate_event_months_dropdown($cur_date, $status, $category, $active_status);
1029
+	}
1030
+
1031
+
1032
+	/**
1033
+	 * returns a list of "active" statuses on the event
1034
+	 *
1035
+	 * @param  string $current_value whatever the current active status is
1036
+	 * @return string
1037
+	 */
1038
+	public function active_status_dropdown($current_value = '')
1039
+	{
1040
+		$select_name = 'active_status';
1041
+		$values = array(
1042
+			'none'     => esc_html__('Show Active/Inactive', 'event_espresso'),
1043
+			'active'   => esc_html__('Active', 'event_espresso'),
1044
+			'upcoming' => esc_html__('Upcoming', 'event_espresso'),
1045
+			'expired'  => esc_html__('Expired', 'event_espresso'),
1046
+			'inactive' => esc_html__('Inactive', 'event_espresso'),
1047
+		);
1048
+
1049
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1050
+	}
1051
+
1052
+	/**
1053
+	 * returns a list of "venues"
1054
+	 *
1055
+	 * @param  string $current_value whatever the current active status is
1056
+	 * @return string
1057
+	 */
1058
+	protected function venuesDropdown($current_value = '')
1059
+	{
1060
+		$select_name = 'venue';
1061
+		$values = array(
1062
+			'' => esc_html__('All Venues', 'event_espresso'),
1063
+		);
1064
+		// populate the list of venues.
1065
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1066
+		$venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1067
+
1068
+		foreach ($venues as $venue) {
1069
+			$values[ $venue->ID() ] = $venue->name();
1070
+		}
1071
+
1072
+		return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
1073
+	}
1074
+
1075
+
1076
+	/**
1077
+	 * output a dropdown of the categories for the category filter on the event admin list table
1078
+	 *
1079
+	 * @access  public
1080
+	 * @return string html
1081
+	 */
1082
+	public function category_dropdown()
1083
+	{
1084
+		$cur_cat = isset($this->_req_data['EVT_CAT']) ? $this->_req_data['EVT_CAT'] : -1;
1085
+		return EEH_Form_Fields::generate_event_category_dropdown($cur_cat);
1086
+	}
1087
+
1088
+
1089
+	/**
1090
+	 * get total number of events today
1091
+	 *
1092
+	 * @access public
1093
+	 * @return int
1094
+	 * @throws EE_Error
1095
+	 */
1096
+	public function total_events_today()
1097
+	{
1098
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1099
+			'DTT_EVT_start',
1100
+			date('Y-m-d') . ' 00:00:00',
1101
+			'Y-m-d H:i:s',
1102
+			'UTC'
1103
+		);
1104
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1105
+			'DTT_EVT_start',
1106
+			date('Y-m-d') . ' 23:59:59',
1107
+			'Y-m-d H:i:s',
1108
+			'UTC'
1109
+		);
1110
+		$where = array(
1111
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1112
+		);
1113
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1114
+		return $count;
1115
+	}
1116
+
1117
+
1118
+	/**
1119
+	 * get total number of events this month
1120
+	 *
1121
+	 * @access public
1122
+	 * @return int
1123
+	 * @throws EE_Error
1124
+	 */
1125
+	public function total_events_this_month()
1126
+	{
1127
+		// Dates
1128
+		$this_year_r = date('Y');
1129
+		$this_month_r = date('m');
1130
+		$days_this_month = date('t');
1131
+		$start = EEM_Datetime::instance()->convert_datetime_for_query(
1132
+			'DTT_EVT_start',
1133
+			$this_year_r . '-' . $this_month_r . '-01 00:00:00',
1134
+			'Y-m-d H:i:s',
1135
+			'UTC'
1136
+		);
1137
+		$end = EEM_Datetime::instance()->convert_datetime_for_query(
1138
+			'DTT_EVT_start',
1139
+			$this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1140
+			'Y-m-d H:i:s',
1141
+			'UTC'
1142
+		);
1143
+		$where = array(
1144
+			'Datetime.DTT_EVT_start' => array('BETWEEN', array($start, $end)),
1145
+		);
1146
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
1147
+		return $count;
1148
+	}
1149
+
1150
+
1151
+	/** DEFAULT TICKETS STUFF **/
1152
+
1153
+	/**
1154
+	 * Output default tickets list table view.
1155
+	 */
1156
+	public function _tickets_overview_list_table()
1157
+	{
1158
+		$this->_search_btn_label = esc_html__('Tickets', 'event_espresso');
1159
+		$this->display_admin_list_table_page_with_no_sidebar();
1160
+	}
1161
+
1162
+
1163
+	/**
1164
+	 * @param int  $per_page
1165
+	 * @param bool $count
1166
+	 * @param bool $trashed
1167
+	 * @return \EE_Soft_Delete_Base_Class[]|int
1168
+	 */
1169
+	public function get_default_tickets($per_page = 10, $count = false, $trashed = false)
1170
+	{
1171
+		$orderby = empty($this->_req_data['orderby']) ? 'TKT_name' : $this->_req_data['orderby'];
1172
+		$order = empty($this->_req_data['order']) ? 'ASC' : $this->_req_data['order'];
1173
+		switch ($orderby) {
1174
+			case 'TKT_name':
1175
+				$orderby = array('TKT_name' => $order);
1176
+				break;
1177
+			case 'TKT_price':
1178
+				$orderby = array('TKT_price' => $order);
1179
+				break;
1180
+			case 'TKT_uses':
1181
+				$orderby = array('TKT_uses' => $order);
1182
+				break;
1183
+			case 'TKT_min':
1184
+				$orderby = array('TKT_min' => $order);
1185
+				break;
1186
+			case 'TKT_max':
1187
+				$orderby = array('TKT_max' => $order);
1188
+				break;
1189
+			case 'TKT_qty':
1190
+				$orderby = array('TKT_qty' => $order);
1191
+				break;
1192
+		}
1193
+		$current_page = isset($this->_req_data['paged']) && ! empty($this->_req_data['paged'])
1194
+			? $this->_req_data['paged']
1195
+			: 1;
1196
+		$per_page = isset($this->_req_data['perpage']) && ! empty($this->_req_data['perpage'])
1197
+			? $this->_req_data['perpage']
1198
+			: $per_page;
1199
+		$_where = array(
1200
+			'TKT_is_default' => 1,
1201
+			'TKT_deleted'    => $trashed,
1202
+		);
1203
+		$offset = ($current_page - 1) * $per_page;
1204
+		$limit = array($offset, $per_page);
1205
+		if (isset($this->_req_data['s'])) {
1206
+			$sstr = '%' . $this->_req_data['s'] . '%';
1207
+			$_where['OR'] = array(
1208
+				'TKT_name'        => array('LIKE', $sstr),
1209
+				'TKT_description' => array('LIKE', $sstr),
1210
+			);
1211
+		}
1212
+		$query_params = array(
1213
+			$_where,
1214
+			'order_by' => $orderby,
1215
+			'limit'    => $limit,
1216
+			'group_by' => 'TKT_ID',
1217
+		);
1218
+		if ($count) {
1219
+			return EEM_Ticket::instance()->count_deleted_and_undeleted(array($_where));
1220
+		} else {
1221
+			return EEM_Ticket::instance()->get_all_deleted_and_undeleted($query_params);
1222
+		}
1223
+	}
1224
+
1225
+
1226
+	/**
1227
+	 * @param bool $trash
1228
+	 * @throws EE_Error
1229
+	 */
1230
+	protected function _trash_or_restore_ticket($trash = false)
1231
+	{
1232
+		$success = 1;
1233
+		$TKT = EEM_Ticket::instance();
1234
+		// checkboxes?
1235
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1236
+			// if array has more than one element then success message should be plural
1237
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1238
+			// cycle thru the boxes
1239
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1240
+				if ($trash) {
1241
+					if (! $TKT->delete_by_ID($TKT_ID)) {
1242
+						$success = 0;
1243
+					}
1244
+				} else {
1245
+					if (! $TKT->restore_by_ID($TKT_ID)) {
1246
+						$success = 0;
1247
+					}
1248
+				}
1249
+			}
1250
+		} else {
1251
+			// grab single id and trash
1252
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1253
+			if ($trash) {
1254
+				if (! $TKT->delete_by_ID($TKT_ID)) {
1255
+					$success = 0;
1256
+				}
1257
+			} else {
1258
+				if (! $TKT->restore_by_ID($TKT_ID)) {
1259
+					$success = 0;
1260
+				}
1261
+			}
1262
+		}
1263
+		$action_desc = $trash ? 'moved to the trash' : 'restored';
1264
+		$query_args = array(
1265
+			'action' => 'ticket_list_table',
1266
+			'status' => $trash ? '' : 'trashed',
1267
+		);
1268
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1269
+	}
1270
+
1271
+
1272
+	/**
1273
+	 * Handles trashing default ticket.
1274
+	 */
1275
+	protected function _delete_ticket()
1276
+	{
1277
+		$success = 1;
1278
+		// checkboxes?
1279
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1280
+			// if array has more than one element then success message should be plural
1281
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1282
+			// cycle thru the boxes
1283
+			while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1284
+				// delete
1285
+				if (! $this->_delete_the_ticket($TKT_ID)) {
1286
+					$success = 0;
1287
+				}
1288
+			}
1289
+		} else {
1290
+			// grab single id and trash
1291
+			$TKT_ID = absint($this->_req_data['TKT_ID']);
1292
+			if (! $this->_delete_the_ticket($TKT_ID)) {
1293
+				$success = 0;
1294
+			}
1295
+		}
1296
+		$action_desc = 'deleted';
1297
+		$query_args = array(
1298
+			'action' => 'ticket_list_table',
1299
+			'status' => 'trashed',
1300
+		);
1301
+		// fail safe.  If the default ticket count === 1 then we need to redirect to event overview.
1302
+		if (EEM_Ticket::instance()->count_deleted_and_undeleted(
1303
+			array(array('TKT_is_default' => 1)),
1304
+			'TKT_ID',
1305
+			true
1306
+		)
1307
+		) {
1308
+			$query_args = array();
1309
+		}
1310
+		$this->_redirect_after_action($success, 'Tickets', $action_desc, $query_args);
1311
+	}
1312
+
1313
+
1314
+	/**
1315
+	 * @param int $TKT_ID
1316
+	 * @return bool|int
1317
+	 * @throws EE_Error
1318
+	 */
1319
+	protected function _delete_the_ticket($TKT_ID)
1320
+	{
1321
+		$tkt = EEM_Ticket::instance()->get_one_by_ID($TKT_ID);
1322
+		$tkt->_remove_relations('Datetime');
1323
+		// delete all related prices first
1324
+		$tkt->delete_related_permanently('Price');
1325
+		return $tkt->delete_permanently();
1326
+	}
1327
+
1328
+
1329
+	/**
1330
+	 * @param array $default_event_settings_form_subsections
1331
+	 * @return array
1332
+	 * @since $VID:$
1333
+	 */
1334
+	public function advancedEditorAdminFormSection(array $default_event_settings_form_subsections)
1335
+	{
1336
+		return [
1337
+			'use_advanced_editor'         => new EE_Select_Input(
1338
+				apply_filters(
1339
+					'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_answer_options',
1340
+					[
1341
+						esc_html__('Legacy Editor', 'event_espresso'),
1342
+						esc_html__('Advanced Editor', 'event_espresso'),
1343
+					]
1344
+				),
1345
+				apply_filters(
1346
+					'FHEE__Events_Admin_Page___default_event_settings_form__advanced_editor_input_settings',
1347
+					[
1348
+						'default'         => $this->admin_config->useAdvancedEditor(),
1349
+						'html_label_text' => esc_html__('Activate Advanced Editor?', 'event_espresso'),
1350
+						'html_help_text'  => sprintf(
1351
+							esc_html__(
1352
+								'Controls whether the Event Espresso Event Editor continues to use the existing legacy editor that functions like the typical older WordPress admin you are used to,%1$sor uses the new Advanced Editor with a more powerful and easier to use interface. This may be automatically turned on in order to utilize advanced features from new addons.',
1353
+								'event_espresso'
1354
+							),
1355
+							'<br />'
1356
+						),
1357
+					]
1358
+				)
1359
+			),
1360
+			'defaults_section_header' => new EE_Form_Section_HTML(
1361
+				EEH_HTML::h2(
1362
+					esc_html__('Default Settings', 'event_espresso'),
1363
+					'',
1364
+					'ee-admin-settings-hdr'
1365
+				)
1366
+			),
1367
+		] + $default_event_settings_form_subsections;
1368
+	}
1369
+
1370
+
1371
+	/**
1372
+	 * @param array     $valid_data
1373
+	 * @param EE_Config $config
1374
+	 * @since $VID:$
1375
+	 */
1376
+	public function updateAdvancedEditorAdminFormSettings(array $valid_data, EE_Config $config)
1377
+	{
1378
+		$config->admin->setUseAdvancedEditor(
1379
+			isset($valid_data['use_advanced_editor'])
1380
+				? $valid_data['use_advanced_editor']
1381
+				: false
1382
+		);
1383
+	}
1384 1384
 }
Please login to merge, or discard this patch.
Spacing   +44 added lines, -44 removed lines patch added patch discarded remove patch
@@ -29,10 +29,10 @@  discard block
 block discarded – undo
29 29
     public function __construct($routing = true)
30 30
     {
31 31
         parent::__construct($routing);
32
-        if (! defined('EVENTS_CAF_TEMPLATE_PATH')) {
33
-            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND . 'events/templates/');
34
-            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND . 'events/assets/');
35
-            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'events/assets/');
32
+        if ( ! defined('EVENTS_CAF_TEMPLATE_PATH')) {
33
+            define('EVENTS_CAF_TEMPLATE_PATH', EE_CORE_CAF_ADMIN_EXTEND.'events/templates/');
34
+            define('EVENTS_CAF_ASSETS', EE_CORE_CAF_ADMIN_EXTEND.'events/assets/');
35
+            define('EVENTS_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL.'events/assets/');
36 36
         }
37 37
     }
38 38
 
@@ -42,7 +42,7 @@  discard block
 block discarded – undo
42 42
      */
43 43
     protected function _extend_page_config()
44 44
     {
45
-        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND . 'events';
45
+        $this->_admin_base_path = EE_CORE_CAF_ADMIN_EXTEND.'events';
46 46
         // is there a evt_id in the request?
47 47
         $evt_id = ! empty($this->_req_data['EVT_ID']) && ! is_array($this->_req_data['EVT_ID'])
48 48
             ? $this->_req_data['EVT_ID']
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
     {
264 264
         $return = parent::extra_permalink_field_buttons($return, $id, $new_title, $new_slug);
265 265
         // make sure this is only when editing
266
-        if (! empty($id)) {
266
+        if ( ! empty($id)) {
267 267
             $href = EE_Admin_Page::add_query_args_and_nonce(
268 268
                 array('action' => 'duplicate_event', 'EVT_ID' => $id),
269 269
                 $this->_admin_base_url
@@ -315,7 +315,7 @@  discard block
 block discarded – undo
315 315
     {
316 316
         wp_register_script(
317 317
             'ee-event-editor-heartbeat',
318
-            EVENTS_CAF_ASSETS_URL . 'event-editor-heartbeat.js',
318
+            EVENTS_CAF_ASSETS_URL.'event-editor-heartbeat.js',
319 319
             array('ee_admin_js', 'heartbeat'),
320 320
             EVENT_ESPRESSO_VERSION,
321 321
             true
@@ -328,12 +328,12 @@  discard block
 block discarded – undo
328 328
         if ($this->admin_config->useAdvancedEditor()) {
329 329
             add_action(
330 330
                 'admin_footer',
331
-                function () {
331
+                function() {
332 332
                     $eventId = isset($_REQUEST['post']) ? absint($_REQUEST['post']) : 0;
333 333
                     if ($eventId) {
334 334
                         echo '
335 335
         <script type="text/javascript">
336
-            /* <![CDATA[ */ var eeEditorEventId = ' . $eventId . '; /* ]]> */
336
+            /* <![CDATA[ */ var eeEditorEventId = ' . $eventId.'; /* ]]> */
337 337
         </script>';
338 338
                     }
339 339
                 }
@@ -353,7 +353,7 @@  discard block
 block discarded – undo
353 353
     public function add_additional_datetime_button($template, $template_args)
354 354
     {
355 355
         return EEH_Template::display_template(
356
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_add_additional_time.template.php',
356
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_add_additional_time.template.php',
357 357
             $template_args,
358 358
             true
359 359
         );
@@ -371,7 +371,7 @@  discard block
 block discarded – undo
371 371
     public function add_datetime_clone_button($template, $template_args)
372 372
     {
373 373
         return EEH_Template::display_template(
374
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_metabox_clone_button.template.php',
374
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_metabox_clone_button.template.php',
375 375
             $template_args,
376 376
             true
377 377
         );
@@ -389,7 +389,7 @@  discard block
 block discarded – undo
389 389
     public function datetime_timezones_template($template, $template_args)
390 390
     {
391 391
         return EEH_Template::display_template(
392
-            EVENTS_CAF_TEMPLATE_PATH . 'event_datetime_timezones.template.php',
392
+            EVENTS_CAF_TEMPLATE_PATH.'event_datetime_timezones.template.php',
393 393
             $template_args,
394 394
             true
395 395
         );
@@ -508,7 +508,7 @@  discard block
 block discarded – undo
508 508
     {
509 509
         // first make sure the ID for the event is in the request.
510 510
         //  If it isn't then we need to bail and redirect back to overview list table (cause how did we get here?)
511
-        if (! isset($this->_req_data['EVT_ID'])) {
511
+        if ( ! isset($this->_req_data['EVT_ID'])) {
512 512
             EE_Error::add_error(
513 513
                 esc_html__(
514 514
                     'In order to duplicate an event an Event ID is required.  None was given.',
@@ -523,7 +523,7 @@  discard block
 block discarded – undo
523 523
         }
524 524
         // k we've got EVT_ID so let's use that to get the event we'll duplicate
525 525
         $orig_event = EEM_Event::instance()->get_one_by_ID($this->_req_data['EVT_ID']);
526
-        if (! $orig_event instanceof EE_Event) {
526
+        if ( ! $orig_event instanceof EE_Event) {
527 527
             throw new EE_Error(
528 528
                 sprintf(
529 529
                     esc_html__('An EE_Event object could not be retrieved for the given ID (%s)', 'event_espresso'),
@@ -539,7 +539,7 @@  discard block
 block discarded – undo
539 539
         $orig_ven = $orig_event->get_many_related('Venue');
540 540
         // reset the ID and modify other details to make it clear this is a dupe
541 541
         $new_event->set('EVT_ID', 0);
542
-        $new_name = $new_event->name() . ' ' . esc_html__('**DUPLICATE**', 'event_espresso');
542
+        $new_name = $new_event->name().' '.esc_html__('**DUPLICATE**', 'event_espresso');
543 543
         $new_event->set('EVT_name', $new_name);
544 544
         $new_event->set(
545 545
             'EVT_slug',
@@ -568,7 +568,7 @@  discard block
 block discarded – undo
568 568
             'Question_Group',
569 569
             [['Event_Question_Group.EQG_primary' => true]]
570 570
         );
571
-        if (! empty($orig_primary_qgs)) {
571
+        if ( ! empty($orig_primary_qgs)) {
572 572
             foreach ($orig_primary_qgs as $id => $obj) {
573 573
                 if ($obj instanceof EE_Question_Group) {
574 574
                     $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_primary' => true]);
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
             'Question_Group',
581 581
             [['Event_Question_Group.EQG_additional' => true]]
582 582
         );
583
-        if (! empty($orig_additional_qgs)) {
583
+        if ( ! empty($orig_additional_qgs)) {
584 584
             foreach ($orig_additional_qgs as $id => $obj) {
585 585
                 if ($obj instanceof EE_Question_Group) {
586 586
                     $new_event->_add_relation_to($obj, 'Question_Group', ['EQG_additional' => true]);
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
         // k now that we have the new event saved we can loop through the datetimes and start adding relations.
594 594
         $cloned_tickets = array();
595 595
         foreach ($orig_datetimes as $orig_dtt) {
596
-            if (! $orig_dtt instanceof EE_Datetime) {
596
+            if ( ! $orig_dtt instanceof EE_Datetime) {
597 597
                 continue;
598 598
             }
599 599
             $new_dtt = clone $orig_dtt;
@@ -608,7 +608,7 @@  discard block
 block discarded – undo
608 608
             // now let's get the ticket relations setup.
609 609
             foreach ((array) $orig_tkts as $orig_tkt) {
610 610
                 // it's possible a datetime will have no tickets so let's verify we HAVE a ticket first.
611
-                if (! $orig_tkt instanceof EE_Ticket) {
611
+                if ( ! $orig_tkt instanceof EE_Ticket) {
612 612
                     continue;
613 613
                 }
614 614
                 // is this ticket archived?  If it is then let's skip
@@ -617,8 +617,8 @@  discard block
 block discarded – undo
617 617
                 }
618 618
                 // does this original ticket already exist in the clone_tickets cache?
619 619
                 //  If so we'll just use the new ticket from it.
620
-                if (isset($cloned_tickets[ $orig_tkt->ID() ])) {
621
-                    $new_tkt = $cloned_tickets[ $orig_tkt->ID() ];
620
+                if (isset($cloned_tickets[$orig_tkt->ID()])) {
621
+                    $new_tkt = $cloned_tickets[$orig_tkt->ID()];
622 622
                 } else {
623 623
                     $new_tkt = clone $orig_tkt;
624 624
                     // get relations on the $orig_tkt that we need to setup.
@@ -651,7 +651,7 @@  discard block
 block discarded – undo
651 651
                 // for use with later datetimes that have the same ticket.
652 652
                 $new_dtt->_add_relation_to($new_tkt, 'Ticket');
653 653
                 $new_dtt->save();
654
-                $cloned_tickets[ $orig_tkt->ID() ] = $new_tkt;
654
+                $cloned_tickets[$orig_tkt->ID()] = $new_tkt;
655 655
             }
656 656
         }
657 657
         // clone taxonomy information
@@ -734,7 +734,7 @@  discard block
 block discarded – undo
734 734
             $this->_admin_base_url
735 735
         );
736 736
         $content = EEH_Template::display_template(
737
-            EVENTS_CAF_TEMPLATE_PATH . 'import_page.template.php',
737
+            EVENTS_CAF_TEMPLATE_PATH.'import_page.template.php',
738 738
             $this->_template_args,
739 739
             true
740 740
         );
@@ -751,7 +751,7 @@  discard block
 block discarded – undo
751 751
      */
752 752
     protected function _import_events()
753 753
     {
754
-        require_once(EE_CLASSES . 'EE_Import.class.php');
754
+        require_once(EE_CLASSES.'EE_Import.class.php');
755 755
         $success = EE_Import::instance()->import();
756 756
         $this->_redirect_after_action($success, 'Import File', 'ran', array('action' => 'import_page'), true);
757 757
     }
@@ -780,8 +780,8 @@  discard block
 block discarded – undo
780 780
             'EVT_ID' => $event_ids,
781 781
         );
782 782
         $this->_req_data = array_merge($this->_req_data, $new_request_args);
783
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
784
-            require_once(EE_CLASSES . 'EE_Export.class.php');
783
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
784
+            require_once(EE_CLASSES.'EE_Export.class.php');
785 785
             $EE_Export = EE_Export::instance($this->_req_data);
786 786
             $EE_Export->export();
787 787
         }
@@ -802,8 +802,8 @@  discard block
 block discarded – undo
802 802
             'category_ids' => $this->_req_data['EVT_CAT_ID'],
803 803
         );
804 804
         $this->_req_data = array_merge($this->_req_data, $new_request_args);
805
-        if (is_readable(EE_CLASSES . 'EE_Export.class.php')) {
806
-            require_once(EE_CLASSES . 'EE_Export.class.php');
805
+        if (is_readable(EE_CLASSES.'EE_Export.class.php')) {
806
+            require_once(EE_CLASSES.'EE_Export.class.php');
807 807
             $EE_Export = EE_Export::instance($this->_req_data);
808 808
             $EE_Export->export();
809 809
         }
@@ -841,7 +841,7 @@  discard block
 block discarded – undo
841 841
         $this->_set_add_edit_form_tags('update_template_settings');
842 842
         $this->_set_publish_post_box_vars(null, false, false, null, false);
843 843
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
844
-            EVENTS_CAF_TEMPLATE_PATH . 'template_settings.template.php',
844
+            EVENTS_CAF_TEMPLATE_PATH.'template_settings.template.php',
845 845
             $this->_template_args,
846 846
             true
847 847
         );
@@ -968,7 +968,7 @@  discard block
 block discarded – undo
968 968
             $default_reg_status_values
969 969
         );
970 970
         EEH_Template::display_template(
971
-            EVENTS_CAF_TEMPLATE_PATH . 'event_registration_options.template.php',
971
+            EVENTS_CAF_TEMPLATE_PATH.'event_registration_options.template.php',
972 972
             $template_args
973 973
         );
974 974
     }
@@ -1066,7 +1066,7 @@  discard block
 block discarded – undo
1066 1066
         $venues = $venue_model->get_all(array('order_by' => array('VNU_name' => 'ASC')));
1067 1067
 
1068 1068
         foreach ($venues as $venue) {
1069
-            $values[ $venue->ID() ] = $venue->name();
1069
+            $values[$venue->ID()] = $venue->name();
1070 1070
         }
1071 1071
 
1072 1072
         return EEH_Form_Fields::select_input($select_name, $values, $current_value, '', 'wide');
@@ -1097,13 +1097,13 @@  discard block
 block discarded – undo
1097 1097
     {
1098 1098
         $start = EEM_Datetime::instance()->convert_datetime_for_query(
1099 1099
             'DTT_EVT_start',
1100
-            date('Y-m-d') . ' 00:00:00',
1100
+            date('Y-m-d').' 00:00:00',
1101 1101
             'Y-m-d H:i:s',
1102 1102
             'UTC'
1103 1103
         );
1104 1104
         $end = EEM_Datetime::instance()->convert_datetime_for_query(
1105 1105
             'DTT_EVT_start',
1106
-            date('Y-m-d') . ' 23:59:59',
1106
+            date('Y-m-d').' 23:59:59',
1107 1107
             'Y-m-d H:i:s',
1108 1108
             'UTC'
1109 1109
         );
@@ -1130,13 +1130,13 @@  discard block
 block discarded – undo
1130 1130
         $days_this_month = date('t');
1131 1131
         $start = EEM_Datetime::instance()->convert_datetime_for_query(
1132 1132
             'DTT_EVT_start',
1133
-            $this_year_r . '-' . $this_month_r . '-01 00:00:00',
1133
+            $this_year_r.'-'.$this_month_r.'-01 00:00:00',
1134 1134
             'Y-m-d H:i:s',
1135 1135
             'UTC'
1136 1136
         );
1137 1137
         $end = EEM_Datetime::instance()->convert_datetime_for_query(
1138 1138
             'DTT_EVT_start',
1139
-            $this_year_r . '-' . $this_month_r . '-' . $days_this_month . ' 23:59:59',
1139
+            $this_year_r.'-'.$this_month_r.'-'.$days_this_month.' 23:59:59',
1140 1140
             'Y-m-d H:i:s',
1141 1141
             'UTC'
1142 1142
         );
@@ -1203,7 +1203,7 @@  discard block
 block discarded – undo
1203 1203
         $offset = ($current_page - 1) * $per_page;
1204 1204
         $limit = array($offset, $per_page);
1205 1205
         if (isset($this->_req_data['s'])) {
1206
-            $sstr = '%' . $this->_req_data['s'] . '%';
1206
+            $sstr = '%'.$this->_req_data['s'].'%';
1207 1207
             $_where['OR'] = array(
1208 1208
                 'TKT_name'        => array('LIKE', $sstr),
1209 1209
                 'TKT_description' => array('LIKE', $sstr),
@@ -1232,17 +1232,17 @@  discard block
 block discarded – undo
1232 1232
         $success = 1;
1233 1233
         $TKT = EEM_Ticket::instance();
1234 1234
         // checkboxes?
1235
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1235
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1236 1236
             // if array has more than one element then success message should be plural
1237 1237
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1238 1238
             // cycle thru the boxes
1239 1239
             while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1240 1240
                 if ($trash) {
1241
-                    if (! $TKT->delete_by_ID($TKT_ID)) {
1241
+                    if ( ! $TKT->delete_by_ID($TKT_ID)) {
1242 1242
                         $success = 0;
1243 1243
                     }
1244 1244
                 } else {
1245
-                    if (! $TKT->restore_by_ID($TKT_ID)) {
1245
+                    if ( ! $TKT->restore_by_ID($TKT_ID)) {
1246 1246
                         $success = 0;
1247 1247
                     }
1248 1248
                 }
@@ -1251,11 +1251,11 @@  discard block
 block discarded – undo
1251 1251
             // grab single id and trash
1252 1252
             $TKT_ID = absint($this->_req_data['TKT_ID']);
1253 1253
             if ($trash) {
1254
-                if (! $TKT->delete_by_ID($TKT_ID)) {
1254
+                if ( ! $TKT->delete_by_ID($TKT_ID)) {
1255 1255
                     $success = 0;
1256 1256
                 }
1257 1257
             } else {
1258
-                if (! $TKT->restore_by_ID($TKT_ID)) {
1258
+                if ( ! $TKT->restore_by_ID($TKT_ID)) {
1259 1259
                     $success = 0;
1260 1260
                 }
1261 1261
             }
@@ -1276,20 +1276,20 @@  discard block
 block discarded – undo
1276 1276
     {
1277 1277
         $success = 1;
1278 1278
         // checkboxes?
1279
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1279
+        if ( ! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
1280 1280
             // if array has more than one element then success message should be plural
1281 1281
             $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
1282 1282
             // cycle thru the boxes
1283 1283
             while (list($TKT_ID, $value) = each($this->_req_data['checkbox'])) {
1284 1284
                 // delete
1285
-                if (! $this->_delete_the_ticket($TKT_ID)) {
1285
+                if ( ! $this->_delete_the_ticket($TKT_ID)) {
1286 1286
                     $success = 0;
1287 1287
                 }
1288 1288
             }
1289 1289
         } else {
1290 1290
             // grab single id and trash
1291 1291
             $TKT_ID = absint($this->_req_data['TKT_ID']);
1292
-            if (! $this->_delete_the_ticket($TKT_ID)) {
1292
+            if ( ! $this->_delete_the_ticket($TKT_ID)) {
1293 1293
                 $success = 0;
1294 1294
             }
1295 1295
         }
Please login to merge, or discard this patch.