Completed
Branch EDTR/master (903b91)
by
unknown
26:04 queued 17:28
created
core/db_classes/EE_Taxes.class.php 2 patches
Indentation   +131 added lines, -131 removed lines patch added patch discarded remove patch
@@ -12,146 +12,146 @@
 block discarded – undo
12 12
 class EE_Taxes extends EE_Base
13 13
 {
14 14
 
15
-    /**
16
-     * This is used for when EE_Taxes is used statically by the admin
17
-     *
18
-     * @var array
19
-     */
20
-    private static $_subtotal = [];
15
+	/**
16
+	 * This is used for when EE_Taxes is used statically by the admin
17
+	 *
18
+	 * @var array
19
+	 */
20
+	private static $_subtotal = [];
21 21
 
22
-    /**
23
-     * This holds an array of EE_Price objects that are of PRT_ID == 4 (tax price types)
24
-     *
25
-     * @var EE_Price[]
26
-     */
27
-    private static $_default_taxes = [];
22
+	/**
23
+	 * This holds an array of EE_Price objects that are of PRT_ID == 4 (tax price types)
24
+	 *
25
+	 * @var EE_Price[]
26
+	 */
27
+	private static $_default_taxes = [];
28 28
 
29 29
 
30
-    /**
31
-     * This method simply calculates the total taxes for a given ticket (by pulling the prices attached to the ticket
32
-     * and applying default taxes to it). Note: this is just an intermediary helper method added to facilitate quick
33
-     * calc of taxes for tickets listed in the event editor.
34
-     *
35
-     * @param EE_Ticket $ticket incoming EE_Ticket
36
-     * @return float             total taxes to apply to ticket.
37
-     * @throws EE_Error
38
-     * @throws ReflectionException
39
-     */
40
-    public static function get_total_taxes_for_admin(EE_Ticket $ticket)
41
-    {
42
-        $tax = 0;
43
-        $total_tax = 0;
44
-        // This first checks to see if the given ticket is taxable.
45
-        if (! $ticket->taxable()) {
46
-            return $tax;
47
-        }
48
-        // get subtotal (notice we're only retrieving a subtotal if there isn't one given)
49
-        $subtotal = EE_Taxes::get_subtotal_for_admin($ticket);
50
-        // get taxes
51
-        $taxes = EE_Taxes::get_taxes_for_admin();
52
-        // apply taxes to subtotal
53
-        foreach ($taxes as $tax) {
54
-            // assuming taxes are not cumulative
55
-            $total_tax += $subtotal * $tax->amount() / 100;
56
-        }
57
-        return $total_tax;
58
-    }
30
+	/**
31
+	 * This method simply calculates the total taxes for a given ticket (by pulling the prices attached to the ticket
32
+	 * and applying default taxes to it). Note: this is just an intermediary helper method added to facilitate quick
33
+	 * calc of taxes for tickets listed in the event editor.
34
+	 *
35
+	 * @param EE_Ticket $ticket incoming EE_Ticket
36
+	 * @return float             total taxes to apply to ticket.
37
+	 * @throws EE_Error
38
+	 * @throws ReflectionException
39
+	 */
40
+	public static function get_total_taxes_for_admin(EE_Ticket $ticket)
41
+	{
42
+		$tax = 0;
43
+		$total_tax = 0;
44
+		// This first checks to see if the given ticket is taxable.
45
+		if (! $ticket->taxable()) {
46
+			return $tax;
47
+		}
48
+		// get subtotal (notice we're only retrieving a subtotal if there isn't one given)
49
+		$subtotal = EE_Taxes::get_subtotal_for_admin($ticket);
50
+		// get taxes
51
+		$taxes = EE_Taxes::get_taxes_for_admin();
52
+		// apply taxes to subtotal
53
+		foreach ($taxes as $tax) {
54
+			// assuming taxes are not cumulative
55
+			$total_tax += $subtotal * $tax->amount() / 100;
56
+		}
57
+		return $total_tax;
58
+	}
59 59
 
60 60
 
61
-    /**
62
-     * Gets the total percentage of tax that should be applied to taxable line items
63
-     *
64
-     * @return float the percentage of tax that should be added to taxable items
65
-     * @throws EE_Error
66
-     * @throws ReflectionException
67
-     * eg 20 for %20 tax (NOT 0.20, which
68
-     */
69
-    public static function get_total_taxes_percentage()
70
-    {
71
-        $total_tax_percent = 0;
72
-        foreach (EE_Taxes::get_taxes_for_admin() as $tax_price) {
73
-            $total_tax_percent += $tax_price->get('PRC_amount');
74
-        }
75
-        return $total_tax_percent;
76
-    }
61
+	/**
62
+	 * Gets the total percentage of tax that should be applied to taxable line items
63
+	 *
64
+	 * @return float the percentage of tax that should be added to taxable items
65
+	 * @throws EE_Error
66
+	 * @throws ReflectionException
67
+	 * eg 20 for %20 tax (NOT 0.20, which
68
+	 */
69
+	public static function get_total_taxes_percentage()
70
+	{
71
+		$total_tax_percent = 0;
72
+		foreach (EE_Taxes::get_taxes_for_admin() as $tax_price) {
73
+			$total_tax_percent += $tax_price->get('PRC_amount');
74
+		}
75
+		return $total_tax_percent;
76
+	}
77 77
 
78 78
 
79
-    /**
80
-     * @param EE_Ticket $ticket
81
-     * @return float
82
-     * @throws EE_Error
83
-     * @throws ReflectionException
84
-     */
85
-    public static function get_subtotal_for_admin(EE_Ticket $ticket)
86
-    {
87
-        $TKT_ID = $ticket->ID();
88
-        return isset(EE_Taxes::$_subtotal[ $TKT_ID ])
89
-            ? EE_Taxes::$_subtotal[ $TKT_ID ]
90
-            : EE_Taxes::_get_subtotal_for_admin($ticket);
91
-    }
79
+	/**
80
+	 * @param EE_Ticket $ticket
81
+	 * @return float
82
+	 * @throws EE_Error
83
+	 * @throws ReflectionException
84
+	 */
85
+	public static function get_subtotal_for_admin(EE_Ticket $ticket)
86
+	{
87
+		$TKT_ID = $ticket->ID();
88
+		return isset(EE_Taxes::$_subtotal[ $TKT_ID ])
89
+			? EE_Taxes::$_subtotal[ $TKT_ID ]
90
+			: EE_Taxes::_get_subtotal_for_admin($ticket);
91
+	}
92 92
 
93 93
 
94
-    /**
95
-     * simply take an incoming ticket and calculate the subtotal for the ticket
96
-     *
97
-     * @param EE_Ticket $ticket
98
-     * @return float     subtotal calculated from all EE_Price[] on Ticket.
99
-     * @throws EE_Error
100
-     * @throws ReflectionException
101
-     */
102
-    private static function _get_subtotal_for_admin(EE_Ticket $ticket)
103
-    {
104
-        $subtotal = 0;
105
-        // get all prices
106
-        $prices = $ticket->get_many_related(
107
-            'Price',
108
-            [
109
-                'default_where_conditions' => 'none',
110
-                'order_by'                 => ['PRC_order' => 'ASC'],
111
-            ]
112
-        );
113
-        // let's loop through them (base price is always the first item)
114
-        foreach ($prices as $price) {
115
-            if ($price instanceof EE_Price) {
116
-                $price_type = $price->type_obj();
117
-                if ($price_type instanceof EE_Price_Type) {
118
-                    switch ($price->type_obj()->base_type()) {
119
-                        case 1: // base price
120
-                        case 3: // surcharges
121
-                            $subtotal += $price->is_percent()
122
-                                ? $subtotal * $price->get('PRC_amount') / 100
123
-                                : $price->get('PRC_amount');
124
-                            break;
125
-                        case 2: // discounts
126
-                            $subtotal -= $price->is_percent()
127
-                                ? $subtotal * $price->get('PRC_amount') / 100
128
-                                : $price->get('PRC_amount');
129
-                            break;
130
-                    }
131
-                }
132
-            }
133
-        }
134
-        $TKT_ID = $ticket->ID();
135
-        EE_Taxes::$_subtotal[ $TKT_ID ] = $subtotal;
136
-        return $subtotal;
137
-    }
94
+	/**
95
+	 * simply take an incoming ticket and calculate the subtotal for the ticket
96
+	 *
97
+	 * @param EE_Ticket $ticket
98
+	 * @return float     subtotal calculated from all EE_Price[] on Ticket.
99
+	 * @throws EE_Error
100
+	 * @throws ReflectionException
101
+	 */
102
+	private static function _get_subtotal_for_admin(EE_Ticket $ticket)
103
+	{
104
+		$subtotal = 0;
105
+		// get all prices
106
+		$prices = $ticket->get_many_related(
107
+			'Price',
108
+			[
109
+				'default_where_conditions' => 'none',
110
+				'order_by'                 => ['PRC_order' => 'ASC'],
111
+			]
112
+		);
113
+		// let's loop through them (base price is always the first item)
114
+		foreach ($prices as $price) {
115
+			if ($price instanceof EE_Price) {
116
+				$price_type = $price->type_obj();
117
+				if ($price_type instanceof EE_Price_Type) {
118
+					switch ($price->type_obj()->base_type()) {
119
+						case 1: // base price
120
+						case 3: // surcharges
121
+							$subtotal += $price->is_percent()
122
+								? $subtotal * $price->get('PRC_amount') / 100
123
+								: $price->get('PRC_amount');
124
+							break;
125
+						case 2: // discounts
126
+							$subtotal -= $price->is_percent()
127
+								? $subtotal * $price->get('PRC_amount') / 100
128
+								: $price->get('PRC_amount');
129
+							break;
130
+					}
131
+				}
132
+			}
133
+		}
134
+		$TKT_ID = $ticket->ID();
135
+		EE_Taxes::$_subtotal[ $TKT_ID ] = $subtotal;
136
+		return $subtotal;
137
+	}
138 138
 
139 139
 
140
-    /**
141
-     * get all default prices that are a Tax price type (PRT_ID = 4) and return
142
-     *
143
-     * @return EE_Price[] EE_Price objects that have PRT_ID == 4
144
-     * @throws EE_Error
145
-     */
146
-    public static function get_taxes_for_admin()
147
-    {
148
-        if (empty(EE_Taxes::$_default_taxes)) {
149
-            /** @var EEM_Price $price_model */
150
-            $price_model = LoaderFactory::getLoader()->getShared('EEM_Price');
151
-            EE_Taxes::$_default_taxes = $price_model->get_all(
152
-                [['Price_Type.PBT_ID' => 4]]
153
-            );
154
-        }
155
-        return EE_Taxes::$_default_taxes;
156
-    }
140
+	/**
141
+	 * get all default prices that are a Tax price type (PRT_ID = 4) and return
142
+	 *
143
+	 * @return EE_Price[] EE_Price objects that have PRT_ID == 4
144
+	 * @throws EE_Error
145
+	 */
146
+	public static function get_taxes_for_admin()
147
+	{
148
+		if (empty(EE_Taxes::$_default_taxes)) {
149
+			/** @var EEM_Price $price_model */
150
+			$price_model = LoaderFactory::getLoader()->getShared('EEM_Price');
151
+			EE_Taxes::$_default_taxes = $price_model->get_all(
152
+				[['Price_Type.PBT_ID' => 4]]
153
+			);
154
+		}
155
+		return EE_Taxes::$_default_taxes;
156
+	}
157 157
 }
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -42,7 +42,7 @@  discard block
 block discarded – undo
42 42
         $tax = 0;
43 43
         $total_tax = 0;
44 44
         // This first checks to see if the given ticket is taxable.
45
-        if (! $ticket->taxable()) {
45
+        if ( ! $ticket->taxable()) {
46 46
             return $tax;
47 47
         }
48 48
         // get subtotal (notice we're only retrieving a subtotal if there isn't one given)
@@ -85,8 +85,8 @@  discard block
 block discarded – undo
85 85
     public static function get_subtotal_for_admin(EE_Ticket $ticket)
86 86
     {
87 87
         $TKT_ID = $ticket->ID();
88
-        return isset(EE_Taxes::$_subtotal[ $TKT_ID ])
89
-            ? EE_Taxes::$_subtotal[ $TKT_ID ]
88
+        return isset(EE_Taxes::$_subtotal[$TKT_ID])
89
+            ? EE_Taxes::$_subtotal[$TKT_ID]
90 90
             : EE_Taxes::_get_subtotal_for_admin($ticket);
91 91
     }
92 92
 
@@ -132,7 +132,7 @@  discard block
 block discarded – undo
132 132
             }
133 133
         }
134 134
         $TKT_ID = $ticket->ID();
135
-        EE_Taxes::$_subtotal[ $TKT_ID ] = $subtotal;
135
+        EE_Taxes::$_subtotal[$TKT_ID] = $subtotal;
136 136
         return $subtotal;
137 137
     }
138 138
 
Please login to merge, or discard this patch.
core/services/route_match/RouteHandler.php 1 patch
Indentation   +318 added lines, -318 removed lines patch added patch discarded remove patch
@@ -22,322 +22,322 @@
 block discarded – undo
22 22
 class RouteHandler
23 23
 {
24 24
 
25
-    /**
26
-     * @var LoaderInterface
27
-     */
28
-    private $loader;
29
-
30
-    /**
31
-     * @var EE_Maintenance_Mode $maintenance_mode
32
-     */
33
-    private $maintenance_mode;
34
-
35
-    /**
36
-     * @var RequestInterface $request
37
-     */
38
-    private $request;
39
-
40
-    /**
41
-     * @var RouteMatchSpecificationManager $route_manager
42
-     */
43
-    private $route_manager;
44
-
45
-    /**
46
-     * AdminRouter constructor.
47
-     *
48
-     * @param LoaderInterface  $loader
49
-     * @param EE_Maintenance_Mode $maintenance_mode
50
-     * @param RequestInterface $request
51
-     * @param RouteMatchSpecificationManager $route_manager
52
-     */
53
-    public function __construct(
54
-        LoaderInterface $loader,
55
-        EE_Maintenance_Mode $maintenance_mode,
56
-        RequestInterface $request,
57
-        RouteMatchSpecificationManager $route_manager
58
-    ) {
59
-        $this->loader = $loader;
60
-        $this->maintenance_mode = $maintenance_mode;
61
-        $this->request = $request;
62
-        $this->route_manager = $route_manager;
63
-    }
64
-
65
-
66
-    /**
67
-     * @throws Exception
68
-     * @since $VID:$
69
-     */
70
-    public function handleAssetManagerRequest()
71
-    {
72
-        try {
73
-            if (! $this->request->isAdmin()
74
-                && ! $this->request->isFrontend()
75
-                && ! $this->request->isIframe()
76
-                && ! $this->request->isWordPressApi()
77
-            ) {
78
-                return;
79
-            }
80
-            $this->loader->getShared('EventEspresso\core\services\assets\Registry');
81
-            $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
82
-            if ($this->canLoadBlocks()) {
83
-                $this->loader->getShared(
84
-                    'EventEspresso\core\services\editor\BlockRegistrationManager'
85
-                );
86
-            }
87
-        } catch (Exception $exception) {
88
-            new ExceptionStackTraceDisplay($exception);
89
-        }
90
-    }
91
-
92
-
93
-    /**
94
-     * Return whether blocks can be registered/loaded or not.
95
-     *
96
-     * @return bool
97
-     * @since $VID:$
98
-     */
99
-    private function canLoadBlocks()
100
-    {
101
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
102
-               && function_exists('register_block_type')
103
-               // don't load blocks if in the Divi page builder editor context
104
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
105
-               && ! $this->request->getRequestParam('et_fb', false);
106
-    }
107
-
108
-
109
-    /**
110
-     * @throws Exception
111
-     * @since $VID:$
112
-     */
113
-    public function handleControllerRequest()
114
-    {
115
-        try {
116
-            $this->handleAdminRequest();
117
-            $this->handleFrontendRequest();
118
-            $this->handleWordPressHeartbeatRequest();
119
-            $this->handleWordPressPluginsPage();
120
-        } catch (Exception $exception) {
121
-            new ExceptionStackTraceDisplay($exception);
122
-        }
123
-    }
124
-
125
-
126
-    /**
127
-     * @throws Exception
128
-     * @since $VID:$
129
-     */
130
-    private function handleAdminRequest()
131
-    {
132
-        try {
133
-            if (! $this->request->isAdmin() || $this->request->isAdminAjax()) {
134
-                return;
135
-            }
136
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
137
-            $this->loader->getShared('EE_Admin');
138
-
139
-            EE_Dependency_Map::register_dependencies(
140
-                'EventEspresso\core\domain\services\assets\EspressoAdminAssetManager',
141
-                [
142
-                    'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
143
-                    'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
144
-                    'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
145
-                ]
146
-            );
147
-            $this->loader->getShared('EventEspresso\core\domain\services\assets\EspressoAdminAssetManager');
148
-        } catch (Exception $exception) {
149
-            new ExceptionStackTraceDisplay($exception);
150
-        }
151
-    }
152
-
153
-
154
-    /**
155
-     * @throws Exception
156
-     * @since $VID:$
157
-     */
158
-    private function handleFrontendRequest()
159
-    {
160
-        try {
161
-            // don't load frontend if M-Mode is active or request is not browser HTTP
162
-            if ($this->maintenance_mode->level() || ! $this->request->isFrontend() || ! $this->request->isFrontAjax()) {
163
-                return;
164
-            }
165
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
166
-            $this->loader->getShared('EE_Front_Controller');
167
-        } catch (Exception $exception) {
168
-            new ExceptionStackTraceDisplay($exception);
169
-        }
170
-    }
171
-
172
-
173
-    /**
174
-     * @return bool
175
-     * @since $VID:$
176
-     */
177
-    private function isGQLRequest()
178
-    {
179
-        return PHP_VERSION_ID > 70000
180
-               && (
181
-                   $this->request->isGQL()
182
-                   || $this->request->isUnitTesting()
183
-                   || $this->route_manager->routeMatchesCurrentRequest(
184
-                       'EventEspresso\core\domain\entities\route_match\specifications\admin\EspressoEventEditor'
185
-                   )
186
-               );
187
-    }
188
-
189
-
190
-    /**
191
-     * @throws Exception
192
-     * @since $VID:$
193
-     */
194
-    public function handleGQLRequest()
195
-    {
196
-        try {
197
-            if (! $this->isGQLRequest()) {
198
-                return;
199
-            }
200
-            if (! class_exists('WPGraphQL')) {
201
-                require_once EE_THIRD_PARTY . 'wp-graphql/wp-graphql.php';
202
-            }
203
-            // load handler for EE GraphQL requests
204
-            $graphQL_manager = $this->loader->getShared(
205
-                'EventEspresso\core\services\graphql\GraphQLManager'
206
-            );
207
-            $graphQL_manager->init();
208
-        } catch (Exception $exception) {
209
-            new ExceptionStackTraceDisplay($exception);
210
-        }
211
-    }
212
-
213
-
214
-    /**
215
-     * @throws Exception
216
-     * @since $VID:$
217
-     */
218
-    public function handlePersonalDataRequest()
219
-    {
220
-        try {
221
-            // don't load frontend if M-Mode is active or request is not browser HTTP
222
-            if (! $this->request->isAdmin()
223
-                || ! $this->request->isAjax()
224
-                || ! $this->maintenance_mode->models_can_query()
225
-            ) {
226
-                return;
227
-            }
228
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
229
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
230
-        } catch (Exception $exception) {
231
-            new ExceptionStackTraceDisplay($exception);
232
-        }
233
-    }
234
-
235
-
236
-    /**
237
-     * @throws Exception
238
-     * @since $VID:$
239
-     */
240
-    public function handlePueRequest()
241
-    {
242
-        try {
243
-            if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
244
-                // pew pew pew
245
-                $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
246
-                do_action('AHEE__EE_System__brew_espresso__after_pue_init');
247
-            }
248
-        } catch (Exception $exception) {
249
-            new ExceptionStackTraceDisplay($exception);
250
-        }
251
-    }
252
-
253
-
254
-    /**
255
-     * @throws Exception
256
-     * @since $VID:$
257
-     */
258
-    public function handleSessionRequest()
259
-    {
260
-        try {
261
-            if (! $this->request->isAdmin() && ! $this->request->isEeAjax() && ! $this->request->isFrontend()) {
262
-                return;
263
-            }
264
-            $this->loader->getShared('EE_Session');
265
-        } catch (Exception $exception) {
266
-            new ExceptionStackTraceDisplay($exception);
267
-        }
268
-    }
269
-
270
-
271
-    /**
272
-     * @throws Exception
273
-     * @since $VID:$
274
-     */
275
-    public function handleShortcodesRequest()
276
-    {
277
-        try {
278
-            if (! $this->request->isFrontend() && ! $this->request->isIframe() && ! $this->request->isAjax()) {
279
-                return;
280
-            }
281
-            // load, register, and add shortcodes the new way
282
-            $this->loader->getShared(
283
-                'EventEspresso\core\services\shortcodes\ShortcodesManager',
284
-                [
285
-                    // and the old way, but we'll put it under control of the new system
286
-                    EE_Config::getLegacyShortcodesManager(),
287
-                ]
288
-            );
289
-        } catch (Exception $exception) {
290
-            new ExceptionStackTraceDisplay($exception);
291
-        }
292
-    }
293
-
294
-
295
-    /**
296
-     * @throws Exception
297
-     * @since $VID:$
298
-     */
299
-    public function handleWordPressHeartbeatRequest()
300
-    {
301
-        try {
302
-            if (! $this->request->isWordPressHeartbeat()) {
303
-                return;
304
-            }
305
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
306
-        } catch (Exception $exception) {
307
-            new ExceptionStackTraceDisplay($exception);
308
-        }
309
-    }
310
-
311
-
312
-    /**
313
-     * @throws Exception
314
-     * @since $VID:$
315
-     */
316
-    public function handleWordPressPluginsPage()
317
-    {
318
-        try {
319
-            if (! $this->request->isAdmin()
320
-                || ! $this->route_manager->routeMatchesCurrentRequest(
321
-                    'EventEspresso\core\domain\entities\route_match\specifications\admin\WordPressPluginsPage'
322
-                )
323
-            ) {
324
-                return;
325
-            }
326
-            EE_Dependency_Map::register_dependencies(
327
-                'EventEspresso\core\domain\services\assets\WordpressPluginsPageAssetManager',
328
-                [
329
-                    'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
330
-                    'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
331
-                    'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
332
-                    'EventEspresso\core\domain\services\admin\ExitModal' => EE_Dependency_Map::load_from_cache,
333
-                ]
334
-            );
335
-            $this->loader->getShared('EventEspresso\core\domain\services\assets\WordpressPluginsPageAssetManager');
336
-            /** @var PluginUpsells $plugin_upsells */
337
-            $plugin_upsells = $this->loader->getShared('EventEspresso\core\domain\services\admin\PluginUpsells');
338
-            $plugin_upsells->decafUpsells();
339
-        } catch (Exception $exception) {
340
-            new ExceptionStackTraceDisplay($exception);
341
-        }
342
-    }
25
+	/**
26
+	 * @var LoaderInterface
27
+	 */
28
+	private $loader;
29
+
30
+	/**
31
+	 * @var EE_Maintenance_Mode $maintenance_mode
32
+	 */
33
+	private $maintenance_mode;
34
+
35
+	/**
36
+	 * @var RequestInterface $request
37
+	 */
38
+	private $request;
39
+
40
+	/**
41
+	 * @var RouteMatchSpecificationManager $route_manager
42
+	 */
43
+	private $route_manager;
44
+
45
+	/**
46
+	 * AdminRouter constructor.
47
+	 *
48
+	 * @param LoaderInterface  $loader
49
+	 * @param EE_Maintenance_Mode $maintenance_mode
50
+	 * @param RequestInterface $request
51
+	 * @param RouteMatchSpecificationManager $route_manager
52
+	 */
53
+	public function __construct(
54
+		LoaderInterface $loader,
55
+		EE_Maintenance_Mode $maintenance_mode,
56
+		RequestInterface $request,
57
+		RouteMatchSpecificationManager $route_manager
58
+	) {
59
+		$this->loader = $loader;
60
+		$this->maintenance_mode = $maintenance_mode;
61
+		$this->request = $request;
62
+		$this->route_manager = $route_manager;
63
+	}
64
+
65
+
66
+	/**
67
+	 * @throws Exception
68
+	 * @since $VID:$
69
+	 */
70
+	public function handleAssetManagerRequest()
71
+	{
72
+		try {
73
+			if (! $this->request->isAdmin()
74
+				&& ! $this->request->isFrontend()
75
+				&& ! $this->request->isIframe()
76
+				&& ! $this->request->isWordPressApi()
77
+			) {
78
+				return;
79
+			}
80
+			$this->loader->getShared('EventEspresso\core\services\assets\Registry');
81
+			$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
82
+			if ($this->canLoadBlocks()) {
83
+				$this->loader->getShared(
84
+					'EventEspresso\core\services\editor\BlockRegistrationManager'
85
+				);
86
+			}
87
+		} catch (Exception $exception) {
88
+			new ExceptionStackTraceDisplay($exception);
89
+		}
90
+	}
91
+
92
+
93
+	/**
94
+	 * Return whether blocks can be registered/loaded or not.
95
+	 *
96
+	 * @return bool
97
+	 * @since $VID:$
98
+	 */
99
+	private function canLoadBlocks()
100
+	{
101
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
102
+			   && function_exists('register_block_type')
103
+			   // don't load blocks if in the Divi page builder editor context
104
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
105
+			   && ! $this->request->getRequestParam('et_fb', false);
106
+	}
107
+
108
+
109
+	/**
110
+	 * @throws Exception
111
+	 * @since $VID:$
112
+	 */
113
+	public function handleControllerRequest()
114
+	{
115
+		try {
116
+			$this->handleAdminRequest();
117
+			$this->handleFrontendRequest();
118
+			$this->handleWordPressHeartbeatRequest();
119
+			$this->handleWordPressPluginsPage();
120
+		} catch (Exception $exception) {
121
+			new ExceptionStackTraceDisplay($exception);
122
+		}
123
+	}
124
+
125
+
126
+	/**
127
+	 * @throws Exception
128
+	 * @since $VID:$
129
+	 */
130
+	private function handleAdminRequest()
131
+	{
132
+		try {
133
+			if (! $this->request->isAdmin() || $this->request->isAdminAjax()) {
134
+				return;
135
+			}
136
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
137
+			$this->loader->getShared('EE_Admin');
138
+
139
+			EE_Dependency_Map::register_dependencies(
140
+				'EventEspresso\core\domain\services\assets\EspressoAdminAssetManager',
141
+				[
142
+					'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
143
+					'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
144
+					'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
145
+				]
146
+			);
147
+			$this->loader->getShared('EventEspresso\core\domain\services\assets\EspressoAdminAssetManager');
148
+		} catch (Exception $exception) {
149
+			new ExceptionStackTraceDisplay($exception);
150
+		}
151
+	}
152
+
153
+
154
+	/**
155
+	 * @throws Exception
156
+	 * @since $VID:$
157
+	 */
158
+	private function handleFrontendRequest()
159
+	{
160
+		try {
161
+			// don't load frontend if M-Mode is active or request is not browser HTTP
162
+			if ($this->maintenance_mode->level() || ! $this->request->isFrontend() || ! $this->request->isFrontAjax()) {
163
+				return;
164
+			}
165
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
166
+			$this->loader->getShared('EE_Front_Controller');
167
+		} catch (Exception $exception) {
168
+			new ExceptionStackTraceDisplay($exception);
169
+		}
170
+	}
171
+
172
+
173
+	/**
174
+	 * @return bool
175
+	 * @since $VID:$
176
+	 */
177
+	private function isGQLRequest()
178
+	{
179
+		return PHP_VERSION_ID > 70000
180
+			   && (
181
+				   $this->request->isGQL()
182
+				   || $this->request->isUnitTesting()
183
+				   || $this->route_manager->routeMatchesCurrentRequest(
184
+					   'EventEspresso\core\domain\entities\route_match\specifications\admin\EspressoEventEditor'
185
+				   )
186
+			   );
187
+	}
188
+
189
+
190
+	/**
191
+	 * @throws Exception
192
+	 * @since $VID:$
193
+	 */
194
+	public function handleGQLRequest()
195
+	{
196
+		try {
197
+			if (! $this->isGQLRequest()) {
198
+				return;
199
+			}
200
+			if (! class_exists('WPGraphQL')) {
201
+				require_once EE_THIRD_PARTY . 'wp-graphql/wp-graphql.php';
202
+			}
203
+			// load handler for EE GraphQL requests
204
+			$graphQL_manager = $this->loader->getShared(
205
+				'EventEspresso\core\services\graphql\GraphQLManager'
206
+			);
207
+			$graphQL_manager->init();
208
+		} catch (Exception $exception) {
209
+			new ExceptionStackTraceDisplay($exception);
210
+		}
211
+	}
212
+
213
+
214
+	/**
215
+	 * @throws Exception
216
+	 * @since $VID:$
217
+	 */
218
+	public function handlePersonalDataRequest()
219
+	{
220
+		try {
221
+			// don't load frontend if M-Mode is active or request is not browser HTTP
222
+			if (! $this->request->isAdmin()
223
+				|| ! $this->request->isAjax()
224
+				|| ! $this->maintenance_mode->models_can_query()
225
+			) {
226
+				return;
227
+			}
228
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
229
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
230
+		} catch (Exception $exception) {
231
+			new ExceptionStackTraceDisplay($exception);
232
+		}
233
+	}
234
+
235
+
236
+	/**
237
+	 * @throws Exception
238
+	 * @since $VID:$
239
+	 */
240
+	public function handlePueRequest()
241
+	{
242
+		try {
243
+			if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
244
+				// pew pew pew
245
+				$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
246
+				do_action('AHEE__EE_System__brew_espresso__after_pue_init');
247
+			}
248
+		} catch (Exception $exception) {
249
+			new ExceptionStackTraceDisplay($exception);
250
+		}
251
+	}
252
+
253
+
254
+	/**
255
+	 * @throws Exception
256
+	 * @since $VID:$
257
+	 */
258
+	public function handleSessionRequest()
259
+	{
260
+		try {
261
+			if (! $this->request->isAdmin() && ! $this->request->isEeAjax() && ! $this->request->isFrontend()) {
262
+				return;
263
+			}
264
+			$this->loader->getShared('EE_Session');
265
+		} catch (Exception $exception) {
266
+			new ExceptionStackTraceDisplay($exception);
267
+		}
268
+	}
269
+
270
+
271
+	/**
272
+	 * @throws Exception
273
+	 * @since $VID:$
274
+	 */
275
+	public function handleShortcodesRequest()
276
+	{
277
+		try {
278
+			if (! $this->request->isFrontend() && ! $this->request->isIframe() && ! $this->request->isAjax()) {
279
+				return;
280
+			}
281
+			// load, register, and add shortcodes the new way
282
+			$this->loader->getShared(
283
+				'EventEspresso\core\services\shortcodes\ShortcodesManager',
284
+				[
285
+					// and the old way, but we'll put it under control of the new system
286
+					EE_Config::getLegacyShortcodesManager(),
287
+				]
288
+			);
289
+		} catch (Exception $exception) {
290
+			new ExceptionStackTraceDisplay($exception);
291
+		}
292
+	}
293
+
294
+
295
+	/**
296
+	 * @throws Exception
297
+	 * @since $VID:$
298
+	 */
299
+	public function handleWordPressHeartbeatRequest()
300
+	{
301
+		try {
302
+			if (! $this->request->isWordPressHeartbeat()) {
303
+				return;
304
+			}
305
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
306
+		} catch (Exception $exception) {
307
+			new ExceptionStackTraceDisplay($exception);
308
+		}
309
+	}
310
+
311
+
312
+	/**
313
+	 * @throws Exception
314
+	 * @since $VID:$
315
+	 */
316
+	public function handleWordPressPluginsPage()
317
+	{
318
+		try {
319
+			if (! $this->request->isAdmin()
320
+				|| ! $this->route_manager->routeMatchesCurrentRequest(
321
+					'EventEspresso\core\domain\entities\route_match\specifications\admin\WordPressPluginsPage'
322
+				)
323
+			) {
324
+				return;
325
+			}
326
+			EE_Dependency_Map::register_dependencies(
327
+				'EventEspresso\core\domain\services\assets\WordpressPluginsPageAssetManager',
328
+				[
329
+					'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
330
+					'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
331
+					'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
332
+					'EventEspresso\core\domain\services\admin\ExitModal' => EE_Dependency_Map::load_from_cache,
333
+				]
334
+			);
335
+			$this->loader->getShared('EventEspresso\core\domain\services\assets\WordpressPluginsPageAssetManager');
336
+			/** @var PluginUpsells $plugin_upsells */
337
+			$plugin_upsells = $this->loader->getShared('EventEspresso\core\domain\services\admin\PluginUpsells');
338
+			$plugin_upsells->decafUpsells();
339
+		} catch (Exception $exception) {
340
+			new ExceptionStackTraceDisplay($exception);
341
+		}
342
+	}
343 343
 }
Please login to merge, or discard this patch.
core/domain/services/admin/entities/DefaultPrices.php 2 patches
Indentation   +94 added lines, -94 removed lines patch added patch discarded remove patch
@@ -25,105 +25,105 @@
 block discarded – undo
25 25
 class DefaultPrices implements DefaultEntityGeneratorInterface
26 26
 {
27 27
 
28
-    /**
29
-     * @var EEM_Price $price_model
30
-     */
31
-    protected $price_model;
28
+	/**
29
+	 * @var EEM_Price $price_model
30
+	 */
31
+	protected $price_model;
32 32
 
33
-    /**
34
-     * @var EEM_Price_Type $price_type_model
35
-     */
36
-    protected $price_type_model;
33
+	/**
34
+	 * @var EEM_Price_Type $price_type_model
35
+	 */
36
+	protected $price_type_model;
37 37
 
38 38
 
39
-    /**
40
-     * @param EEM_Price      $price_model
41
-     * @param EEM_Price_Type $price_type_model
42
-     */
43
-    public function __construct(EEM_Price $price_model, EEM_Price_Type $price_type_model)
44
-    {
45
-        $this->price_model = $price_model;
46
-        $this->price_type_model = $price_type_model;
47
-    }
39
+	/**
40
+	 * @param EEM_Price      $price_model
41
+	 * @param EEM_Price_Type $price_type_model
42
+	 */
43
+	public function __construct(EEM_Price $price_model, EEM_Price_Type $price_type_model)
44
+	{
45
+		$this->price_model = $price_model;
46
+		$this->price_type_model = $price_type_model;
47
+	}
48 48
 
49 49
 
50
-    /**
51
-     * @param EE_Ticket|EE_Base_Class $entity
52
-     * @return EE_Price[]
53
-     * @throws EE_Error
54
-     * @throws InvalidInterfaceException
55
-     * @throws ReflectionException
56
-     * @since $VID:$
57
-     */
58
-    public function create(EE_Base_Class $entity)
59
-    {
60
-        if (! $entity instanceof EE_Ticket) {
61
-            throw new InvalidEntityException($entity, 'EE_Ticket');
62
-        }
63
-        $new_prices = [];
64
-        $has_base_price = false;
65
-        $default_prices = $this->price_model->get_all_default_prices(false, true);
66
-        if (is_array($default_prices)) {
67
-            foreach ($default_prices as $default_price) {
68
-                if (! $default_price instanceof EE_Price) {
69
-                    throw new InvalidEntityException($default_price, 'EE_Price');
70
-                }
71
-                // assign taxes but don't duplicate them because they operate globally
72
-                if ($default_price->is_tax()) {
73
-                    $entity->set_taxable(true);
74
-                    $default_price->_add_relation_to($entity, 'Ticket');
75
-                    continue;
76
-                }
77
-                $default_price_clone = clone $default_price;
78
-                $default_price_clone->set('PRC_ID', null);
79
-                $default_price_clone->set('PRC_is_default', false);
80
-                $default_price_clone->save();
81
-                $default_price_clone->_add_relation_to($entity, 'Ticket');
82
-                // verify that a base price has been set
83
-                $has_base_price = $default_price_clone->is_base_price() ? true : $has_base_price;
84
-                $new_prices[ $default_price_clone->ID() ] = $default_price_clone;
85
-            }
86
-        }
87
-        if (! $has_base_price) {
88
-            $new_base_price = $this->createNewBasePrice($entity);
89
-            $new_prices[ $new_base_price->ID() ] = $new_base_price;
90
-        }
91
-        $ticket_total = $entity->get_ticket_total_with_taxes(true);
92
-        if ($ticket_total !== $entity->ticket_price()) {
93
-            $entity->set_price($ticket_total);
94
-            $entity->save();
95
-        }
96
-        return $new_prices;
97
-    }
50
+	/**
51
+	 * @param EE_Ticket|EE_Base_Class $entity
52
+	 * @return EE_Price[]
53
+	 * @throws EE_Error
54
+	 * @throws InvalidInterfaceException
55
+	 * @throws ReflectionException
56
+	 * @since $VID:$
57
+	 */
58
+	public function create(EE_Base_Class $entity)
59
+	{
60
+		if (! $entity instanceof EE_Ticket) {
61
+			throw new InvalidEntityException($entity, 'EE_Ticket');
62
+		}
63
+		$new_prices = [];
64
+		$has_base_price = false;
65
+		$default_prices = $this->price_model->get_all_default_prices(false, true);
66
+		if (is_array($default_prices)) {
67
+			foreach ($default_prices as $default_price) {
68
+				if (! $default_price instanceof EE_Price) {
69
+					throw new InvalidEntityException($default_price, 'EE_Price');
70
+				}
71
+				// assign taxes but don't duplicate them because they operate globally
72
+				if ($default_price->is_tax()) {
73
+					$entity->set_taxable(true);
74
+					$default_price->_add_relation_to($entity, 'Ticket');
75
+					continue;
76
+				}
77
+				$default_price_clone = clone $default_price;
78
+				$default_price_clone->set('PRC_ID', null);
79
+				$default_price_clone->set('PRC_is_default', false);
80
+				$default_price_clone->save();
81
+				$default_price_clone->_add_relation_to($entity, 'Ticket');
82
+				// verify that a base price has been set
83
+				$has_base_price = $default_price_clone->is_base_price() ? true : $has_base_price;
84
+				$new_prices[ $default_price_clone->ID() ] = $default_price_clone;
85
+			}
86
+		}
87
+		if (! $has_base_price) {
88
+			$new_base_price = $this->createNewBasePrice($entity);
89
+			$new_prices[ $new_base_price->ID() ] = $new_base_price;
90
+		}
91
+		$ticket_total = $entity->get_ticket_total_with_taxes(true);
92
+		if ($ticket_total !== $entity->ticket_price()) {
93
+			$entity->set_price($ticket_total);
94
+			$entity->save();
95
+		}
96
+		return $new_prices;
97
+	}
98 98
 
99 99
 
100
-    /**
101
-     * @param EE_Ticket $ticket
102
-     * @return EE_Price
103
-     * @throws EE_Error
104
-     * @throws ReflectionException
105
-     * @since $VID:$
106
-     */
107
-    protected function createNewBasePrice(EE_Ticket $ticket)
108
-    {
109
-        $new_base_price = $this->price_model->get_new_price();
110
-        $base_price_type = $this->price_type_model->get_one([
111
-            [
112
-                'PBT_ID' => EEM_Price_Type::base_type_base_price
113
-            ]
114
-        ]);
115
-        if (! $base_price_type instanceof EE_Price_Type) {
116
-            throw new RuntimeException(
117
-                esc_html__(
118
-                    'A valid base price type could not be retrieved from the database.',
119
-                    'event_espresso'
120
-                )
121
-            );
122
-        }
123
-        $new_base_price->set('PRT_ID', $base_price_type->ID());
124
-        $new_base_price->set('PRC_is_default', false);
125
-        $new_base_price->save();
126
-        $new_base_price->_add_relation_to($ticket, 'Ticket');
127
-        return $new_base_price;
128
-    }
100
+	/**
101
+	 * @param EE_Ticket $ticket
102
+	 * @return EE_Price
103
+	 * @throws EE_Error
104
+	 * @throws ReflectionException
105
+	 * @since $VID:$
106
+	 */
107
+	protected function createNewBasePrice(EE_Ticket $ticket)
108
+	{
109
+		$new_base_price = $this->price_model->get_new_price();
110
+		$base_price_type = $this->price_type_model->get_one([
111
+			[
112
+				'PBT_ID' => EEM_Price_Type::base_type_base_price
113
+			]
114
+		]);
115
+		if (! $base_price_type instanceof EE_Price_Type) {
116
+			throw new RuntimeException(
117
+				esc_html__(
118
+					'A valid base price type could not be retrieved from the database.',
119
+					'event_espresso'
120
+				)
121
+			);
122
+		}
123
+		$new_base_price->set('PRT_ID', $base_price_type->ID());
124
+		$new_base_price->set('PRC_is_default', false);
125
+		$new_base_price->save();
126
+		$new_base_price->_add_relation_to($ticket, 'Ticket');
127
+		return $new_base_price;
128
+	}
129 129
 }
Please login to merge, or discard this patch.
Spacing   +6 added lines, -6 removed lines patch added patch discarded remove patch
@@ -57,7 +57,7 @@  discard block
 block discarded – undo
57 57
      */
58 58
     public function create(EE_Base_Class $entity)
59 59
     {
60
-        if (! $entity instanceof EE_Ticket) {
60
+        if ( ! $entity instanceof EE_Ticket) {
61 61
             throw new InvalidEntityException($entity, 'EE_Ticket');
62 62
         }
63 63
         $new_prices = [];
@@ -65,7 +65,7 @@  discard block
 block discarded – undo
65 65
         $default_prices = $this->price_model->get_all_default_prices(false, true);
66 66
         if (is_array($default_prices)) {
67 67
             foreach ($default_prices as $default_price) {
68
-                if (! $default_price instanceof EE_Price) {
68
+                if ( ! $default_price instanceof EE_Price) {
69 69
                     throw new InvalidEntityException($default_price, 'EE_Price');
70 70
                 }
71 71
                 // assign taxes but don't duplicate them because they operate globally
@@ -81,12 +81,12 @@  discard block
 block discarded – undo
81 81
                 $default_price_clone->_add_relation_to($entity, 'Ticket');
82 82
                 // verify that a base price has been set
83 83
                 $has_base_price = $default_price_clone->is_base_price() ? true : $has_base_price;
84
-                $new_prices[ $default_price_clone->ID() ] = $default_price_clone;
84
+                $new_prices[$default_price_clone->ID()] = $default_price_clone;
85 85
             }
86 86
         }
87
-        if (! $has_base_price) {
87
+        if ( ! $has_base_price) {
88 88
             $new_base_price = $this->createNewBasePrice($entity);
89
-            $new_prices[ $new_base_price->ID() ] = $new_base_price;
89
+            $new_prices[$new_base_price->ID()] = $new_base_price;
90 90
         }
91 91
         $ticket_total = $entity->get_ticket_total_with_taxes(true);
92 92
         if ($ticket_total !== $entity->ticket_price()) {
@@ -112,7 +112,7 @@  discard block
 block discarded – undo
112 112
                 'PBT_ID' => EEM_Price_Type::base_type_base_price
113 113
             ]
114 114
         ]);
115
-        if (! $base_price_type instanceof EE_Price_Type) {
115
+        if ( ! $base_price_type instanceof EE_Price_Type) {
116 116
             throw new RuntimeException(
117 117
                 esc_html__(
118 118
                     'A valid base price type could not be retrieved from the database.',
Please login to merge, or discard this patch.
core/domain/services/admin/PluginUpsells.php 2 patches
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -17,70 +17,70 @@
 block discarded – undo
17 17
 class PluginUpsells
18 18
 {
19 19
 
20
-    /**
21
-     * @var DomainInterface
22
-     */
23
-    private $domain;
20
+	/**
21
+	 * @var DomainInterface
22
+	 */
23
+	private $domain;
24 24
 
25 25
 
26
-    /**
27
-     * PluginUpsells constructor.
28
-     *
29
-     * @param DomainInterface $domain
30
-     */
31
-    public function __construct(DomainInterface $domain)
32
-    {
33
-        $this->domain = $domain;
34
-    }
26
+	/**
27
+	 * PluginUpsells constructor.
28
+	 *
29
+	 * @param DomainInterface $domain
30
+	 */
31
+	public function __construct(DomainInterface $domain)
32
+	{
33
+		$this->domain = $domain;
34
+	}
35 35
 
36 36
 
37
-    /**
38
-     * Hook in various upsells for the decaf version of EE.
39
-     */
40
-    public function decafUpsells()
41
-    {
42
-        if ($this->domain instanceof CaffeinatedInterface && ! $this->domain->isCaffeinated()) {
43
-            add_action('after_plugin_row', array($this, 'doPremiumUpsell'), 10);
44
-        }
45
-    }
37
+	/**
38
+	 * Hook in various upsells for the decaf version of EE.
39
+	 */
40
+	public function decafUpsells()
41
+	{
42
+		if ($this->domain instanceof CaffeinatedInterface && ! $this->domain->isCaffeinated()) {
43
+			add_action('after_plugin_row', array($this, 'doPremiumUpsell'), 10);
44
+		}
45
+	}
46 46
 
47 47
 
48
-    /**
49
-     * Callback for `after_plugin_row` to add upsell info
50
-     *
51
-     * @param string $plugin_file
52
-     * @throws DomainException
53
-     */
54
-    public function doPremiumUpsell($plugin_file)
55
-    {
56
-        if ($plugin_file === $this->domain->pluginBasename()) {
57
-            echo '
48
+	/**
49
+	 * Callback for `after_plugin_row` to add upsell info
50
+	 *
51
+	 * @param string $plugin_file
52
+	 * @throws DomainException
53
+	 */
54
+	public function doPremiumUpsell($plugin_file)
55
+	{
56
+		if ($plugin_file === $this->domain->pluginBasename()) {
57
+			echo '
58 58
     <tr class="ee-upsell-plugin-list-table active">
59 59
         <th scope="row" class="check-column"></th>
60 60
         <td class="column-primary">
61 61
             <div class="ee-upsell-col" style="padding:10px 0;">
62 62
                 <a href="https://eventespresso.com/purchase/?slug=ee4-license-personal&utm_source=wp_admin_plugins_screen&utm_medium=link&utm_campaign=plugins_screen_upgrade_link"">
63 63
                     <button class="button button-secondary" style="background:#008dcb; border:1px solid #008dcb; color:#fff; ">'
64
-                     . esc_html__('Upgrade for Support', 'event_espresso')
65
-                     . '</button>
64
+					 . esc_html__('Upgrade for Support', 'event_espresso')
65
+					 . '</button>
66 66
                 </a>
67 67
             </div>                 
68 68
         </td>
69 69
         <td class="column-description"> 
70 70
             <div class="ee-upsell-col plugin-description" style="font-size: .85rem; line-height: 1.2rem; padding:5px 0;">'
71
-                 . sprintf(
72
-                     esc_html__(
73
-                         'You\'re missing out on %1$sexpert support%2$s and %1$sone-click updates%2$s!%3$sDon\'t have an Event Espresso support license key? Support the project and buy one today!',
74
-                         'event_espresso'
75
-                     ),
76
-                     '<strong>',
77
-                     '</strong>',
78
-                     '<br />'
79
-                 ) .
80
-            '</div>
71
+				 . sprintf(
72
+					 esc_html__(
73
+						 'You\'re missing out on %1$sexpert support%2$s and %1$sone-click updates%2$s!%3$sDon\'t have an Event Espresso support license key? Support the project and buy one today!',
74
+						 'event_espresso'
75
+					 ),
76
+					 '<strong>',
77
+					 '</strong>',
78
+					 '<br />'
79
+				 ) .
80
+			'</div>
81 81
         </td>
82 82
     </tr>
83 83
 ';
84
-        }
85
-    }
84
+		}
85
+	}
86 86
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -76,7 +76,7 @@
 block discarded – undo
76 76
                      '<strong>',
77 77
                      '</strong>',
78 78
                      '<br />'
79
-                 ) .
79
+                 ).
80 80
             '</div>
81 81
         </td>
82 82
     </tr>
Please login to merge, or discard this patch.
core/db_models/EEM_Price.model.php 2 patches
Indentation   +307 added lines, -307 removed lines patch added patch discarded remove patch
@@ -13,336 +13,336 @@
 block discarded – undo
13 13
 class EEM_Price extends EEM_Soft_Delete_Base
14 14
 {
15 15
 
16
-    // private instance of the EEM_Price object
17
-    protected static $_instance;
16
+	// private instance of the EEM_Price object
17
+	protected static $_instance;
18 18
 
19 19
 
20
-    /**
21
-     * private constructor to prevent direct creation
22
-     *
23
-     * @Constructor
24
-     * @param string $timezone string representing the timezone we want to set for returned Date Time Strings
25
-     *                         (and any incoming timezone data that gets saved).
26
-     *                         Note this just sends the timezone info to the date time model field objects.
27
-     *                         Default is NULL
28
-     *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
29
-     */
30
-    protected function __construct($timezone)
31
-    {
32
-        require_once(EE_MODELS . 'EEM_Price_Type.model.php');
33
-        $this->singular_item = __('Price', 'event_espresso');
34
-        $this->plural_item = __('Prices', 'event_espresso');
20
+	/**
21
+	 * private constructor to prevent direct creation
22
+	 *
23
+	 * @Constructor
24
+	 * @param string $timezone string representing the timezone we want to set for returned Date Time Strings
25
+	 *                         (and any incoming timezone data that gets saved).
26
+	 *                         Note this just sends the timezone info to the date time model field objects.
27
+	 *                         Default is NULL
28
+	 *                         (and will be assumed using the set timezone in the 'timezone_string' wp option)
29
+	 */
30
+	protected function __construct($timezone)
31
+	{
32
+		require_once(EE_MODELS . 'EEM_Price_Type.model.php');
33
+		$this->singular_item = __('Price', 'event_espresso');
34
+		$this->plural_item = __('Prices', 'event_espresso');
35 35
 
36
-        $this->_tables = array(
37
-            'Price' => new EE_Primary_Table('esp_price', 'PRC_ID'),
38
-        );
39
-        $this->_fields = array(
40
-            'Price' => array(
41
-                'PRC_ID'         => new EE_Primary_Key_Int_Field(
42
-                    'PRC_ID',
43
-                    'Price ID'
44
-                ),
45
-                'PRT_ID'         => new EE_Foreign_Key_Int_Field(
46
-                    'PRT_ID',
47
-                    esc_html__('Price type Id', 'event_espresso'),
48
-                    false,
49
-                    null,
50
-                    'Price_Type'
51
-                ),
52
-                'PRC_amount'     => new EE_Money_Field(
53
-                    'PRC_amount',
54
-                    esc_html__('Price Amount', 'event_espresso'),
55
-                    false,
56
-                    0
57
-                ),
58
-                'PRC_name'       => new EE_Plain_Text_Field(
59
-                    'PRC_name',
60
-                    esc_html__('Name of Price', 'event_espresso'),
61
-                    false,
62
-                    ''
63
-                ),
64
-                'PRC_desc'       => new EE_Post_Content_Field(
65
-                    'PRC_desc',
66
-                    esc_html__('Price Description', 'event_espresso'),
67
-                    false,
68
-                    ''
69
-                ),
70
-                'PRC_is_default' => new EE_Boolean_Field(
71
-                    'PRC_is_default',
72
-                    esc_html__('Flag indicating whether price is a default price', 'event_espresso'),
73
-                    false,
74
-                    false
75
-                ),
76
-                'PRC_overrides'  => new EE_Integer_Field(
77
-                    'PRC_overrides',
78
-                    esc_html__(
79
-                        'Price ID for a global Price that will be overridden by this Price  ( for replacing default prices )',
80
-                        'event_espresso'
81
-                    ),
82
-                    true,
83
-                    0
84
-                ),
85
-                'PRC_order'      => new EE_Integer_Field(
86
-                    'PRC_order',
87
-                    esc_html__(
88
-                        'Order of Application of Price (lower numbers apply first?)',
89
-                        'event_espresso'
90
-                    ),
91
-                    false,
92
-                    1
93
-                ),
94
-                'PRC_deleted'    => new EE_Trashed_Flag_Field(
95
-                    'PRC_deleted',
96
-                    esc_html__('Flag Indicating if this has been deleted or not', 'event_espresso'),
97
-                    false,
98
-                    false
99
-                ),
100
-                'PRC_parent'     => new EE_Integer_Field(
101
-                    'PRC_parent',
102
-                    esc_html__('Indicates what PRC_ID is the parent of this PRC_ID', 'event_espresso'),
103
-                    true,
104
-                    0
105
-                ),
106
-                'PRC_wp_user'    => new EE_WP_User_Field(
107
-                    'PRC_wp_user',
108
-                    esc_html__('Price Creator ID', 'event_espresso'),
109
-                    false
110
-                ),
111
-            ),
112
-        );
113
-        $this->_model_relations = array(
114
-            'Ticket'     => new EE_HABTM_Relation('Ticket_Price'),
115
-            'Price_Type' => new EE_Belongs_To_Relation(),
116
-            'WP_User'    => new EE_Belongs_To_Relation(),
117
-        );
118
-        // this model is generally available for reading
119
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] =
120
-            new EE_Restriction_Generator_Default_Public(
121
-                'PRC_is_default',
122
-                'Ticket.Datetime.Event'
123
-            );
124
-        // account for default tickets in the caps
125
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
126
-            new EE_Restriction_Generator_Default_Protected(
127
-                'PRC_is_default',
128
-                'Ticket.Datetime.Event'
129
-            );
130
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ] =
131
-            new EE_Restriction_Generator_Default_Protected(
132
-                'PRC_is_default',
133
-                'Ticket.Datetime.Event'
134
-            );
135
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ] =
136
-            new EE_Restriction_Generator_Default_Protected(
137
-                'PRC_is_default',
138
-                'Ticket.Datetime.Event'
139
-            );
140
-        parent::__construct($timezone);
141
-    }
36
+		$this->_tables = array(
37
+			'Price' => new EE_Primary_Table('esp_price', 'PRC_ID'),
38
+		);
39
+		$this->_fields = array(
40
+			'Price' => array(
41
+				'PRC_ID'         => new EE_Primary_Key_Int_Field(
42
+					'PRC_ID',
43
+					'Price ID'
44
+				),
45
+				'PRT_ID'         => new EE_Foreign_Key_Int_Field(
46
+					'PRT_ID',
47
+					esc_html__('Price type Id', 'event_espresso'),
48
+					false,
49
+					null,
50
+					'Price_Type'
51
+				),
52
+				'PRC_amount'     => new EE_Money_Field(
53
+					'PRC_amount',
54
+					esc_html__('Price Amount', 'event_espresso'),
55
+					false,
56
+					0
57
+				),
58
+				'PRC_name'       => new EE_Plain_Text_Field(
59
+					'PRC_name',
60
+					esc_html__('Name of Price', 'event_espresso'),
61
+					false,
62
+					''
63
+				),
64
+				'PRC_desc'       => new EE_Post_Content_Field(
65
+					'PRC_desc',
66
+					esc_html__('Price Description', 'event_espresso'),
67
+					false,
68
+					''
69
+				),
70
+				'PRC_is_default' => new EE_Boolean_Field(
71
+					'PRC_is_default',
72
+					esc_html__('Flag indicating whether price is a default price', 'event_espresso'),
73
+					false,
74
+					false
75
+				),
76
+				'PRC_overrides'  => new EE_Integer_Field(
77
+					'PRC_overrides',
78
+					esc_html__(
79
+						'Price ID for a global Price that will be overridden by this Price  ( for replacing default prices )',
80
+						'event_espresso'
81
+					),
82
+					true,
83
+					0
84
+				),
85
+				'PRC_order'      => new EE_Integer_Field(
86
+					'PRC_order',
87
+					esc_html__(
88
+						'Order of Application of Price (lower numbers apply first?)',
89
+						'event_espresso'
90
+					),
91
+					false,
92
+					1
93
+				),
94
+				'PRC_deleted'    => new EE_Trashed_Flag_Field(
95
+					'PRC_deleted',
96
+					esc_html__('Flag Indicating if this has been deleted or not', 'event_espresso'),
97
+					false,
98
+					false
99
+				),
100
+				'PRC_parent'     => new EE_Integer_Field(
101
+					'PRC_parent',
102
+					esc_html__('Indicates what PRC_ID is the parent of this PRC_ID', 'event_espresso'),
103
+					true,
104
+					0
105
+				),
106
+				'PRC_wp_user'    => new EE_WP_User_Field(
107
+					'PRC_wp_user',
108
+					esc_html__('Price Creator ID', 'event_espresso'),
109
+					false
110
+				),
111
+			),
112
+		);
113
+		$this->_model_relations = array(
114
+			'Ticket'     => new EE_HABTM_Relation('Ticket_Price'),
115
+			'Price_Type' => new EE_Belongs_To_Relation(),
116
+			'WP_User'    => new EE_Belongs_To_Relation(),
117
+		);
118
+		// this model is generally available for reading
119
+		$this->_cap_restriction_generators[ EEM_Base::caps_read ] =
120
+			new EE_Restriction_Generator_Default_Public(
121
+				'PRC_is_default',
122
+				'Ticket.Datetime.Event'
123
+			);
124
+		// account for default tickets in the caps
125
+		$this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
126
+			new EE_Restriction_Generator_Default_Protected(
127
+				'PRC_is_default',
128
+				'Ticket.Datetime.Event'
129
+			);
130
+		$this->_cap_restriction_generators[ EEM_Base::caps_edit ] =
131
+			new EE_Restriction_Generator_Default_Protected(
132
+				'PRC_is_default',
133
+				'Ticket.Datetime.Event'
134
+			);
135
+		$this->_cap_restriction_generators[ EEM_Base::caps_delete ] =
136
+			new EE_Restriction_Generator_Default_Protected(
137
+				'PRC_is_default',
138
+				'Ticket.Datetime.Event'
139
+			);
140
+		parent::__construct($timezone);
141
+	}
142 142
 
143 143
 
144
-    /**
145
-     * instantiate a new price object with blank/empty properties
146
-     *
147
-     * @return mixed array on success, FALSE on fail
148
-     */
149
-    public function get_new_price()
150
-    {
151
-        return $this->create_default_object();
152
-    }
144
+	/**
145
+	 * instantiate a new price object with blank/empty properties
146
+	 *
147
+	 * @return mixed array on success, FALSE on fail
148
+	 */
149
+	public function get_new_price()
150
+	{
151
+		return $this->create_default_object();
152
+	}
153 153
 
154 154
 
155
-    /**
156
-     * retrieve  ALL prices from db
157
-     *
158
-     * @return EE_Base_Class[]|EE_PRice[]
159
-     * @throws EE_Error
160
-     */
161
-    public function get_all_prices()
162
-    {
163
-        // retrieve all prices
164
-        return $this->get_all(array('order_by' => array('PRC_amount' => 'ASC')));
165
-    }
155
+	/**
156
+	 * retrieve  ALL prices from db
157
+	 *
158
+	 * @return EE_Base_Class[]|EE_PRice[]
159
+	 * @throws EE_Error
160
+	 */
161
+	public function get_all_prices()
162
+	{
163
+		// retrieve all prices
164
+		return $this->get_all(array('order_by' => array('PRC_amount' => 'ASC')));
165
+	}
166 166
 
167 167
 
168
-    /**
169
-     * retrieve all active prices for a particular event
170
-     *
171
-     * @param int $EVT_ID
172
-     * @return array on success
173
-     * @throws EE_Error
174
-     */
175
-    public function get_all_event_prices($EVT_ID = 0)
176
-    {
177
-        return $this->get_all(array(
178
-            array(
179
-                'EVT_ID'            => $EVT_ID,
180
-                'Price_Type.PBT_ID' => array('!=', EEM_Price_Type::base_type_tax),
181
-            ),
182
-            'order_by' => $this->_order_by_array_for_get_all_method(),
183
-        ));
184
-    }
168
+	/**
169
+	 * retrieve all active prices for a particular event
170
+	 *
171
+	 * @param int $EVT_ID
172
+	 * @return array on success
173
+	 * @throws EE_Error
174
+	 */
175
+	public function get_all_event_prices($EVT_ID = 0)
176
+	{
177
+		return $this->get_all(array(
178
+			array(
179
+				'EVT_ID'            => $EVT_ID,
180
+				'Price_Type.PBT_ID' => array('!=', EEM_Price_Type::base_type_tax),
181
+			),
182
+			'order_by' => $this->_order_by_array_for_get_all_method(),
183
+		));
184
+	}
185 185
 
186 186
 
187
-    /**
188
-     * retrieve all active global prices (that are not taxes (PBT_ID=4)) for a particular event
189
-     *
190
-     * @param boolean $count return count
191
-     * @param bool    $include_taxes
192
-     * @return bool|EE_Base_Class[]|EE_PRice[]
193
-     * @throws EE_Error
194
-     */
195
-    public function get_all_default_prices($count = false, $include_taxes = false)
196
-    {
197
-        $_where = array(
198
-            'PRC_deleted'       => 0,
199
-            'PRC_is_default'    => 1,
200
-        );
201
-        if (!$include_taxes) {
202
-            $_where['Price_Type.PBT_ID']  = ['!=', 4];
203
-        }
204
-        $_query_params = array(
205
-            $_where,
206
-            'order_by' => $this->_order_by_array_for_get_all_method(),
207
-        );
208
-        return $count ? $this->count(array($_where)) : $this->get_all($_query_params);
209
-    }
187
+	/**
188
+	 * retrieve all active global prices (that are not taxes (PBT_ID=4)) for a particular event
189
+	 *
190
+	 * @param boolean $count return count
191
+	 * @param bool    $include_taxes
192
+	 * @return bool|EE_Base_Class[]|EE_PRice[]
193
+	 * @throws EE_Error
194
+	 */
195
+	public function get_all_default_prices($count = false, $include_taxes = false)
196
+	{
197
+		$_where = array(
198
+			'PRC_deleted'       => 0,
199
+			'PRC_is_default'    => 1,
200
+		);
201
+		if (!$include_taxes) {
202
+			$_where['Price_Type.PBT_ID']  = ['!=', 4];
203
+		}
204
+		$_query_params = array(
205
+			$_where,
206
+			'order_by' => $this->_order_by_array_for_get_all_method(),
207
+		);
208
+		return $count ? $this->count(array($_where)) : $this->get_all($_query_params);
209
+	}
210 210
 
211 211
 
212
-    /**
213
-     * retrieve all prices that are taxes
214
-     *
215
-     * @return EE_Base_Class[]|EE_PRice[]
216
-     * @throws EE_Error
217
-     * @throws InvalidArgumentException
218
-     * @throws ReflectionException
219
-     * @throws InvalidDataTypeException
220
-     * @throws InvalidInterfaceException
221
-     */
222
-    public function get_all_prices_that_are_taxes()
223
-    {
224
-        $taxes = array();
225
-        $all_taxes = $this->get_all(array(
226
-            array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax),
227
-            'order_by' => array('Price_Type.PRT_order' => 'ASC', 'PRC_order' => 'ASC'),
228
-        ));
229
-        foreach ($all_taxes as $tax) {
230
-            if ($tax instanceof EE_Price) {
231
-                $taxes[ $tax->order() ][ $tax->ID() ] = $tax;
232
-            }
233
-        }
234
-        return $taxes;
235
-    }
212
+	/**
213
+	 * retrieve all prices that are taxes
214
+	 *
215
+	 * @return EE_Base_Class[]|EE_PRice[]
216
+	 * @throws EE_Error
217
+	 * @throws InvalidArgumentException
218
+	 * @throws ReflectionException
219
+	 * @throws InvalidDataTypeException
220
+	 * @throws InvalidInterfaceException
221
+	 */
222
+	public function get_all_prices_that_are_taxes()
223
+	{
224
+		$taxes = array();
225
+		$all_taxes = $this->get_all(array(
226
+			array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_tax),
227
+			'order_by' => array('Price_Type.PRT_order' => 'ASC', 'PRC_order' => 'ASC'),
228
+		));
229
+		foreach ($all_taxes as $tax) {
230
+			if ($tax instanceof EE_Price) {
231
+				$taxes[ $tax->order() ][ $tax->ID() ] = $tax;
232
+			}
233
+		}
234
+		return $taxes;
235
+	}
236 236
 
237 237
 
238
-    /**
239
-     * retrieve all prices for an ticket plus default global prices, but not taxes
240
-     *
241
-     * @param int $TKT_ID the id of the event.  If not included then we assume that this is a new ticket.
242
-     * @return EE_Base_Class[]|EE_PRice[]|boolean
243
-     * @throws EE_Error
244
-     */
245
-    public function get_all_ticket_prices_for_admin($TKT_ID = 0)
246
-    {
247
-        $array_of_price_objects = array();
248
-        if (empty($TKT_ID)) {
249
-            // if there is no tkt, get prices with no tkt ID, are global, are not a tax, and are active
250
-            // return that list
251
-            $default_prices = $this->get_all_default_prices();
238
+	/**
239
+	 * retrieve all prices for an ticket plus default global prices, but not taxes
240
+	 *
241
+	 * @param int $TKT_ID the id of the event.  If not included then we assume that this is a new ticket.
242
+	 * @return EE_Base_Class[]|EE_PRice[]|boolean
243
+	 * @throws EE_Error
244
+	 */
245
+	public function get_all_ticket_prices_for_admin($TKT_ID = 0)
246
+	{
247
+		$array_of_price_objects = array();
248
+		if (empty($TKT_ID)) {
249
+			// if there is no tkt, get prices with no tkt ID, are global, are not a tax, and are active
250
+			// return that list
251
+			$default_prices = $this->get_all_default_prices();
252 252
 
253
-            if ($default_prices) {
254
-                foreach ($default_prices as $price) {
255
-                    if ($price instanceof EE_Price) {
256
-                        $array_of_price_objects[ $price->type() ][] = $price;
257
-                    }
258
-                }
259
-                return $array_of_price_objects;
260
-            }
261
-            return array();
262
-        }
263
-        $ticket_prices = $this->get_all(array(
264
-            array(
265
-                'TKT_ID'      => $TKT_ID,
266
-                'PRC_deleted' => 0,
267
-            ),
268
-            'order_by' => array('PRC_order' => 'ASC'),
269
-        ));
253
+			if ($default_prices) {
254
+				foreach ($default_prices as $price) {
255
+					if ($price instanceof EE_Price) {
256
+						$array_of_price_objects[ $price->type() ][] = $price;
257
+					}
258
+				}
259
+				return $array_of_price_objects;
260
+			}
261
+			return array();
262
+		}
263
+		$ticket_prices = $this->get_all(array(
264
+			array(
265
+				'TKT_ID'      => $TKT_ID,
266
+				'PRC_deleted' => 0,
267
+			),
268
+			'order_by' => array('PRC_order' => 'ASC'),
269
+		));
270 270
 
271
-        if (! empty($ticket_prices)) {
272
-            foreach ($ticket_prices as $price) {
273
-                if ($price instanceof EE_Price) {
274
-                    $array_of_price_objects[ $price->type() ][] = $price;
275
-                }
276
-            }
277
-            return $array_of_price_objects;
278
-        }
279
-        return false;
280
-    }
271
+		if (! empty($ticket_prices)) {
272
+			foreach ($ticket_prices as $price) {
273
+				if ($price instanceof EE_Price) {
274
+					$array_of_price_objects[ $price->type() ][] = $price;
275
+				}
276
+			}
277
+			return $array_of_price_objects;
278
+		}
279
+		return false;
280
+	}
281 281
 
282 282
 
283
-    /**
284
-     * _sort_event_prices_by_type
285
-     *
286
-     * @param EE_Price $price_a
287
-     * @param EE_Price $price_b
288
-     * @return bool false on fail
289
-     */
290
-    public function _sort_event_prices_by_type(EE_Price $price_a, EE_Price $price_b)
291
-    {
292
-        if ($price_a->type_obj()->order() === $price_b->type_obj()->order()) {
293
-            return $this->_sort_event_prices_by_order($price_a, $price_b);
294
-        }
295
-        return $price_a->type_obj()->order() < $price_b->type_obj()->order() ? -1 : 1;
296
-    }
283
+	/**
284
+	 * _sort_event_prices_by_type
285
+	 *
286
+	 * @param EE_Price $price_a
287
+	 * @param EE_Price $price_b
288
+	 * @return bool false on fail
289
+	 */
290
+	public function _sort_event_prices_by_type(EE_Price $price_a, EE_Price $price_b)
291
+	{
292
+		if ($price_a->type_obj()->order() === $price_b->type_obj()->order()) {
293
+			return $this->_sort_event_prices_by_order($price_a, $price_b);
294
+		}
295
+		return $price_a->type_obj()->order() < $price_b->type_obj()->order() ? -1 : 1;
296
+	}
297 297
 
298 298
 
299
-    /**
300
-     *        _sort_event_prices_by_order
301
-     *
302
-     * @param EE_Price $price_a
303
-     * @param EE_Price $price_b
304
-     * @return bool false on fail
305
-     */
306
-    public function _sort_event_prices_by_order(EE_Price $price_a, EE_Price $price_b)
307
-    {
308
-        if ($price_a->order() === $price_b->order()) {
309
-            return 0;
310
-        }
311
-        return $price_a->order() < $price_b->order() ? -1 : 1;
312
-    }
299
+	/**
300
+	 *        _sort_event_prices_by_order
301
+	 *
302
+	 * @param EE_Price $price_a
303
+	 * @param EE_Price $price_b
304
+	 * @return bool false on fail
305
+	 */
306
+	public function _sort_event_prices_by_order(EE_Price $price_a, EE_Price $price_b)
307
+	{
308
+		if ($price_a->order() === $price_b->order()) {
309
+			return 0;
310
+		}
311
+		return $price_a->order() < $price_b->order() ? -1 : 1;
312
+	}
313 313
 
314 314
 
315
-    /**
316
-     * get all prices of a specific type
317
-     *
318
-     * @param int $type - PRT_ID
319
-     * @return EE_Base_Class[]|EE_PRice[]
320
-     * @throws EE_Error
321
-     */
322
-    public function get_all_prices_that_are_type($type = 0)
323
-    {
324
-        return $this->get_all(array(
325
-            array(
326
-                'PRT_ID' => $type,
327
-            ),
328
-            'order_by' => $this->_order_by_array_for_get_all_method(),
329
-        ));
330
-    }
315
+	/**
316
+	 * get all prices of a specific type
317
+	 *
318
+	 * @param int $type - PRT_ID
319
+	 * @return EE_Base_Class[]|EE_PRice[]
320
+	 * @throws EE_Error
321
+	 */
322
+	public function get_all_prices_that_are_type($type = 0)
323
+	{
324
+		return $this->get_all(array(
325
+			array(
326
+				'PRT_ID' => $type,
327
+			),
328
+			'order_by' => $this->_order_by_array_for_get_all_method(),
329
+		));
330
+	}
331 331
 
332 332
 
333
-    /**
334
-     * Returns an array of the normal 'order_by' query parameter provided to the get_all query.
335
-     * Of course you don't have to use it, but this is the order we usually want to sort prices by
336
-     *
337
-     * @return array which can be used like so: $this->get_all(array(array(...where
338
-     *               stuff...),'order_by'=>$this->_order_by_array_for_get_all_method()));
339
-     */
340
-    public function _order_by_array_for_get_all_method()
341
-    {
342
-        return array(
343
-            'PRC_order'            => 'ASC',
344
-            'Price_Type.PRT_order' => 'ASC',
345
-            'PRC_ID'               => 'ASC',
346
-        );
347
-    }
333
+	/**
334
+	 * Returns an array of the normal 'order_by' query parameter provided to the get_all query.
335
+	 * Of course you don't have to use it, but this is the order we usually want to sort prices by
336
+	 *
337
+	 * @return array which can be used like so: $this->get_all(array(array(...where
338
+	 *               stuff...),'order_by'=>$this->_order_by_array_for_get_all_method()));
339
+	 */
340
+	public function _order_by_array_for_get_all_method()
341
+	{
342
+		return array(
343
+			'PRC_order'            => 'ASC',
344
+			'Price_Type.PRT_order' => 'ASC',
345
+			'PRC_ID'               => 'ASC',
346
+		);
347
+	}
348 348
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -29,7 +29,7 @@  discard block
 block discarded – undo
29 29
      */
30 30
     protected function __construct($timezone)
31 31
     {
32
-        require_once(EE_MODELS . 'EEM_Price_Type.model.php');
32
+        require_once(EE_MODELS.'EEM_Price_Type.model.php');
33 33
         $this->singular_item = __('Price', 'event_espresso');
34 34
         $this->plural_item = __('Prices', 'event_espresso');
35 35
 
@@ -116,23 +116,23 @@  discard block
 block discarded – undo
116 116
             'WP_User'    => new EE_Belongs_To_Relation(),
117 117
         );
118 118
         // this model is generally available for reading
119
-        $this->_cap_restriction_generators[ EEM_Base::caps_read ] =
119
+        $this->_cap_restriction_generators[EEM_Base::caps_read] =
120 120
             new EE_Restriction_Generator_Default_Public(
121 121
                 'PRC_is_default',
122 122
                 'Ticket.Datetime.Event'
123 123
             );
124 124
         // account for default tickets in the caps
125
-        $this->_cap_restriction_generators[ EEM_Base::caps_read_admin ] =
125
+        $this->_cap_restriction_generators[EEM_Base::caps_read_admin] =
126 126
             new EE_Restriction_Generator_Default_Protected(
127 127
                 'PRC_is_default',
128 128
                 'Ticket.Datetime.Event'
129 129
             );
130
-        $this->_cap_restriction_generators[ EEM_Base::caps_edit ] =
130
+        $this->_cap_restriction_generators[EEM_Base::caps_edit] =
131 131
             new EE_Restriction_Generator_Default_Protected(
132 132
                 'PRC_is_default',
133 133
                 'Ticket.Datetime.Event'
134 134
             );
135
-        $this->_cap_restriction_generators[ EEM_Base::caps_delete ] =
135
+        $this->_cap_restriction_generators[EEM_Base::caps_delete] =
136 136
             new EE_Restriction_Generator_Default_Protected(
137 137
                 'PRC_is_default',
138 138
                 'Ticket.Datetime.Event'
@@ -198,8 +198,8 @@  discard block
 block discarded – undo
198 198
             'PRC_deleted'       => 0,
199 199
             'PRC_is_default'    => 1,
200 200
         );
201
-        if (!$include_taxes) {
202
-            $_where['Price_Type.PBT_ID']  = ['!=', 4];
201
+        if ( ! $include_taxes) {
202
+            $_where['Price_Type.PBT_ID'] = ['!=', 4];
203 203
         }
204 204
         $_query_params = array(
205 205
             $_where,
@@ -228,7 +228,7 @@  discard block
 block discarded – undo
228 228
         ));
229 229
         foreach ($all_taxes as $tax) {
230 230
             if ($tax instanceof EE_Price) {
231
-                $taxes[ $tax->order() ][ $tax->ID() ] = $tax;
231
+                $taxes[$tax->order()][$tax->ID()] = $tax;
232 232
             }
233 233
         }
234 234
         return $taxes;
@@ -253,7 +253,7 @@  discard block
 block discarded – undo
253 253
             if ($default_prices) {
254 254
                 foreach ($default_prices as $price) {
255 255
                     if ($price instanceof EE_Price) {
256
-                        $array_of_price_objects[ $price->type() ][] = $price;
256
+                        $array_of_price_objects[$price->type()][] = $price;
257 257
                     }
258 258
                 }
259 259
                 return $array_of_price_objects;
@@ -268,10 +268,10 @@  discard block
 block discarded – undo
268 268
             'order_by' => array('PRC_order' => 'ASC'),
269 269
         ));
270 270
 
271
-        if (! empty($ticket_prices)) {
271
+        if ( ! empty($ticket_prices)) {
272 272
             foreach ($ticket_prices as $price) {
273 273
                 if ($price instanceof EE_Price) {
274
-                    $array_of_price_objects[ $price->type() ][] = $price;
274
+                    $array_of_price_objects[$price->type()][] = $price;
275 275
                 }
276 276
             }
277 277
             return $array_of_price_objects;
Please login to merge, or discard this patch.
core/EE_Config.core.php 1 patch
Indentation   +3205 added lines, -3205 removed lines patch added patch discarded remove patch
@@ -14,2537 +14,2537 @@  discard block
 block discarded – undo
14 14
 final class EE_Config implements ResettableInterface
15 15
 {
16 16
 
17
-    const OPTION_NAME = 'ee_config';
18
-
19
-    const LOG_NAME = 'ee_config_log';
20
-
21
-    const LOG_LENGTH = 100;
22
-
23
-    const ADDON_OPTION_NAMES = 'ee_config_option_names';
24
-
25
-    /**
26
-     *    instance of the EE_Config object
27
-     *
28
-     * @var    EE_Config $_instance
29
-     * @access    private
30
-     */
31
-    private static $_instance;
32
-
33
-    /**
34
-     * @var boolean $_logging_enabled
35
-     */
36
-    private static $_logging_enabled = false;
37
-
38
-    /**
39
-     * @var LegacyShortcodesManager $legacy_shortcodes_manager
40
-     */
41
-    private $legacy_shortcodes_manager;
42
-
43
-    /**
44
-     * An StdClass whose property names are addon slugs,
45
-     * and values are their config classes
46
-     *
47
-     * @var StdClass
48
-     */
49
-    public $addons;
50
-
51
-    /**
52
-     * @var EE_Admin_Config
53
-     */
54
-    public $admin;
55
-
56
-    /**
57
-     * @var EE_Core_Config
58
-     */
59
-    public $core;
60
-
61
-    /**
62
-     * @var EE_Currency_Config
63
-     */
64
-    public $currency;
65
-
66
-    /**
67
-     * @var EE_Organization_Config
68
-     */
69
-    public $organization;
70
-
71
-    /**
72
-     * @var EE_Registration_Config
73
-     */
74
-    public $registration;
75
-
76
-    /**
77
-     * @var EE_Template_Config
78
-     */
79
-    public $template_settings;
80
-
81
-    /**
82
-     * Holds EE environment values.
83
-     *
84
-     * @var EE_Environment_Config
85
-     */
86
-    public $environment;
87
-
88
-    /**
89
-     * settings pertaining to Google maps
90
-     *
91
-     * @var EE_Map_Config
92
-     */
93
-    public $map_settings;
94
-
95
-    /**
96
-     * settings pertaining to Taxes
97
-     *
98
-     * @var EE_Tax_Config
99
-     */
100
-    public $tax_settings;
101
-
102
-    /**
103
-     * Settings pertaining to global messages settings.
104
-     *
105
-     * @var EE_Messages_Config
106
-     */
107
-    public $messages;
108
-
109
-    /**
110
-     * @deprecated
111
-     * @var EE_Gateway_Config
112
-     */
113
-    public $gateway;
114
-
115
-    /**
116
-     * @var    array $_addon_option_names
117
-     * @access    private
118
-     */
119
-    private $_addon_option_names = array();
120
-
121
-    /**
122
-     * @var    array $_module_route_map
123
-     * @access    private
124
-     */
125
-    private static $_module_route_map = array();
126
-
127
-    /**
128
-     * @var    array $_module_forward_map
129
-     * @access    private
130
-     */
131
-    private static $_module_forward_map = array();
132
-
133
-    /**
134
-     * @var    array $_module_view_map
135
-     * @access    private
136
-     */
137
-    private static $_module_view_map = array();
138
-
139
-
140
-    /**
141
-     * @singleton method used to instantiate class object
142
-     * @access    public
143
-     * @return EE_Config instance
144
-     */
145
-    public static function instance()
146
-    {
147
-        // check if class object is instantiated, and instantiated properly
148
-        if (! self::$_instance instanceof EE_Config) {
149
-            self::$_instance = new self();
150
-        }
151
-        return self::$_instance;
152
-    }
153
-
154
-
155
-    /**
156
-     * Resets the config
157
-     *
158
-     * @param bool    $hard_reset    if TRUE, sets EE_CONFig back to its original settings in the database. If FALSE
159
-     *                               (default) leaves the database alone, and merely resets the EE_Config object to
160
-     *                               reflect its state in the database
161
-     * @param boolean $reinstantiate if TRUE (default) call instance() and return it. Otherwise, just leave
162
-     *                               $_instance as NULL. Useful in case you want to forget about the old instance on
163
-     *                               EE_Config, but might not be ready to instantiate EE_Config currently (eg if the
164
-     *                               site was put into maintenance mode)
165
-     * @return EE_Config
166
-     */
167
-    public static function reset($hard_reset = false, $reinstantiate = true)
168
-    {
169
-        if (self::$_instance instanceof EE_Config) {
170
-            if ($hard_reset) {
171
-                self::$_instance->legacy_shortcodes_manager = null;
172
-                self::$_instance->_addon_option_names = array();
173
-                self::$_instance->_initialize_config();
174
-                self::$_instance->update_espresso_config();
175
-            }
176
-            self::$_instance->update_addon_option_names();
177
-        }
178
-        self::$_instance = null;
179
-        // we don't need to reset the static properties imo because those should
180
-        // only change when a module is added or removed. Currently we don't
181
-        // support removing a module during a request when it previously existed
182
-        if ($reinstantiate) {
183
-            return self::instance();
184
-        } else {
185
-            return null;
186
-        }
187
-    }
188
-
189
-
190
-    /**
191
-     *    class constructor
192
-     *
193
-     * @access    private
194
-     */
195
-    private function __construct()
196
-    {
197
-        do_action('AHEE__EE_Config__construct__begin', $this);
198
-        EE_Config::$_logging_enabled = apply_filters('FHEE__EE_Config___construct__logging_enabled', false);
199
-        // setup empty config classes
200
-        $this->_initialize_config();
201
-        // load existing EE site settings
202
-        $this->_load_core_config();
203
-        // confirm everything loaded correctly and set filtered defaults if not
204
-        $this->_verify_config();
205
-        //  register shortcodes and modules
206
-        add_action(
207
-            'AHEE__EE_System__register_shortcodes_modules_and_widgets',
208
-            array($this, 'register_shortcodes_and_modules'),
209
-            999
210
-        );
211
-        //  initialize shortcodes and modules
212
-        add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'initialize_shortcodes_and_modules'));
213
-        // register widgets
214
-        add_action('widgets_init', array($this, 'widgets_init'), 10);
215
-        // shutdown
216
-        add_action('shutdown', array($this, 'shutdown'), 10);
217
-        // construct__end hook
218
-        do_action('AHEE__EE_Config__construct__end', $this);
219
-        // hardcoded hack
220
-        $this->template_settings->current_espresso_theme = 'Espresso_Arabica_2014';
221
-    }
222
-
223
-
224
-    /**
225
-     * @return boolean
226
-     */
227
-    public static function logging_enabled()
228
-    {
229
-        return self::$_logging_enabled;
230
-    }
231
-
232
-
233
-    /**
234
-     * use to get the current theme if needed from static context
235
-     *
236
-     * @return string current theme set.
237
-     */
238
-    public static function get_current_theme()
239
-    {
240
-        return isset(self::$_instance->template_settings->current_espresso_theme)
241
-            ? self::$_instance->template_settings->current_espresso_theme : 'Espresso_Arabica_2014';
242
-    }
243
-
244
-
245
-    /**
246
-     *        _initialize_config
247
-     *
248
-     * @access private
249
-     * @return void
250
-     */
251
-    private function _initialize_config()
252
-    {
253
-        EE_Config::trim_log();
254
-        // set defaults
255
-        $this->_addon_option_names = get_option(EE_Config::ADDON_OPTION_NAMES, array());
256
-        $this->addons = new stdClass();
257
-        // set _module_route_map
258
-        EE_Config::$_module_route_map = array();
259
-        // set _module_forward_map
260
-        EE_Config::$_module_forward_map = array();
261
-        // set _module_view_map
262
-        EE_Config::$_module_view_map = array();
263
-    }
264
-
265
-
266
-    /**
267
-     *        load core plugin configuration
268
-     *
269
-     * @access private
270
-     * @return void
271
-     */
272
-    private function _load_core_config()
273
-    {
274
-        // load_core_config__start hook
275
-        do_action('AHEE__EE_Config___load_core_config__start', $this);
276
-        $espresso_config = $this->get_espresso_config();
277
-        foreach ($espresso_config as $config => $settings) {
278
-            // load_core_config__start hook
279
-            $settings = apply_filters(
280
-                'FHEE__EE_Config___load_core_config__config_settings',
281
-                $settings,
282
-                $config,
283
-                $this
284
-            );
285
-            if (is_object($settings) && property_exists($this, $config)) {
286
-                $this->{$config} = apply_filters('FHEE__EE_Config___load_core_config__' . $config, $settings);
287
-                // call configs populate method to ensure any defaults are set for empty values.
288
-                if (method_exists($settings, 'populate')) {
289
-                    $this->{$config}->populate();
290
-                }
291
-                if (method_exists($settings, 'do_hooks')) {
292
-                    $this->{$config}->do_hooks();
293
-                }
294
-            }
295
-        }
296
-        if (apply_filters('FHEE__EE_Config___load_core_config__update_espresso_config', false)) {
297
-            $this->update_espresso_config();
298
-        }
299
-        // load_core_config__end hook
300
-        do_action('AHEE__EE_Config___load_core_config__end', $this);
301
-    }
302
-
303
-
304
-    /**
305
-     *    _verify_config
306
-     *
307
-     * @access    protected
308
-     * @return    void
309
-     */
310
-    protected function _verify_config()
311
-    {
312
-        $this->core = $this->core instanceof EE_Core_Config
313
-            ? $this->core
314
-            : new EE_Core_Config();
315
-        $this->core = apply_filters('FHEE__EE_Config___initialize_config__core', $this->core);
316
-        $this->organization = $this->organization instanceof EE_Organization_Config
317
-            ? $this->organization
318
-            : new EE_Organization_Config();
319
-        $this->organization = apply_filters(
320
-            'FHEE__EE_Config___initialize_config__organization',
321
-            $this->organization
322
-        );
323
-        $this->currency = $this->currency instanceof EE_Currency_Config
324
-            ? $this->currency
325
-            : new EE_Currency_Config();
326
-        $this->currency = apply_filters('FHEE__EE_Config___initialize_config__currency', $this->currency);
327
-        $this->registration = $this->registration instanceof EE_Registration_Config
328
-            ? $this->registration
329
-            : new EE_Registration_Config();
330
-        $this->registration = apply_filters(
331
-            'FHEE__EE_Config___initialize_config__registration',
332
-            $this->registration
333
-        );
334
-        $this->admin = $this->admin instanceof EE_Admin_Config
335
-            ? $this->admin
336
-            : new EE_Admin_Config();
337
-        $this->admin = apply_filters('FHEE__EE_Config___initialize_config__admin', $this->admin);
338
-        $this->template_settings = $this->template_settings instanceof EE_Template_Config
339
-            ? $this->template_settings
340
-            : new EE_Template_Config();
341
-        $this->template_settings = apply_filters(
342
-            'FHEE__EE_Config___initialize_config__template_settings',
343
-            $this->template_settings
344
-        );
345
-        $this->map_settings = $this->map_settings instanceof EE_Map_Config
346
-            ? $this->map_settings
347
-            : new EE_Map_Config();
348
-        $this->map_settings = apply_filters(
349
-            'FHEE__EE_Config___initialize_config__map_settings',
350
-            $this->map_settings
351
-        );
352
-        $this->environment = $this->environment instanceof EE_Environment_Config
353
-            ? $this->environment
354
-            : new EE_Environment_Config();
355
-        $this->environment = apply_filters(
356
-            'FHEE__EE_Config___initialize_config__environment',
357
-            $this->environment
358
-        );
359
-        $this->tax_settings = $this->tax_settings instanceof EE_Tax_Config
360
-            ? $this->tax_settings
361
-            : new EE_Tax_Config();
362
-        $this->tax_settings = apply_filters(
363
-            'FHEE__EE_Config___initialize_config__tax_settings',
364
-            $this->tax_settings
365
-        );
366
-        $this->messages = apply_filters('FHEE__EE_Config__initialize_config__messages', $this->messages);
367
-        $this->messages = $this->messages instanceof EE_Messages_Config
368
-            ? $this->messages
369
-            : new EE_Messages_Config();
370
-        $this->gateway = $this->gateway instanceof EE_Gateway_Config
371
-            ? $this->gateway
372
-            : new EE_Gateway_Config();
373
-        $this->gateway = apply_filters('FHEE__EE_Config___initialize_config__gateway', $this->gateway);
374
-        $this->legacy_shortcodes_manager = null;
375
-    }
376
-
377
-
378
-    /**
379
-     *    get_espresso_config
380
-     *
381
-     * @access    public
382
-     * @return    array of espresso config stuff
383
-     */
384
-    public function get_espresso_config()
385
-    {
386
-        // grab espresso configuration
387
-        return apply_filters(
388
-            'FHEE__EE_Config__get_espresso_config__CFG',
389
-            get_option(EE_Config::OPTION_NAME, array())
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     *    double_check_config_comparison
396
-     *
397
-     * @access    public
398
-     * @param string $option
399
-     * @param        $old_value
400
-     * @param        $value
401
-     */
402
-    public function double_check_config_comparison($option = '', $old_value, $value)
403
-    {
404
-        // make sure we're checking the ee config
405
-        if ($option === EE_Config::OPTION_NAME) {
406
-            // run a loose comparison of the old value against the new value for type and properties,
407
-            // but NOT exact instance like WP update_option does (ie: NOT type safe comparison)
408
-            if ($value != $old_value) {
409
-                // if they are NOT the same, then remove the hook,
410
-                // which means the subsequent update results will be based solely on the update query results
411
-                // the reason we do this is because, as stated above,
412
-                // WP update_option performs an exact instance comparison (===) on any update values passed to it
413
-                // this happens PRIOR to serialization and any subsequent update.
414
-                // If values are found to match their previous old value,
415
-                // then WP bails before performing any update.
416
-                // Since we are passing the EE_Config object, it is comparing the EXACT instance of the saved version
417
-                // it just pulled from the db, with the one being passed to it (which will not match).
418
-                // HOWEVER, once the object is serialized and passed off to MySQL to update,
419
-                // MySQL MAY ALSO NOT perform the update because
420
-                // the string it sees in the db looks the same as the new one it has been passed!!!
421
-                // This results in the query returning an "affected rows" value of ZERO,
422
-                // which gets returned immediately by WP update_option and looks like an error.
423
-                remove_action('update_option', array($this, 'check_config_updated'));
424
-            }
425
-        }
426
-    }
427
-
428
-
429
-    /**
430
-     *    update_espresso_config
431
-     *
432
-     * @access   public
433
-     */
434
-    protected function _reset_espresso_addon_config()
435
-    {
436
-        $this->_addon_option_names = array();
437
-        foreach ($this->addons as $addon_name => $addon_config_obj) {
438
-            $addon_config_obj = maybe_unserialize($addon_config_obj);
439
-            if ($addon_config_obj instanceof EE_Config_Base) {
440
-                $this->update_config('addons', $addon_name, $addon_config_obj, false);
441
-            }
442
-            $this->addons->{$addon_name} = null;
443
-        }
444
-    }
445
-
446
-
447
-    /**
448
-     *    update_espresso_config
449
-     *
450
-     * @access   public
451
-     * @param   bool $add_success
452
-     * @param   bool $add_error
453
-     * @return   bool
454
-     */
455
-    public function update_espresso_config($add_success = false, $add_error = true)
456
-    {
457
-        // don't allow config updates during WP heartbeats
458
-        if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
459
-            return false;
460
-        }
461
-        // commented out the following re: https://events.codebasehq.com/projects/event-espresso/tickets/8197
462
-        // $clone = clone( self::$_instance );
463
-        // self::$_instance = NULL;
464
-        do_action('AHEE__EE_Config__update_espresso_config__begin', $this);
465
-        $this->_reset_espresso_addon_config();
466
-        // hook into update_option because that happens AFTER the ( $value === $old_value ) conditional
467
-        // but BEFORE the actual update occurs
468
-        add_action('update_option', array($this, 'double_check_config_comparison'), 1, 3);
469
-        // don't want to persist legacy_shortcodes_manager, but don't want to lose it either
470
-        $legacy_shortcodes_manager = $this->legacy_shortcodes_manager;
471
-        $this->legacy_shortcodes_manager = null;
472
-        // now update "ee_config"
473
-        $saved = update_option(EE_Config::OPTION_NAME, $this);
474
-        $this->legacy_shortcodes_manager = $legacy_shortcodes_manager;
475
-        EE_Config::log(EE_Config::OPTION_NAME);
476
-        // if not saved... check if the hook we just added still exists;
477
-        // if it does, it means one of two things:
478
-        // that update_option bailed at the($value === $old_value) conditional,
479
-        // or...
480
-        // the db update query returned 0 rows affected
481
-        // (probably because the data  value was the same from it's perspective)
482
-        // so the existence of the hook means that a negative result from update_option is NOT an error,
483
-        // but just means no update occurred, so don't display an error to the user.
484
-        // BUT... if update_option returns FALSE, AND the hook is missing,
485
-        // then it means that something truly went wrong
486
-        $saved = ! $saved ? has_action('update_option', array($this, 'double_check_config_comparison')) : $saved;
487
-        // remove our action since we don't want it in the system anymore
488
-        remove_action('update_option', array($this, 'double_check_config_comparison'), 1);
489
-        do_action('AHEE__EE_Config__update_espresso_config__end', $this, $saved);
490
-        // self::$_instance = $clone;
491
-        // unset( $clone );
492
-        // if config remains the same or was updated successfully
493
-        if ($saved) {
494
-            if ($add_success) {
495
-                EE_Error::add_success(
496
-                    __('The Event Espresso Configuration Settings have been successfully updated.', 'event_espresso'),
497
-                    __FILE__,
498
-                    __FUNCTION__,
499
-                    __LINE__
500
-                );
501
-            }
502
-            return true;
503
-        } else {
504
-            if ($add_error) {
505
-                EE_Error::add_error(
506
-                    __('The Event Espresso Configuration Settings were not updated.', 'event_espresso'),
507
-                    __FILE__,
508
-                    __FUNCTION__,
509
-                    __LINE__
510
-                );
511
-            }
512
-            return false;
513
-        }
514
-    }
515
-
516
-
517
-    /**
518
-     *    _verify_config_params
519
-     *
520
-     * @access    private
521
-     * @param    string         $section
522
-     * @param    string         $name
523
-     * @param    string         $config_class
524
-     * @param    EE_Config_Base $config_obj
525
-     * @param    array          $tests_to_run
526
-     * @param    bool           $display_errors
527
-     * @return    bool    TRUE on success, FALSE on fail
528
-     */
529
-    private function _verify_config_params(
530
-        $section = '',
531
-        $name = '',
532
-        $config_class = '',
533
-        $config_obj = null,
534
-        $tests_to_run = array(1, 2, 3, 4, 5, 6, 7, 8),
535
-        $display_errors = true
536
-    ) {
537
-        try {
538
-            foreach ($tests_to_run as $test) {
539
-                switch ($test) {
540
-                    // TEST #1 : check that section was set
541
-                    case 1:
542
-                        if (empty($section)) {
543
-                            if ($display_errors) {
544
-                                throw new EE_Error(
545
-                                    sprintf(
546
-                                        __(
547
-                                            'No configuration section has been provided while attempting to save "%s".',
548
-                                            'event_espresso'
549
-                                        ),
550
-                                        $config_class
551
-                                    )
552
-                                );
553
-                            }
554
-                            return false;
555
-                        }
556
-                        break;
557
-                    // TEST #2 : check that settings section exists
558
-                    case 2:
559
-                        if (! isset($this->{$section})) {
560
-                            if ($display_errors) {
561
-                                throw new EE_Error(
562
-                                    sprintf(
563
-                                        __('The "%s" configuration section does not exist.', 'event_espresso'),
564
-                                        $section
565
-                                    )
566
-                                );
567
-                            }
568
-                            return false;
569
-                        }
570
-                        break;
571
-                    // TEST #3 : check that section is the proper format
572
-                    case 3:
573
-                        if (! ($this->{$section} instanceof EE_Config_Base || $this->{$section} instanceof stdClass)
574
-                        ) {
575
-                            if ($display_errors) {
576
-                                throw new EE_Error(
577
-                                    sprintf(
578
-                                        __(
579
-                                            'The "%s" configuration settings have not been formatted correctly.',
580
-                                            'event_espresso'
581
-                                        ),
582
-                                        $section
583
-                                    )
584
-                                );
585
-                            }
586
-                            return false;
587
-                        }
588
-                        break;
589
-                    // TEST #4 : check that config section name has been set
590
-                    case 4:
591
-                        if (empty($name)) {
592
-                            if ($display_errors) {
593
-                                throw new EE_Error(
594
-                                    __(
595
-                                        'No name has been provided for the specific configuration section.',
596
-                                        'event_espresso'
597
-                                    )
598
-                                );
599
-                            }
600
-                            return false;
601
-                        }
602
-                        break;
603
-                    // TEST #5 : check that a config class name has been set
604
-                    case 5:
605
-                        if (empty($config_class)) {
606
-                            if ($display_errors) {
607
-                                throw new EE_Error(
608
-                                    __(
609
-                                        'No class name has been provided for the specific configuration section.',
610
-                                        'event_espresso'
611
-                                    )
612
-                                );
613
-                            }
614
-                            return false;
615
-                        }
616
-                        break;
617
-                    // TEST #6 : verify config class is accessible
618
-                    case 6:
619
-                        if (! class_exists($config_class)) {
620
-                            if ($display_errors) {
621
-                                throw new EE_Error(
622
-                                    sprintf(
623
-                                        __(
624
-                                            'The "%s" class does not exist. Please ensure that an autoloader has been set for it.',
625
-                                            'event_espresso'
626
-                                        ),
627
-                                        $config_class
628
-                                    )
629
-                                );
630
-                            }
631
-                            return false;
632
-                        }
633
-                        break;
634
-                    // TEST #7 : check that config has even been set
635
-                    case 7:
636
-                        if (! isset($this->{$section}->{$name})) {
637
-                            if ($display_errors) {
638
-                                throw new EE_Error(
639
-                                    sprintf(
640
-                                        __('No configuration has been set for "%1$s->%2$s".', 'event_espresso'),
641
-                                        $section,
642
-                                        $name
643
-                                    )
644
-                                );
645
-                            }
646
-                            return false;
647
-                        } else {
648
-                            // and make sure it's not serialized
649
-                            $this->{$section}->{$name} = maybe_unserialize($this->{$section}->{$name});
650
-                        }
651
-                        break;
652
-                    // TEST #8 : check that config is the requested type
653
-                    case 8:
654
-                        if (! $this->{$section}->{$name} instanceof $config_class) {
655
-                            if ($display_errors) {
656
-                                throw new EE_Error(
657
-                                    sprintf(
658
-                                        __(
659
-                                            'The configuration for "%1$s->%2$s" is not of the "%3$s" class.',
660
-                                            'event_espresso'
661
-                                        ),
662
-                                        $section,
663
-                                        $name,
664
-                                        $config_class
665
-                                    )
666
-                                );
667
-                            }
668
-                            return false;
669
-                        }
670
-                        break;
671
-                    // TEST #9 : verify config object
672
-                    case 9:
673
-                        if (! $config_obj instanceof EE_Config_Base) {
674
-                            if ($display_errors) {
675
-                                throw new EE_Error(
676
-                                    sprintf(
677
-                                        __('The "%s" class is not an instance of EE_Config_Base.', 'event_espresso'),
678
-                                        print_r($config_obj, true)
679
-                                    )
680
-                                );
681
-                            }
682
-                            return false;
683
-                        }
684
-                        break;
685
-                }
686
-            }
687
-        } catch (EE_Error $e) {
688
-            $e->get_error();
689
-        }
690
-        // you have successfully run the gauntlet
691
-        return true;
692
-    }
693
-
694
-
695
-    /**
696
-     *    _generate_config_option_name
697
-     *
698
-     * @access        protected
699
-     * @param        string $section
700
-     * @param        string $name
701
-     * @return        string
702
-     */
703
-    private function _generate_config_option_name($section = '', $name = '')
704
-    {
705
-        return 'ee_config-' . strtolower($section . '-' . str_replace(array('EE_', 'EED_'), '', $name));
706
-    }
707
-
708
-
709
-    /**
710
-     *    _set_config_class
711
-     * ensures that a config class is set, either from a passed config class or one generated from the config name
712
-     *
713
-     * @access    private
714
-     * @param    string $config_class
715
-     * @param    string $name
716
-     * @return    string
717
-     */
718
-    private function _set_config_class($config_class = '', $name = '')
719
-    {
720
-        return ! empty($config_class)
721
-            ? $config_class
722
-            : str_replace(' ', '_', ucwords(str_replace('_', ' ', $name))) . '_Config';
723
-    }
724
-
725
-
726
-    /**
727
-     *    set_config
728
-     *
729
-     * @access    protected
730
-     * @param    string         $section
731
-     * @param    string         $name
732
-     * @param    string         $config_class
733
-     * @param    EE_Config_Base $config_obj
734
-     * @return    EE_Config_Base
735
-     */
736
-    public function set_config($section = '', $name = '', $config_class = '', EE_Config_Base $config_obj = null)
737
-    {
738
-        // ensure config class is set to something
739
-        $config_class = $this->_set_config_class($config_class, $name);
740
-        // run tests 1-4, 6, and 7 to verify all config params are set and valid
741
-        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
742
-            return null;
743
-        }
744
-        $config_option_name = $this->_generate_config_option_name($section, $name);
745
-        // if the config option name hasn't been added yet to the list of option names we're tracking, then do so now
746
-        if (! isset($this->_addon_option_names[ $config_option_name ])) {
747
-            $this->_addon_option_names[ $config_option_name ] = $config_class;
748
-            $this->update_addon_option_names();
749
-        }
750
-        // verify the incoming config object but suppress errors
751
-        if (! $this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
752
-            $config_obj = new $config_class();
753
-        }
754
-        if (get_option($config_option_name)) {
755
-            EE_Config::log($config_option_name);
756
-            update_option($config_option_name, $config_obj);
757
-            $this->{$section}->{$name} = $config_obj;
758
-            return $this->{$section}->{$name};
759
-        } else {
760
-            // create a wp-option for this config
761
-            if (add_option($config_option_name, $config_obj, '', 'no')) {
762
-                $this->{$section}->{$name} = maybe_unserialize($config_obj);
763
-                return $this->{$section}->{$name};
764
-            } else {
765
-                EE_Error::add_error(
766
-                    sprintf(__('The "%s" could not be saved to the database.', 'event_espresso'), $config_class),
767
-                    __FILE__,
768
-                    __FUNCTION__,
769
-                    __LINE__
770
-                );
771
-                return null;
772
-            }
773
-        }
774
-    }
775
-
776
-
777
-    /**
778
-     *    update_config
779
-     * Important: the config object must ALREADY be set, otherwise this will produce an error.
780
-     *
781
-     * @access    public
782
-     * @param    string                $section
783
-     * @param    string                $name
784
-     * @param    EE_Config_Base|string $config_obj
785
-     * @param    bool                  $throw_errors
786
-     * @return    bool
787
-     */
788
-    public function update_config($section = '', $name = '', $config_obj = '', $throw_errors = true)
789
-    {
790
-        // don't allow config updates during WP heartbeats
791
-        if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
792
-            return false;
793
-        }
794
-        $config_obj = maybe_unserialize($config_obj);
795
-        // get class name of the incoming object
796
-        $config_class = get_class($config_obj);
797
-        // run tests 1-5 and 9 to verify config
798
-        if (! $this->_verify_config_params(
799
-            $section,
800
-            $name,
801
-            $config_class,
802
-            $config_obj,
803
-            array(1, 2, 3, 4, 7, 9)
804
-        )
805
-        ) {
806
-            return false;
807
-        }
808
-        $config_option_name = $this->_generate_config_option_name($section, $name);
809
-        // check if config object has been added to db by seeing if config option name is in $this->_addon_option_names array
810
-        if (! isset($this->_addon_option_names[ $config_option_name ])) {
811
-            // save new config to db
812
-            if ($this->set_config($section, $name, $config_class, $config_obj)) {
813
-                return true;
814
-            }
815
-        } else {
816
-            // first check if the record already exists
817
-            $existing_config = get_option($config_option_name);
818
-            $config_obj = serialize($config_obj);
819
-            // just return if db record is already up to date (NOT type safe comparison)
820
-            if ($existing_config == $config_obj) {
821
-                $this->{$section}->{$name} = $config_obj;
822
-                return true;
823
-            } elseif (update_option($config_option_name, $config_obj)) {
824
-                EE_Config::log($config_option_name);
825
-                // update wp-option for this config class
826
-                $this->{$section}->{$name} = $config_obj;
827
-                return true;
828
-            } elseif ($throw_errors) {
829
-                EE_Error::add_error(
830
-                    sprintf(
831
-                        __(
832
-                            'The "%1$s" object stored at"%2$s" was not successfully updated in the database.',
833
-                            'event_espresso'
834
-                        ),
835
-                        $config_class,
836
-                        'EE_Config->' . $section . '->' . $name
837
-                    ),
838
-                    __FILE__,
839
-                    __FUNCTION__,
840
-                    __LINE__
841
-                );
842
-            }
843
-        }
844
-        return false;
845
-    }
846
-
847
-
848
-    /**
849
-     *    get_config
850
-     *
851
-     * @access    public
852
-     * @param    string $section
853
-     * @param    string $name
854
-     * @param    string $config_class
855
-     * @return    mixed EE_Config_Base | NULL
856
-     */
857
-    public function get_config($section = '', $name = '', $config_class = '')
858
-    {
859
-        // ensure config class is set to something
860
-        $config_class = $this->_set_config_class($config_class, $name);
861
-        // run tests 1-4, 6 and 7 to verify that all params have been set
862
-        if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
863
-            return null;
864
-        }
865
-        // now test if the requested config object exists, but suppress errors
866
-        if ($this->_verify_config_params($section, $name, $config_class, null, array(7, 8), false)) {
867
-            // config already exists, so pass it back
868
-            return $this->{$section}->{$name};
869
-        }
870
-        // load config option from db if it exists
871
-        $config_obj = $this->get_config_option($this->_generate_config_option_name($section, $name));
872
-        // verify the newly retrieved config object, but suppress errors
873
-        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
874
-            // config is good, so set it and pass it back
875
-            $this->{$section}->{$name} = $config_obj;
876
-            return $this->{$section}->{$name};
877
-        }
878
-        // oops! $config_obj is not already set and does not exist in the db, so create a new one
879
-        $config_obj = $this->set_config($section, $name, $config_class);
880
-        // verify the newly created config object
881
-        if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9))) {
882
-            return $this->{$section}->{$name};
883
-        } else {
884
-            EE_Error::add_error(
885
-                sprintf(__('The "%s" could not be retrieved from the database.', 'event_espresso'), $config_class),
886
-                __FILE__,
887
-                __FUNCTION__,
888
-                __LINE__
889
-            );
890
-        }
891
-        return null;
892
-    }
893
-
894
-
895
-    /**
896
-     *    get_config_option
897
-     *
898
-     * @access    public
899
-     * @param    string $config_option_name
900
-     * @return    mixed EE_Config_Base | FALSE
901
-     */
902
-    public function get_config_option($config_option_name = '')
903
-    {
904
-        // retrieve the wp-option for this config class.
905
-        $config_option = maybe_unserialize(get_option($config_option_name, array()));
906
-        if (empty($config_option)) {
907
-            EE_Config::log($config_option_name . '-NOT-FOUND');
908
-        }
909
-        return $config_option;
910
-    }
911
-
912
-
913
-    /**
914
-     * log
915
-     *
916
-     * @param string $config_option_name
917
-     */
918
-    public static function log($config_option_name = '')
919
-    {
920
-        if (EE_Config::logging_enabled() && ! empty($config_option_name)) {
921
-            $config_log = get_option(EE_Config::LOG_NAME, array());
922
-            // copy incoming $_REQUEST and sanitize it so we can save it
923
-            $_request = $_REQUEST;
924
-            array_walk_recursive($_request, 'sanitize_text_field');
925
-            $config_log[ (string) microtime(true) ] = array(
926
-                'config_name' => $config_option_name,
927
-                'request'     => $_request,
928
-            );
929
-            update_option(EE_Config::LOG_NAME, $config_log);
930
-        }
931
-    }
932
-
933
-
934
-    /**
935
-     * trim_log
936
-     * reduces the size of the config log to the length specified by EE_Config::LOG_LENGTH
937
-     */
938
-    public static function trim_log()
939
-    {
940
-        if (! EE_Config::logging_enabled()) {
941
-            return;
942
-        }
943
-        $config_log = maybe_unserialize(get_option(EE_Config::LOG_NAME, array()));
944
-        $log_length = count($config_log);
945
-        if ($log_length > EE_Config::LOG_LENGTH) {
946
-            ksort($config_log);
947
-            $config_log = array_slice($config_log, $log_length - EE_Config::LOG_LENGTH, null, true);
948
-            update_option(EE_Config::LOG_NAME, $config_log);
949
-        }
950
-    }
951
-
952
-
953
-    /**
954
-     *    get_page_for_posts
955
-     *    if the wp-option "show_on_front" is set to "page", then this is the post_name for the post set in the
956
-     *    wp-option "page_for_posts", or "posts" if no page is selected
957
-     *
958
-     * @access    public
959
-     * @return    string
960
-     */
961
-    public static function get_page_for_posts()
962
-    {
963
-        $page_for_posts = get_option('page_for_posts');
964
-        if (! $page_for_posts) {
965
-            return 'posts';
966
-        }
967
-        /** @type WPDB $wpdb */
968
-        global $wpdb;
969
-        $SQL = "SELECT post_name from $wpdb->posts WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
970
-        return $wpdb->get_var($wpdb->prepare($SQL, $page_for_posts));
971
-    }
972
-
973
-
974
-    /**
975
-     *    register_shortcodes_and_modules.
976
-     *    At this point, it's too early to tell if we're maintenance mode or not.
977
-     *    In fact, this is where we give modules a chance to let core know they exist
978
-     *    so they can help trigger maintenance mode if it's needed
979
-     *
980
-     * @access    public
981
-     * @return    void
982
-     */
983
-    public function register_shortcodes_and_modules()
984
-    {
985
-        // allow modules to set hooks for the rest of the system
986
-        EE_Registry::instance()->modules = $this->_register_modules();
987
-    }
988
-
989
-
990
-    /**
991
-     *    initialize_shortcodes_and_modules
992
-     *    meaning they can start adding their hooks to get stuff done
993
-     *
994
-     * @access    public
995
-     * @return    void
996
-     */
997
-    public function initialize_shortcodes_and_modules()
998
-    {
999
-        // allow modules to set hooks for the rest of the system
1000
-        $this->_initialize_modules();
1001
-    }
1002
-
1003
-
1004
-    /**
1005
-     *    widgets_init
1006
-     *
1007
-     * @access private
1008
-     * @return void
1009
-     */
1010
-    public function widgets_init()
1011
-    {
1012
-        // only init widgets on admin pages when not in complete maintenance, and
1013
-        // on frontend when not in any maintenance mode
1014
-        if (! EE_Maintenance_Mode::instance()->level()
1015
-            || (
1016
-                is_admin()
1017
-                && EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance
1018
-            )
1019
-        ) {
1020
-            // grab list of installed widgets
1021
-            $widgets_to_register = glob(EE_WIDGETS . '*', GLOB_ONLYDIR);
1022
-            // filter list of modules to register
1023
-            $widgets_to_register = apply_filters(
1024
-                'FHEE__EE_Config__register_widgets__widgets_to_register',
1025
-                $widgets_to_register
1026
-            );
1027
-            if (! empty($widgets_to_register)) {
1028
-                // cycle thru widget folders
1029
-                foreach ($widgets_to_register as $widget_path) {
1030
-                    // add to list of installed widget modules
1031
-                    EE_Config::register_ee_widget($widget_path);
1032
-                }
1033
-            }
1034
-            // filter list of installed modules
1035
-            EE_Registry::instance()->widgets = apply_filters(
1036
-                'FHEE__EE_Config__register_widgets__installed_widgets',
1037
-                EE_Registry::instance()->widgets
1038
-            );
1039
-        }
1040
-    }
1041
-
1042
-
1043
-    /**
1044
-     *    register_ee_widget - makes core aware of this widget
1045
-     *
1046
-     * @access    public
1047
-     * @param    string $widget_path - full path up to and including widget folder
1048
-     * @return    void
1049
-     */
1050
-    public static function register_ee_widget($widget_path = null)
1051
-    {
1052
-        do_action('AHEE__EE_Config__register_widget__begin', $widget_path);
1053
-        $widget_ext = '.widget.php';
1054
-        // make all separators match
1055
-        $widget_path = rtrim(str_replace('\\', DS, $widget_path), DS);
1056
-        // does the file path INCLUDE the actual file name as part of the path ?
1057
-        if (strpos($widget_path, $widget_ext) !== false) {
1058
-            // grab and shortcode file name from directory name and break apart at dots
1059
-            $file_name = explode('.', basename($widget_path));
1060
-            // take first segment from file name pieces and remove class prefix if it exists
1061
-            $widget = strpos($file_name[0], 'EEW_') === 0 ? substr($file_name[0], 4) : $file_name[0];
1062
-            // sanitize shortcode directory name
1063
-            $widget = sanitize_key($widget);
1064
-            // now we need to rebuild the shortcode path
1065
-            $widget_path = explode('/', $widget_path);
1066
-            // remove last segment
1067
-            array_pop($widget_path);
1068
-            // glue it back together
1069
-            $widget_path = implode(DS, $widget_path);
1070
-        } else {
1071
-            // grab and sanitize widget directory name
1072
-            $widget = sanitize_key(basename($widget_path));
1073
-        }
1074
-        // create classname from widget directory name
1075
-        $widget = str_replace(' ', '_', ucwords(str_replace('_', ' ', $widget)));
1076
-        // add class prefix
1077
-        $widget_class = 'EEW_' . $widget;
1078
-        // does the widget exist ?
1079
-        if (! is_readable($widget_path . '/' . $widget_class . $widget_ext)) {
1080
-            $msg = sprintf(
1081
-                __(
1082
-                    'The requested %s widget file could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
1083
-                    'event_espresso'
1084
-                ),
1085
-                $widget_class,
1086
-                $widget_path . '/' . $widget_class . $widget_ext
1087
-            );
1088
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1089
-            return;
1090
-        }
1091
-        // load the widget class file
1092
-        require_once($widget_path . '/' . $widget_class . $widget_ext);
1093
-        // verify that class exists
1094
-        if (! class_exists($widget_class)) {
1095
-            $msg = sprintf(__('The requested %s widget class does not exist.', 'event_espresso'), $widget_class);
1096
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1097
-            return;
1098
-        }
1099
-        register_widget($widget_class);
1100
-        // add to array of registered widgets
1101
-        EE_Registry::instance()->widgets->{$widget_class} = $widget_path . '/' . $widget_class . $widget_ext;
1102
-    }
1103
-
1104
-
1105
-    /**
1106
-     *        _register_modules
1107
-     *
1108
-     * @access private
1109
-     * @return array
1110
-     */
1111
-    private function _register_modules()
1112
-    {
1113
-        // grab list of installed modules
1114
-        $modules_to_register = glob(EE_MODULES . '*', GLOB_ONLYDIR);
1115
-        // filter list of modules to register
1116
-        $modules_to_register = apply_filters(
1117
-            'FHEE__EE_Config__register_modules__modules_to_register',
1118
-            $modules_to_register
1119
-        );
1120
-        if (! empty($modules_to_register)) {
1121
-            // loop through folders
1122
-            foreach ($modules_to_register as $module_path) {
1123
-                /**TEMPORARILY EXCLUDE gateways from modules for time being**/
1124
-                if ($module_path !== EE_MODULES . 'zzz-copy-this-module-template'
1125
-                    && $module_path !== EE_MODULES . 'gateways'
1126
-                ) {
1127
-                    // add to list of installed modules
1128
-                    EE_Config::register_module($module_path);
1129
-                }
1130
-            }
1131
-        }
1132
-        // filter list of installed modules
1133
-        return apply_filters(
1134
-            'FHEE__EE_Config___register_modules__installed_modules',
1135
-            EE_Registry::instance()->modules
1136
-        );
1137
-    }
1138
-
1139
-
1140
-    /**
1141
-     *    register_module - makes core aware of this module
1142
-     *
1143
-     * @access    public
1144
-     * @param    string $module_path - full path up to and including module folder
1145
-     * @return    bool
1146
-     */
1147
-    public static function register_module($module_path = null)
1148
-    {
1149
-        do_action('AHEE__EE_Config__register_module__begin', $module_path);
1150
-        $module_ext = '.module.php';
1151
-        // make all separators match
1152
-        $module_path = str_replace(array('\\', '/'), '/', $module_path);
1153
-        // does the file path INCLUDE the actual file name as part of the path ?
1154
-        if (strpos($module_path, $module_ext) !== false) {
1155
-            // grab and shortcode file name from directory name and break apart at dots
1156
-            $module_file = explode('.', basename($module_path));
1157
-            // now we need to rebuild the shortcode path
1158
-            $module_path = explode('/', $module_path);
1159
-            // remove last segment
1160
-            array_pop($module_path);
1161
-            // glue it back together
1162
-            $module_path = implode('/', $module_path) . '/';
1163
-            // take first segment from file name pieces and sanitize it
1164
-            $module = preg_replace('/[^a-zA-Z0-9_\-]/', '', $module_file[0]);
1165
-            // ensure class prefix is added
1166
-            $module_class = strpos($module, 'EED_') !== 0 ? 'EED_' . $module : $module;
1167
-        } else {
1168
-            // we need to generate the filename based off of the folder name
1169
-            // grab and sanitize module name
1170
-            $module = strtolower(basename($module_path));
1171
-            $module = preg_replace('/[^a-z0-9_\-]/', '', $module);
1172
-            // like trailingslashit()
1173
-            $module_path = rtrim($module_path, '/') . '/';
1174
-            // create classname from module directory name
1175
-            $module = str_replace(' ', '_', ucwords(str_replace('_', ' ', $module)));
1176
-            // add class prefix
1177
-            $module_class = 'EED_' . $module;
1178
-        }
1179
-        // does the module exist ?
1180
-        if (! is_readable($module_path . '/' . $module_class . $module_ext)) {
1181
-            $msg = sprintf(
1182
-                __(
1183
-                    'The requested %s module file could not be found or is not readable due to file permissions.',
1184
-                    'event_espresso'
1185
-                ),
1186
-                $module
1187
-            );
1188
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1189
-            return false;
1190
-        }
1191
-        // load the module class file
1192
-        require_once($module_path . $module_class . $module_ext);
1193
-        // verify that class exists
1194
-        if (! class_exists($module_class)) {
1195
-            $msg = sprintf(__('The requested %s module class does not exist.', 'event_espresso'), $module_class);
1196
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1197
-            return false;
1198
-        }
1199
-        // add to array of registered modules
1200
-        EE_Registry::instance()->modules->{$module_class} = $module_path . $module_class . $module_ext;
1201
-        do_action(
1202
-            'AHEE__EE_Config__register_module__complete',
1203
-            $module_class,
1204
-            EE_Registry::instance()->modules->{$module_class}
1205
-        );
1206
-        return true;
1207
-    }
1208
-
1209
-
1210
-    /**
1211
-     *    _initialize_modules
1212
-     *    allow modules to set hooks for the rest of the system
1213
-     *
1214
-     * @access private
1215
-     * @return void
1216
-     */
1217
-    private function _initialize_modules()
1218
-    {
1219
-        // cycle thru shortcode folders
1220
-        foreach (EE_Registry::instance()->modules as $module_class => $module_path) {
1221
-            // fire the shortcode class's set_hooks methods in case it needs to hook into other parts of the system
1222
-            // which set hooks ?
1223
-            if (is_admin()) {
1224
-                // fire immediately
1225
-                call_user_func(array($module_class, 'set_hooks_admin'));
1226
-            } else {
1227
-                // delay until other systems are online
1228
-                add_action(
1229
-                    'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons',
1230
-                    array($module_class, 'set_hooks')
1231
-                );
1232
-            }
1233
-        }
1234
-    }
1235
-
1236
-
1237
-    /**
1238
-     *    register_route - adds module method routes to route_map
1239
-     *
1240
-     * @access    public
1241
-     * @param    string $route       - "pretty" public alias for module method
1242
-     * @param    string $module      - module name (classname without EED_ prefix)
1243
-     * @param    string $method_name - the actual module method to be routed to
1244
-     * @param    string $key         - url param key indicating a route is being called
1245
-     * @return    bool
1246
-     */
1247
-    public static function register_route($route = null, $module = null, $method_name = null, $key = 'ee')
1248
-    {
1249
-        do_action('AHEE__EE_Config__register_route__begin', $route, $module, $method_name);
1250
-        $module = str_replace('EED_', '', $module);
1251
-        $module_class = 'EED_' . $module;
1252
-        if (! isset(EE_Registry::instance()->modules->{$module_class})) {
1253
-            $msg = sprintf(__('The module %s has not been registered.', 'event_espresso'), $module);
1254
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1255
-            return false;
1256
-        }
1257
-        if (empty($route)) {
1258
-            $msg = sprintf(__('No route has been supplied.', 'event_espresso'), $route);
1259
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1260
-            return false;
1261
-        }
1262
-        if (! method_exists('EED_' . $module, $method_name)) {
1263
-            $msg = sprintf(
1264
-                __('A valid class method for the %s route has not been supplied.', 'event_espresso'),
1265
-                $route
1266
-            );
1267
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1268
-            return false;
1269
-        }
1270
-        EE_Config::$_module_route_map[ (string) $key ][ (string) $route ] = array('EED_' . $module, $method_name);
1271
-        return true;
1272
-    }
1273
-
1274
-
1275
-    /**
1276
-     *    get_route - get module method route
1277
-     *
1278
-     * @access    public
1279
-     * @param    string $route - "pretty" public alias for module method
1280
-     * @param    string $key   - url param key indicating a route is being called
1281
-     * @return    string
1282
-     */
1283
-    public static function get_route($route = null, $key = 'ee')
1284
-    {
1285
-        do_action('AHEE__EE_Config__get_route__begin', $route);
1286
-        $route = (string) apply_filters('FHEE__EE_Config__get_route', $route);
1287
-        if (isset(EE_Config::$_module_route_map[ $key ][ $route ])) {
1288
-            return EE_Config::$_module_route_map[ $key ][ $route ];
1289
-        }
1290
-        return null;
1291
-    }
1292
-
1293
-
1294
-    /**
1295
-     *    get_routes - get ALL module method routes
1296
-     *
1297
-     * @access    public
1298
-     * @return    array
1299
-     */
1300
-    public static function get_routes()
1301
-    {
1302
-        return EE_Config::$_module_route_map;
1303
-    }
1304
-
1305
-
1306
-    /**
1307
-     *    register_forward - allows modules to forward request to another module for further processing
1308
-     *
1309
-     * @access    public
1310
-     * @param    string       $route   - "pretty" public alias for module method
1311
-     * @param    integer      $status  - integer value corresponding  to status constant strings set in module parent
1312
-     *                                 class, allows different forwards to be served based on status
1313
-     * @param    array|string $forward - function name or array( class, method )
1314
-     * @param    string       $key     - url param key indicating a route is being called
1315
-     * @return    bool
1316
-     */
1317
-    public static function register_forward($route = null, $status = 0, $forward = null, $key = 'ee')
1318
-    {
1319
-        do_action('AHEE__EE_Config__register_forward', $route, $status, $forward);
1320
-        if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1321
-            $msg = sprintf(
1322
-                __('The module route %s for this forward has not been registered.', 'event_espresso'),
1323
-                $route
1324
-            );
1325
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1326
-            return false;
1327
-        }
1328
-        if (empty($forward)) {
1329
-            $msg = sprintf(__('No forwarding route has been supplied.', 'event_espresso'), $route);
1330
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1331
-            return false;
1332
-        }
1333
-        if (is_array($forward)) {
1334
-            if (! isset($forward[1])) {
1335
-                $msg = sprintf(
1336
-                    __('A class method for the %s forwarding route has not been supplied.', 'event_espresso'),
1337
-                    $route
1338
-                );
1339
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1340
-                return false;
1341
-            }
1342
-            if (! method_exists($forward[0], $forward[1])) {
1343
-                $msg = sprintf(
1344
-                    __('The class method %s for the %s forwarding route is in invalid.', 'event_espresso'),
1345
-                    $forward[1],
1346
-                    $route
1347
-                );
1348
-                EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1349
-                return false;
1350
-            }
1351
-        } elseif (! function_exists($forward)) {
1352
-            $msg = sprintf(
1353
-                __('The function %s for the %s forwarding route is in invalid.', 'event_espresso'),
1354
-                $forward,
1355
-                $route
1356
-            );
1357
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1358
-            return false;
1359
-        }
1360
-        EE_Config::$_module_forward_map[ $key ][ $route ][ absint($status) ] = $forward;
1361
-        return true;
1362
-    }
1363
-
1364
-
1365
-    /**
1366
-     *    get_forward - get forwarding route
1367
-     *
1368
-     * @access    public
1369
-     * @param    string  $route  - "pretty" public alias for module method
1370
-     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1371
-     *                           allows different forwards to be served based on status
1372
-     * @param    string  $key    - url param key indicating a route is being called
1373
-     * @return    string
1374
-     */
1375
-    public static function get_forward($route = null, $status = 0, $key = 'ee')
1376
-    {
1377
-        do_action('AHEE__EE_Config__get_forward__begin', $route, $status);
1378
-        if (isset(EE_Config::$_module_forward_map[ $key ][ $route ][ $status ])) {
1379
-            return apply_filters(
1380
-                'FHEE__EE_Config__get_forward',
1381
-                EE_Config::$_module_forward_map[ $key ][ $route ][ $status ],
1382
-                $route,
1383
-                $status
1384
-            );
1385
-        }
1386
-        return null;
1387
-    }
1388
-
1389
-
1390
-    /**
1391
-     *    register_forward - allows modules to specify different view templates for different method routes and status
1392
-     *    results
1393
-     *
1394
-     * @access    public
1395
-     * @param    string  $route  - "pretty" public alias for module method
1396
-     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1397
-     *                           allows different views to be served based on status
1398
-     * @param    string  $view
1399
-     * @param    string  $key    - url param key indicating a route is being called
1400
-     * @return    bool
1401
-     */
1402
-    public static function register_view($route = null, $status = 0, $view = null, $key = 'ee')
1403
-    {
1404
-        do_action('AHEE__EE_Config__register_view__begin', $route, $status, $view);
1405
-        if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1406
-            $msg = sprintf(
1407
-                __('The module route %s for this view has not been registered.', 'event_espresso'),
1408
-                $route
1409
-            );
1410
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1411
-            return false;
1412
-        }
1413
-        if (! is_readable($view)) {
1414
-            $msg = sprintf(
1415
-                __(
1416
-                    'The %s view file could not be found or is not readable due to file permissions.',
1417
-                    'event_espresso'
1418
-                ),
1419
-                $view
1420
-            );
1421
-            EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1422
-            return false;
1423
-        }
1424
-        EE_Config::$_module_view_map[ $key ][ $route ][ absint($status) ] = $view;
1425
-        return true;
1426
-    }
1427
-
1428
-
1429
-    /**
1430
-     *    get_view - get view for route and status
1431
-     *
1432
-     * @access    public
1433
-     * @param    string  $route  - "pretty" public alias for module method
1434
-     * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1435
-     *                           allows different views to be served based on status
1436
-     * @param    string  $key    - url param key indicating a route is being called
1437
-     * @return    string
1438
-     */
1439
-    public static function get_view($route = null, $status = 0, $key = 'ee')
1440
-    {
1441
-        do_action('AHEE__EE_Config__get_view__begin', $route, $status);
1442
-        if (isset(EE_Config::$_module_view_map[ $key ][ $route ][ $status ])) {
1443
-            return apply_filters(
1444
-                'FHEE__EE_Config__get_view',
1445
-                EE_Config::$_module_view_map[ $key ][ $route ][ $status ],
1446
-                $route,
1447
-                $status
1448
-            );
1449
-        }
1450
-        return null;
1451
-    }
1452
-
1453
-
1454
-    public function update_addon_option_names()
1455
-    {
1456
-        update_option(EE_Config::ADDON_OPTION_NAMES, $this->_addon_option_names);
1457
-    }
1458
-
1459
-
1460
-    public function shutdown()
1461
-    {
1462
-        $this->update_addon_option_names();
1463
-    }
1464
-
1465
-
1466
-    /**
1467
-     * @return LegacyShortcodesManager
1468
-     */
1469
-    public static function getLegacyShortcodesManager()
1470
-    {
1471
-
1472
-        if (! EE_Config::instance()->legacy_shortcodes_manager instanceof LegacyShortcodesManager) {
1473
-            EE_Config::instance()->legacy_shortcodes_manager = new LegacyShortcodesManager(
1474
-                EE_Registry::instance()
1475
-            );
1476
-        }
1477
-        return EE_Config::instance()->legacy_shortcodes_manager;
1478
-    }
1479
-
1480
-
1481
-    /**
1482
-     * register_shortcode - makes core aware of this shortcode
1483
-     *
1484
-     * @deprecated 4.9.26
1485
-     * @param    string $shortcode_path - full path up to and including shortcode folder
1486
-     * @return    bool
1487
-     */
1488
-    public static function register_shortcode($shortcode_path = null)
1489
-    {
1490
-        EE_Error::doing_it_wrong(
1491
-            __METHOD__,
1492
-            __(
1493
-                'Usage is deprecated. Use \EventEspresso\core\services\shortcodes\LegacyShortcodesManager::registerShortcode() as direct replacement, or better yet, please see the new \EventEspresso\core\services\shortcodes\ShortcodesManager class.',
1494
-                'event_espresso'
1495
-            ),
1496
-            '4.9.26'
1497
-        );
1498
-        return EE_Config::instance()->getLegacyShortcodesManager()->registerShortcode($shortcode_path);
1499
-    }
1500
-}
1501
-
1502
-/**
1503
- * Base class used for config classes. These classes should generally not have
1504
- * magic functions in use, except we'll allow them to magically set and get stuff...
1505
- * basically, they should just be well-defined stdClasses
1506
- */
1507
-class EE_Config_Base
1508
-{
1509
-
1510
-    /**
1511
-     * Utility function for escaping the value of a property and returning.
1512
-     *
1513
-     * @param string $property property name (checks to see if exists).
1514
-     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1515
-     * @throws \EE_Error
1516
-     */
1517
-    public function get_pretty($property)
1518
-    {
1519
-        if (! property_exists($this, $property)) {
1520
-            throw new EE_Error(
1521
-                sprintf(
1522
-                    __(
1523
-                        '%1$s::get_pretty() has been called with the property %2$s which does not exist on the %1$s config class.',
1524
-                        'event_espresso'
1525
-                    ),
1526
-                    get_class($this),
1527
-                    $property
1528
-                )
1529
-            );
1530
-        }
1531
-        // just handling escaping of strings for now.
1532
-        if (is_string($this->{$property})) {
1533
-            return stripslashes($this->{$property});
1534
-        }
1535
-        return $this->{$property};
1536
-    }
1537
-
1538
-
1539
-    public function populate()
1540
-    {
1541
-        // grab defaults via a new instance of this class.
1542
-        $class_name = get_class($this);
1543
-        $defaults = new $class_name;
1544
-        // loop through the properties for this class and see if they are set.  If they are NOT, then grab the
1545
-        // default from our $defaults object.
1546
-        foreach (get_object_vars($defaults) as $property => $value) {
1547
-            if ($this->{$property} === null) {
1548
-                $this->{$property} = $value;
1549
-            }
1550
-        }
1551
-        // cleanup
1552
-        unset($defaults);
1553
-    }
1554
-
1555
-
1556
-    /**
1557
-     *        __isset
1558
-     *
1559
-     * @param $a
1560
-     * @return bool
1561
-     */
1562
-    public function __isset($a)
1563
-    {
1564
-        return false;
1565
-    }
1566
-
1567
-
1568
-    /**
1569
-     *        __unset
1570
-     *
1571
-     * @param $a
1572
-     * @return bool
1573
-     */
1574
-    public function __unset($a)
1575
-    {
1576
-        return false;
1577
-    }
1578
-
1579
-
1580
-    /**
1581
-     *        __clone
1582
-     */
1583
-    public function __clone()
1584
-    {
1585
-    }
1586
-
1587
-
1588
-    /**
1589
-     *        __wakeup
1590
-     */
1591
-    public function __wakeup()
1592
-    {
1593
-    }
1594
-
1595
-
1596
-    /**
1597
-     *        __destruct
1598
-     */
1599
-    public function __destruct()
1600
-    {
1601
-    }
1602
-}
1603
-
1604
-/**
1605
- * Class for defining what's in the EE_Config relating to registration settings
1606
- */
1607
-class EE_Core_Config extends EE_Config_Base
1608
-{
1609
-
1610
-    const OPTION_NAME_UXIP = 'ee_ueip_optin';
1611
-
1612
-
1613
-    public $current_blog_id;
1614
-
1615
-    public $ee_ueip_optin;
1616
-
1617
-    public $ee_ueip_has_notified;
1618
-
1619
-    /**
1620
-     * Not to be confused with the 4 critical page variables (See
1621
-     * get_critical_pages_array()), this is just an array of wp posts that have EE
1622
-     * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1623
-     * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1624
-     *
1625
-     * @var array
1626
-     */
1627
-    public $post_shortcodes;
1628
-
1629
-    public $module_route_map;
1630
-
1631
-    public $module_forward_map;
1632
-
1633
-    public $module_view_map;
1634
-
1635
-    /**
1636
-     * The next 4 vars are the IDs of critical EE pages.
1637
-     *
1638
-     * @var int
1639
-     */
1640
-    public $reg_page_id;
1641
-
1642
-    public $txn_page_id;
1643
-
1644
-    public $thank_you_page_id;
1645
-
1646
-    public $cancel_page_id;
1647
-
1648
-    /**
1649
-     * The next 4 vars are the URLs of critical EE pages.
1650
-     *
1651
-     * @var int
1652
-     */
1653
-    public $reg_page_url;
1654
-
1655
-    public $txn_page_url;
1656
-
1657
-    public $thank_you_page_url;
1658
-
1659
-    public $cancel_page_url;
1660
-
1661
-    /**
1662
-     * The next vars relate to the custom slugs for EE CPT routes
1663
-     */
1664
-    public $event_cpt_slug;
1665
-
1666
-    /**
1667
-     * This caches the _ee_ueip_option in case this config is reset in the same
1668
-     * request across blog switches in a multisite context.
1669
-     * Avoids extra queries to the db for this option.
1670
-     *
1671
-     * @var bool
1672
-     */
1673
-    public static $ee_ueip_option;
1674
-
1675
-
1676
-    /**
1677
-     *    class constructor
1678
-     *
1679
-     * @access    public
1680
-     */
1681
-    public function __construct()
1682
-    {
1683
-        // set default organization settings
1684
-        $this->current_blog_id = get_current_blog_id();
1685
-        $this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1686
-        $this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1687
-        $this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1688
-        $this->post_shortcodes = array();
1689
-        $this->module_route_map = array();
1690
-        $this->module_forward_map = array();
1691
-        $this->module_view_map = array();
1692
-        // critical EE page IDs
1693
-        $this->reg_page_id = 0;
1694
-        $this->txn_page_id = 0;
1695
-        $this->thank_you_page_id = 0;
1696
-        $this->cancel_page_id = 0;
1697
-        // critical EE page URLs
1698
-        $this->reg_page_url = '';
1699
-        $this->txn_page_url = '';
1700
-        $this->thank_you_page_url = '';
1701
-        $this->cancel_page_url = '';
1702
-        // cpt slugs
1703
-        $this->event_cpt_slug = __('events', 'event_espresso');
1704
-        // ueip constant check
1705
-        if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1706
-            $this->ee_ueip_optin = false;
1707
-            $this->ee_ueip_has_notified = true;
1708
-        }
1709
-    }
1710
-
1711
-
1712
-    /**
1713
-     * @return array
1714
-     */
1715
-    public function get_critical_pages_array()
1716
-    {
1717
-        return array(
1718
-            $this->reg_page_id,
1719
-            $this->txn_page_id,
1720
-            $this->thank_you_page_id,
1721
-            $this->cancel_page_id,
1722
-        );
1723
-    }
1724
-
1725
-
1726
-    /**
1727
-     * @return array
1728
-     */
1729
-    public function get_critical_pages_shortcodes_array()
1730
-    {
1731
-        return array(
1732
-            $this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1733
-            $this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1734
-            $this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1735
-            $this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1736
-        );
1737
-    }
1738
-
1739
-
1740
-    /**
1741
-     *  gets/returns URL for EE reg_page
1742
-     *
1743
-     * @access    public
1744
-     * @return    string
1745
-     */
1746
-    public function reg_page_url()
1747
-    {
1748
-        if (! $this->reg_page_url) {
1749
-            $this->reg_page_url = add_query_arg(
1750
-                array('uts' => time()),
1751
-                get_permalink($this->reg_page_id)
1752
-            ) . '#checkout';
1753
-        }
1754
-        return $this->reg_page_url;
1755
-    }
1756
-
1757
-
1758
-    /**
1759
-     *  gets/returns URL for EE txn_page
1760
-     *
1761
-     * @param array $query_args like what gets passed to
1762
-     *                          add_query_arg() as the first argument
1763
-     * @access    public
1764
-     * @return    string
1765
-     */
1766
-    public function txn_page_url($query_args = array())
1767
-    {
1768
-        if (! $this->txn_page_url) {
1769
-            $this->txn_page_url = get_permalink($this->txn_page_id);
1770
-        }
1771
-        if ($query_args) {
1772
-            return add_query_arg($query_args, $this->txn_page_url);
1773
-        } else {
1774
-            return $this->txn_page_url;
1775
-        }
1776
-    }
1777
-
1778
-
1779
-    /**
1780
-     *  gets/returns URL for EE thank_you_page
1781
-     *
1782
-     * @param array $query_args like what gets passed to
1783
-     *                          add_query_arg() as the first argument
1784
-     * @access    public
1785
-     * @return    string
1786
-     */
1787
-    public function thank_you_page_url($query_args = array())
1788
-    {
1789
-        if (! $this->thank_you_page_url) {
1790
-            $this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1791
-        }
1792
-        if ($query_args) {
1793
-            return add_query_arg($query_args, $this->thank_you_page_url);
1794
-        } else {
1795
-            return $this->thank_you_page_url;
1796
-        }
1797
-    }
1798
-
1799
-
1800
-    /**
1801
-     *  gets/returns URL for EE cancel_page
1802
-     *
1803
-     * @access    public
1804
-     * @return    string
1805
-     */
1806
-    public function cancel_page_url()
1807
-    {
1808
-        if (! $this->cancel_page_url) {
1809
-            $this->cancel_page_url = get_permalink($this->cancel_page_id);
1810
-        }
1811
-        return $this->cancel_page_url;
1812
-    }
1813
-
1814
-
1815
-    /**
1816
-     * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1817
-     *
1818
-     * @since 4.7.5
1819
-     */
1820
-    protected function _reset_urls()
1821
-    {
1822
-        $this->reg_page_url = '';
1823
-        $this->txn_page_url = '';
1824
-        $this->cancel_page_url = '';
1825
-        $this->thank_you_page_url = '';
1826
-    }
1827
-
1828
-
1829
-    /**
1830
-     * Used to return what the optin value is set for the EE User Experience Program.
1831
-     * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1832
-     * on the main site only.
1833
-     *
1834
-     * @return bool
1835
-     */
1836
-    protected function _get_main_ee_ueip_optin()
1837
-    {
1838
-        // if this is the main site then we can just bypass our direct query.
1839
-        if (is_main_site()) {
1840
-            return get_option(self::OPTION_NAME_UXIP, false);
1841
-        }
1842
-        // is this already cached for this request?  If so use it.
1843
-        if (EE_Core_Config::$ee_ueip_option !== null) {
1844
-            return EE_Core_Config::$ee_ueip_option;
1845
-        }
1846
-        global $wpdb;
1847
-        $current_network_main_site = is_multisite() ? get_current_site() : null;
1848
-        $current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1849
-        $option = self::OPTION_NAME_UXIP;
1850
-        // set correct table for query
1851
-        $table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1852
-        // rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1853
-        // get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1854
-        // re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1855
-        // this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1856
-        // for the purpose of caching.
1857
-        $pre = apply_filters('pre_option_' . $option, false, $option);
1858
-        if (false !== $pre) {
1859
-            EE_Core_Config::$ee_ueip_option = $pre;
1860
-            return EE_Core_Config::$ee_ueip_option;
1861
-        }
1862
-        $row = $wpdb->get_row(
1863
-            $wpdb->prepare(
1864
-                "SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1865
-                $option
1866
-            )
1867
-        );
1868
-        if (is_object($row)) {
1869
-            $value = $row->option_value;
1870
-        } else { // option does not exist so use default.
1871
-            EE_Core_Config::$ee_ueip_option =  apply_filters('default_option_' . $option, false, $option);
1872
-            return EE_Core_Config::$ee_ueip_option;
1873
-        }
1874
-        EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1875
-        return EE_Core_Config::$ee_ueip_option;
1876
-    }
1877
-
1878
-
1879
-    /**
1880
-     * Utility function for escaping the value of a property and returning.
1881
-     *
1882
-     * @param string $property property name (checks to see if exists).
1883
-     * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1884
-     * @throws \EE_Error
1885
-     */
1886
-    public function get_pretty($property)
1887
-    {
1888
-        if ($property === self::OPTION_NAME_UXIP) {
1889
-            return $this->ee_ueip_optin ? 'yes' : 'no';
1890
-        }
1891
-        return parent::get_pretty($property);
1892
-    }
1893
-
1894
-
1895
-    /**
1896
-     * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1897
-     * on the object.
1898
-     *
1899
-     * @return array
1900
-     */
1901
-    public function __sleep()
1902
-    {
1903
-        // reset all url properties
1904
-        $this->_reset_urls();
1905
-        // return what to save to db
1906
-        return array_keys(get_object_vars($this));
1907
-    }
1908
-}
1909
-
1910
-/**
1911
- * Config class for storing info on the Organization
1912
- */
1913
-class EE_Organization_Config extends EE_Config_Base
1914
-{
1915
-
1916
-    /**
1917
-     * @var string $name
1918
-     * eg EE4.1
1919
-     */
1920
-    public $name;
1921
-
1922
-    /**
1923
-     * @var string $address_1
1924
-     * eg 123 Onna Road
1925
-     */
1926
-    public $address_1 = '';
1927
-
1928
-    /**
1929
-     * @var string $address_2
1930
-     * eg PO Box 123
1931
-     */
1932
-    public $address_2 = '';
1933
-
1934
-    /**
1935
-     * @var string $city
1936
-     * eg Inna City
1937
-     */
1938
-    public $city = '';
1939
-
1940
-    /**
1941
-     * @var int $STA_ID
1942
-     * eg 4
1943
-     */
1944
-    public $STA_ID = 0;
1945
-
1946
-    /**
1947
-     * @var string $CNT_ISO
1948
-     * eg US
1949
-     */
1950
-    public $CNT_ISO = '';
1951
-
1952
-    /**
1953
-     * @var string $zip
1954
-     * eg 12345  or V1A 2B3
1955
-     */
1956
-    public $zip = '';
1957
-
1958
-    /**
1959
-     * @var string $email
1960
-     * eg [email protected]
1961
-     */
1962
-    public $email;
1963
-
1964
-    /**
1965
-     * @var string $phone
1966
-     * eg. 111-111-1111
1967
-     */
1968
-    public $phone = '';
1969
-
1970
-    /**
1971
-     * @var string $vat
1972
-     * VAT/Tax Number
1973
-     */
1974
-    public $vat = '';
1975
-
1976
-    /**
1977
-     * @var string $logo_url
1978
-     * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
1979
-     */
1980
-    public $logo_url = '';
1981
-
1982
-    /**
1983
-     * The below are all various properties for holding links to organization social network profiles
1984
-     *
1985
-     * @var string
1986
-     */
1987
-    /**
1988
-     * facebook (facebook.com/profile.name)
1989
-     *
1990
-     * @var string
1991
-     */
1992
-    public $facebook = '';
1993
-
1994
-    /**
1995
-     * twitter (twitter.com/twitter_handle)
1996
-     *
1997
-     * @var string
1998
-     */
1999
-    public $twitter = '';
2000
-
2001
-    /**
2002
-     * linkedin (linkedin.com/in/profile_name)
2003
-     *
2004
-     * @var string
2005
-     */
2006
-    public $linkedin = '';
2007
-
2008
-    /**
2009
-     * pinterest (www.pinterest.com/profile_name)
2010
-     *
2011
-     * @var string
2012
-     */
2013
-    public $pinterest = '';
2014
-
2015
-    /**
2016
-     * google+ (google.com/+profileName)
2017
-     *
2018
-     * @var string
2019
-     */
2020
-    public $google = '';
2021
-
2022
-    /**
2023
-     * instagram (instagram.com/handle)
2024
-     *
2025
-     * @var string
2026
-     */
2027
-    public $instagram = '';
2028
-
2029
-
2030
-    /**
2031
-     *    class constructor
2032
-     *
2033
-     * @access    public
2034
-     */
2035
-    public function __construct()
2036
-    {
2037
-        // set default organization settings
2038
-        // decode HTML entities from the WP blogname, because it's stored in the DB with HTML entities encoded
2039
-        $this->name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
2040
-        $this->email = get_bloginfo('admin_email');
2041
-    }
2042
-}
2043
-
2044
-/**
2045
- * Class for defining what's in the EE_Config relating to currency
2046
- */
2047
-class EE_Currency_Config extends EE_Config_Base
2048
-{
2049
-
2050
-    /**
2051
-     * @var string $code
2052
-     * eg 'US'
2053
-     */
2054
-    public $code;
2055
-
2056
-    /**
2057
-     * @var string $name
2058
-     * eg 'Dollar'
2059
-     */
2060
-    public $name;
2061
-
2062
-    /**
2063
-     * plural name
2064
-     *
2065
-     * @var string $plural
2066
-     * eg 'Dollars'
2067
-     */
2068
-    public $plural;
2069
-
2070
-    /**
2071
-     * currency sign
2072
-     *
2073
-     * @var string $sign
2074
-     * eg '$'
2075
-     */
2076
-    public $sign;
2077
-
2078
-    /**
2079
-     * Whether the currency sign should come before the number or not
2080
-     *
2081
-     * @var boolean $sign_b4
2082
-     */
2083
-    public $sign_b4;
2084
-
2085
-    /**
2086
-     * How many digits should come after the decimal place
2087
-     *
2088
-     * @var int $dec_plc
2089
-     */
2090
-    public $dec_plc;
2091
-
2092
-    /**
2093
-     * Symbol to use for decimal mark
2094
-     *
2095
-     * @var string $dec_mrk
2096
-     * eg '.'
2097
-     */
2098
-    public $dec_mrk;
2099
-
2100
-    /**
2101
-     * Symbol to use for thousands
2102
-     *
2103
-     * @var string $thsnds
2104
-     * eg ','
2105
-     */
2106
-    public $thsnds;
2107
-
2108
-
2109
-    /**
2110
-     *    class constructor
2111
-     *
2112
-     * @access    public
2113
-     * @param string $CNT_ISO
2114
-     * @throws \EE_Error
2115
-     */
2116
-    public function __construct($CNT_ISO = '')
2117
-    {
2118
-        /** @var \EventEspresso\core\services\database\TableAnalysis $table_analysis */
2119
-        $table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
2120
-        // get country code from organization settings or use default
2121
-        $ORG_CNT = isset(EE_Registry::instance()->CFG->organization)
2122
-                   && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
2123
-            ? EE_Registry::instance()->CFG->organization->CNT_ISO
2124
-            : '';
2125
-        // but override if requested
2126
-        $CNT_ISO = ! empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
2127
-        // so if that all went well, and we are not in M-Mode (cuz you can't query the db in M-Mode) and double-check the countries table exists
2128
-        if (! empty($CNT_ISO)
2129
-            && EE_Maintenance_Mode::instance()->models_can_query()
2130
-            && $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())
2131
-        ) {
2132
-            // retrieve the country settings from the db, just in case they have been customized
2133
-            $country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2134
-            if ($country instanceof EE_Country) {
2135
-                $this->code = $country->currency_code();    // currency code: USD, CAD, EUR
2136
-                $this->name = $country->currency_name_single();    // Dollar
2137
-                $this->plural = $country->currency_name_plural();    // Dollars
2138
-                $this->sign = $country->currency_sign();            // currency sign: $
2139
-                $this->sign_b4 = $country->currency_sign_before(
2140
-                );        // currency sign before or after: $TRUE  or  FALSE$
2141
-                $this->dec_plc = $country->currency_decimal_places();    // decimal places: 2 = 0.00  3 = 0.000
2142
-                $this->dec_mrk = $country->currency_decimal_mark(
2143
-                );    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2144
-                $this->thsnds = $country->currency_thousands_separator(
2145
-                );    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2146
-            }
2147
-        }
2148
-        // fallback to hardcoded defaults, in case the above failed
2149
-        if (empty($this->code)) {
2150
-            // set default currency settings
2151
-            $this->code = 'USD';    // currency code: USD, CAD, EUR
2152
-            $this->name = __('Dollar', 'event_espresso');    // Dollar
2153
-            $this->plural = __('Dollars', 'event_espresso');    // Dollars
2154
-            $this->sign = '$';    // currency sign: $
2155
-            $this->sign_b4 = true;    // currency sign before or after: $TRUE  or  FALSE$
2156
-            $this->dec_plc = 2;    // decimal places: 2 = 0.00  3 = 0.000
2157
-            $this->dec_mrk = '.';    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2158
-            $this->thsnds = ',';    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2159
-        }
2160
-    }
2161
-}
2162
-
2163
-/**
2164
- * Class for defining what's in the EE_Config relating to registration settings
2165
- */
2166
-class EE_Registration_Config extends EE_Config_Base
2167
-{
2168
-
2169
-    /**
2170
-     * Default registration status
2171
-     *
2172
-     * @var string $default_STS_ID
2173
-     * eg 'RPP'
2174
-     */
2175
-    public $default_STS_ID;
2176
-
2177
-    /**
2178
-     * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2179
-     * registrations)
2180
-     *
2181
-     * @var int
2182
-     */
2183
-    public $default_maximum_number_of_tickets;
2184
-
2185
-    /**
2186
-     * level of validation to apply to email addresses
2187
-     *
2188
-     * @var string $email_validation_level
2189
-     * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2190
-     */
2191
-    public $email_validation_level;
2192
-
2193
-    /**
2194
-     *    whether or not to show alternate payment options during the reg process if payment status is pending
2195
-     *
2196
-     * @var boolean $show_pending_payment_options
2197
-     */
2198
-    public $show_pending_payment_options;
2199
-
2200
-    /**
2201
-     * Whether to skip the registration confirmation page
2202
-     *
2203
-     * @var boolean $skip_reg_confirmation
2204
-     */
2205
-    public $skip_reg_confirmation;
2206
-
2207
-    /**
2208
-     * an array of SPCO reg steps where:
2209
-     *        the keys denotes the reg step order
2210
-     *        each element consists of an array with the following elements:
2211
-     *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2212
-     *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2213
-     *            "slug" => the URL param used to trigger the reg step
2214
-     *
2215
-     * @var array $reg_steps
2216
-     */
2217
-    public $reg_steps;
2218
-
2219
-    /**
2220
-     * Whether registration confirmation should be the last page of SPCO
2221
-     *
2222
-     * @var boolean $reg_confirmation_last
2223
-     */
2224
-    public $reg_confirmation_last;
2225
-
2226
-    /**
2227
-     * Whether or not to enable the EE Bot Trap
2228
-     *
2229
-     * @var boolean $use_bot_trap
2230
-     */
2231
-    public $use_bot_trap;
2232
-
2233
-    /**
2234
-     * Whether or not to encrypt some data sent by the EE Bot Trap
2235
-     *
2236
-     * @var boolean $use_encryption
2237
-     */
2238
-    public $use_encryption;
2239
-
2240
-    /**
2241
-     * Whether or not to use ReCaptcha
2242
-     *
2243
-     * @var boolean $use_captcha
2244
-     */
2245
-    public $use_captcha;
2246
-
2247
-    /**
2248
-     * ReCaptcha Theme
2249
-     *
2250
-     * @var string $recaptcha_theme
2251
-     *    options: 'dark', 'light', 'invisible'
2252
-     */
2253
-    public $recaptcha_theme;
2254
-
2255
-    /**
2256
-     * ReCaptcha Badge - determines the position of the reCAPTCHA badge if using Invisible ReCaptcha.
2257
-     *
2258
-     * @var string $recaptcha_badge
2259
-     *    options: 'bottomright', 'bottomleft', 'inline'
2260
-     */
2261
-    public $recaptcha_badge;
17
+	const OPTION_NAME = 'ee_config';
18
+
19
+	const LOG_NAME = 'ee_config_log';
20
+
21
+	const LOG_LENGTH = 100;
22
+
23
+	const ADDON_OPTION_NAMES = 'ee_config_option_names';
24
+
25
+	/**
26
+	 *    instance of the EE_Config object
27
+	 *
28
+	 * @var    EE_Config $_instance
29
+	 * @access    private
30
+	 */
31
+	private static $_instance;
32
+
33
+	/**
34
+	 * @var boolean $_logging_enabled
35
+	 */
36
+	private static $_logging_enabled = false;
37
+
38
+	/**
39
+	 * @var LegacyShortcodesManager $legacy_shortcodes_manager
40
+	 */
41
+	private $legacy_shortcodes_manager;
42
+
43
+	/**
44
+	 * An StdClass whose property names are addon slugs,
45
+	 * and values are their config classes
46
+	 *
47
+	 * @var StdClass
48
+	 */
49
+	public $addons;
50
+
51
+	/**
52
+	 * @var EE_Admin_Config
53
+	 */
54
+	public $admin;
55
+
56
+	/**
57
+	 * @var EE_Core_Config
58
+	 */
59
+	public $core;
60
+
61
+	/**
62
+	 * @var EE_Currency_Config
63
+	 */
64
+	public $currency;
65
+
66
+	/**
67
+	 * @var EE_Organization_Config
68
+	 */
69
+	public $organization;
70
+
71
+	/**
72
+	 * @var EE_Registration_Config
73
+	 */
74
+	public $registration;
75
+
76
+	/**
77
+	 * @var EE_Template_Config
78
+	 */
79
+	public $template_settings;
80
+
81
+	/**
82
+	 * Holds EE environment values.
83
+	 *
84
+	 * @var EE_Environment_Config
85
+	 */
86
+	public $environment;
87
+
88
+	/**
89
+	 * settings pertaining to Google maps
90
+	 *
91
+	 * @var EE_Map_Config
92
+	 */
93
+	public $map_settings;
94
+
95
+	/**
96
+	 * settings pertaining to Taxes
97
+	 *
98
+	 * @var EE_Tax_Config
99
+	 */
100
+	public $tax_settings;
101
+
102
+	/**
103
+	 * Settings pertaining to global messages settings.
104
+	 *
105
+	 * @var EE_Messages_Config
106
+	 */
107
+	public $messages;
108
+
109
+	/**
110
+	 * @deprecated
111
+	 * @var EE_Gateway_Config
112
+	 */
113
+	public $gateway;
114
+
115
+	/**
116
+	 * @var    array $_addon_option_names
117
+	 * @access    private
118
+	 */
119
+	private $_addon_option_names = array();
120
+
121
+	/**
122
+	 * @var    array $_module_route_map
123
+	 * @access    private
124
+	 */
125
+	private static $_module_route_map = array();
126
+
127
+	/**
128
+	 * @var    array $_module_forward_map
129
+	 * @access    private
130
+	 */
131
+	private static $_module_forward_map = array();
132
+
133
+	/**
134
+	 * @var    array $_module_view_map
135
+	 * @access    private
136
+	 */
137
+	private static $_module_view_map = array();
138
+
139
+
140
+	/**
141
+	 * @singleton method used to instantiate class object
142
+	 * @access    public
143
+	 * @return EE_Config instance
144
+	 */
145
+	public static function instance()
146
+	{
147
+		// check if class object is instantiated, and instantiated properly
148
+		if (! self::$_instance instanceof EE_Config) {
149
+			self::$_instance = new self();
150
+		}
151
+		return self::$_instance;
152
+	}
153
+
154
+
155
+	/**
156
+	 * Resets the config
157
+	 *
158
+	 * @param bool    $hard_reset    if TRUE, sets EE_CONFig back to its original settings in the database. If FALSE
159
+	 *                               (default) leaves the database alone, and merely resets the EE_Config object to
160
+	 *                               reflect its state in the database
161
+	 * @param boolean $reinstantiate if TRUE (default) call instance() and return it. Otherwise, just leave
162
+	 *                               $_instance as NULL. Useful in case you want to forget about the old instance on
163
+	 *                               EE_Config, but might not be ready to instantiate EE_Config currently (eg if the
164
+	 *                               site was put into maintenance mode)
165
+	 * @return EE_Config
166
+	 */
167
+	public static function reset($hard_reset = false, $reinstantiate = true)
168
+	{
169
+		if (self::$_instance instanceof EE_Config) {
170
+			if ($hard_reset) {
171
+				self::$_instance->legacy_shortcodes_manager = null;
172
+				self::$_instance->_addon_option_names = array();
173
+				self::$_instance->_initialize_config();
174
+				self::$_instance->update_espresso_config();
175
+			}
176
+			self::$_instance->update_addon_option_names();
177
+		}
178
+		self::$_instance = null;
179
+		// we don't need to reset the static properties imo because those should
180
+		// only change when a module is added or removed. Currently we don't
181
+		// support removing a module during a request when it previously existed
182
+		if ($reinstantiate) {
183
+			return self::instance();
184
+		} else {
185
+			return null;
186
+		}
187
+	}
188
+
189
+
190
+	/**
191
+	 *    class constructor
192
+	 *
193
+	 * @access    private
194
+	 */
195
+	private function __construct()
196
+	{
197
+		do_action('AHEE__EE_Config__construct__begin', $this);
198
+		EE_Config::$_logging_enabled = apply_filters('FHEE__EE_Config___construct__logging_enabled', false);
199
+		// setup empty config classes
200
+		$this->_initialize_config();
201
+		// load existing EE site settings
202
+		$this->_load_core_config();
203
+		// confirm everything loaded correctly and set filtered defaults if not
204
+		$this->_verify_config();
205
+		//  register shortcodes and modules
206
+		add_action(
207
+			'AHEE__EE_System__register_shortcodes_modules_and_widgets',
208
+			array($this, 'register_shortcodes_and_modules'),
209
+			999
210
+		);
211
+		//  initialize shortcodes and modules
212
+		add_action('AHEE__EE_System__core_loaded_and_ready', array($this, 'initialize_shortcodes_and_modules'));
213
+		// register widgets
214
+		add_action('widgets_init', array($this, 'widgets_init'), 10);
215
+		// shutdown
216
+		add_action('shutdown', array($this, 'shutdown'), 10);
217
+		// construct__end hook
218
+		do_action('AHEE__EE_Config__construct__end', $this);
219
+		// hardcoded hack
220
+		$this->template_settings->current_espresso_theme = 'Espresso_Arabica_2014';
221
+	}
222
+
223
+
224
+	/**
225
+	 * @return boolean
226
+	 */
227
+	public static function logging_enabled()
228
+	{
229
+		return self::$_logging_enabled;
230
+	}
231
+
232
+
233
+	/**
234
+	 * use to get the current theme if needed from static context
235
+	 *
236
+	 * @return string current theme set.
237
+	 */
238
+	public static function get_current_theme()
239
+	{
240
+		return isset(self::$_instance->template_settings->current_espresso_theme)
241
+			? self::$_instance->template_settings->current_espresso_theme : 'Espresso_Arabica_2014';
242
+	}
243
+
244
+
245
+	/**
246
+	 *        _initialize_config
247
+	 *
248
+	 * @access private
249
+	 * @return void
250
+	 */
251
+	private function _initialize_config()
252
+	{
253
+		EE_Config::trim_log();
254
+		// set defaults
255
+		$this->_addon_option_names = get_option(EE_Config::ADDON_OPTION_NAMES, array());
256
+		$this->addons = new stdClass();
257
+		// set _module_route_map
258
+		EE_Config::$_module_route_map = array();
259
+		// set _module_forward_map
260
+		EE_Config::$_module_forward_map = array();
261
+		// set _module_view_map
262
+		EE_Config::$_module_view_map = array();
263
+	}
264
+
265
+
266
+	/**
267
+	 *        load core plugin configuration
268
+	 *
269
+	 * @access private
270
+	 * @return void
271
+	 */
272
+	private function _load_core_config()
273
+	{
274
+		// load_core_config__start hook
275
+		do_action('AHEE__EE_Config___load_core_config__start', $this);
276
+		$espresso_config = $this->get_espresso_config();
277
+		foreach ($espresso_config as $config => $settings) {
278
+			// load_core_config__start hook
279
+			$settings = apply_filters(
280
+				'FHEE__EE_Config___load_core_config__config_settings',
281
+				$settings,
282
+				$config,
283
+				$this
284
+			);
285
+			if (is_object($settings) && property_exists($this, $config)) {
286
+				$this->{$config} = apply_filters('FHEE__EE_Config___load_core_config__' . $config, $settings);
287
+				// call configs populate method to ensure any defaults are set for empty values.
288
+				if (method_exists($settings, 'populate')) {
289
+					$this->{$config}->populate();
290
+				}
291
+				if (method_exists($settings, 'do_hooks')) {
292
+					$this->{$config}->do_hooks();
293
+				}
294
+			}
295
+		}
296
+		if (apply_filters('FHEE__EE_Config___load_core_config__update_espresso_config', false)) {
297
+			$this->update_espresso_config();
298
+		}
299
+		// load_core_config__end hook
300
+		do_action('AHEE__EE_Config___load_core_config__end', $this);
301
+	}
302
+
303
+
304
+	/**
305
+	 *    _verify_config
306
+	 *
307
+	 * @access    protected
308
+	 * @return    void
309
+	 */
310
+	protected function _verify_config()
311
+	{
312
+		$this->core = $this->core instanceof EE_Core_Config
313
+			? $this->core
314
+			: new EE_Core_Config();
315
+		$this->core = apply_filters('FHEE__EE_Config___initialize_config__core', $this->core);
316
+		$this->organization = $this->organization instanceof EE_Organization_Config
317
+			? $this->organization
318
+			: new EE_Organization_Config();
319
+		$this->organization = apply_filters(
320
+			'FHEE__EE_Config___initialize_config__organization',
321
+			$this->organization
322
+		);
323
+		$this->currency = $this->currency instanceof EE_Currency_Config
324
+			? $this->currency
325
+			: new EE_Currency_Config();
326
+		$this->currency = apply_filters('FHEE__EE_Config___initialize_config__currency', $this->currency);
327
+		$this->registration = $this->registration instanceof EE_Registration_Config
328
+			? $this->registration
329
+			: new EE_Registration_Config();
330
+		$this->registration = apply_filters(
331
+			'FHEE__EE_Config___initialize_config__registration',
332
+			$this->registration
333
+		);
334
+		$this->admin = $this->admin instanceof EE_Admin_Config
335
+			? $this->admin
336
+			: new EE_Admin_Config();
337
+		$this->admin = apply_filters('FHEE__EE_Config___initialize_config__admin', $this->admin);
338
+		$this->template_settings = $this->template_settings instanceof EE_Template_Config
339
+			? $this->template_settings
340
+			: new EE_Template_Config();
341
+		$this->template_settings = apply_filters(
342
+			'FHEE__EE_Config___initialize_config__template_settings',
343
+			$this->template_settings
344
+		);
345
+		$this->map_settings = $this->map_settings instanceof EE_Map_Config
346
+			? $this->map_settings
347
+			: new EE_Map_Config();
348
+		$this->map_settings = apply_filters(
349
+			'FHEE__EE_Config___initialize_config__map_settings',
350
+			$this->map_settings
351
+		);
352
+		$this->environment = $this->environment instanceof EE_Environment_Config
353
+			? $this->environment
354
+			: new EE_Environment_Config();
355
+		$this->environment = apply_filters(
356
+			'FHEE__EE_Config___initialize_config__environment',
357
+			$this->environment
358
+		);
359
+		$this->tax_settings = $this->tax_settings instanceof EE_Tax_Config
360
+			? $this->tax_settings
361
+			: new EE_Tax_Config();
362
+		$this->tax_settings = apply_filters(
363
+			'FHEE__EE_Config___initialize_config__tax_settings',
364
+			$this->tax_settings
365
+		);
366
+		$this->messages = apply_filters('FHEE__EE_Config__initialize_config__messages', $this->messages);
367
+		$this->messages = $this->messages instanceof EE_Messages_Config
368
+			? $this->messages
369
+			: new EE_Messages_Config();
370
+		$this->gateway = $this->gateway instanceof EE_Gateway_Config
371
+			? $this->gateway
372
+			: new EE_Gateway_Config();
373
+		$this->gateway = apply_filters('FHEE__EE_Config___initialize_config__gateway', $this->gateway);
374
+		$this->legacy_shortcodes_manager = null;
375
+	}
376
+
377
+
378
+	/**
379
+	 *    get_espresso_config
380
+	 *
381
+	 * @access    public
382
+	 * @return    array of espresso config stuff
383
+	 */
384
+	public function get_espresso_config()
385
+	{
386
+		// grab espresso configuration
387
+		return apply_filters(
388
+			'FHEE__EE_Config__get_espresso_config__CFG',
389
+			get_option(EE_Config::OPTION_NAME, array())
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 *    double_check_config_comparison
396
+	 *
397
+	 * @access    public
398
+	 * @param string $option
399
+	 * @param        $old_value
400
+	 * @param        $value
401
+	 */
402
+	public function double_check_config_comparison($option = '', $old_value, $value)
403
+	{
404
+		// make sure we're checking the ee config
405
+		if ($option === EE_Config::OPTION_NAME) {
406
+			// run a loose comparison of the old value against the new value for type and properties,
407
+			// but NOT exact instance like WP update_option does (ie: NOT type safe comparison)
408
+			if ($value != $old_value) {
409
+				// if they are NOT the same, then remove the hook,
410
+				// which means the subsequent update results will be based solely on the update query results
411
+				// the reason we do this is because, as stated above,
412
+				// WP update_option performs an exact instance comparison (===) on any update values passed to it
413
+				// this happens PRIOR to serialization and any subsequent update.
414
+				// If values are found to match their previous old value,
415
+				// then WP bails before performing any update.
416
+				// Since we are passing the EE_Config object, it is comparing the EXACT instance of the saved version
417
+				// it just pulled from the db, with the one being passed to it (which will not match).
418
+				// HOWEVER, once the object is serialized and passed off to MySQL to update,
419
+				// MySQL MAY ALSO NOT perform the update because
420
+				// the string it sees in the db looks the same as the new one it has been passed!!!
421
+				// This results in the query returning an "affected rows" value of ZERO,
422
+				// which gets returned immediately by WP update_option and looks like an error.
423
+				remove_action('update_option', array($this, 'check_config_updated'));
424
+			}
425
+		}
426
+	}
427
+
428
+
429
+	/**
430
+	 *    update_espresso_config
431
+	 *
432
+	 * @access   public
433
+	 */
434
+	protected function _reset_espresso_addon_config()
435
+	{
436
+		$this->_addon_option_names = array();
437
+		foreach ($this->addons as $addon_name => $addon_config_obj) {
438
+			$addon_config_obj = maybe_unserialize($addon_config_obj);
439
+			if ($addon_config_obj instanceof EE_Config_Base) {
440
+				$this->update_config('addons', $addon_name, $addon_config_obj, false);
441
+			}
442
+			$this->addons->{$addon_name} = null;
443
+		}
444
+	}
445
+
446
+
447
+	/**
448
+	 *    update_espresso_config
449
+	 *
450
+	 * @access   public
451
+	 * @param   bool $add_success
452
+	 * @param   bool $add_error
453
+	 * @return   bool
454
+	 */
455
+	public function update_espresso_config($add_success = false, $add_error = true)
456
+	{
457
+		// don't allow config updates during WP heartbeats
458
+		if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
459
+			return false;
460
+		}
461
+		// commented out the following re: https://events.codebasehq.com/projects/event-espresso/tickets/8197
462
+		// $clone = clone( self::$_instance );
463
+		// self::$_instance = NULL;
464
+		do_action('AHEE__EE_Config__update_espresso_config__begin', $this);
465
+		$this->_reset_espresso_addon_config();
466
+		// hook into update_option because that happens AFTER the ( $value === $old_value ) conditional
467
+		// but BEFORE the actual update occurs
468
+		add_action('update_option', array($this, 'double_check_config_comparison'), 1, 3);
469
+		// don't want to persist legacy_shortcodes_manager, but don't want to lose it either
470
+		$legacy_shortcodes_manager = $this->legacy_shortcodes_manager;
471
+		$this->legacy_shortcodes_manager = null;
472
+		// now update "ee_config"
473
+		$saved = update_option(EE_Config::OPTION_NAME, $this);
474
+		$this->legacy_shortcodes_manager = $legacy_shortcodes_manager;
475
+		EE_Config::log(EE_Config::OPTION_NAME);
476
+		// if not saved... check if the hook we just added still exists;
477
+		// if it does, it means one of two things:
478
+		// that update_option bailed at the($value === $old_value) conditional,
479
+		// or...
480
+		// the db update query returned 0 rows affected
481
+		// (probably because the data  value was the same from it's perspective)
482
+		// so the existence of the hook means that a negative result from update_option is NOT an error,
483
+		// but just means no update occurred, so don't display an error to the user.
484
+		// BUT... if update_option returns FALSE, AND the hook is missing,
485
+		// then it means that something truly went wrong
486
+		$saved = ! $saved ? has_action('update_option', array($this, 'double_check_config_comparison')) : $saved;
487
+		// remove our action since we don't want it in the system anymore
488
+		remove_action('update_option', array($this, 'double_check_config_comparison'), 1);
489
+		do_action('AHEE__EE_Config__update_espresso_config__end', $this, $saved);
490
+		// self::$_instance = $clone;
491
+		// unset( $clone );
492
+		// if config remains the same or was updated successfully
493
+		if ($saved) {
494
+			if ($add_success) {
495
+				EE_Error::add_success(
496
+					__('The Event Espresso Configuration Settings have been successfully updated.', 'event_espresso'),
497
+					__FILE__,
498
+					__FUNCTION__,
499
+					__LINE__
500
+				);
501
+			}
502
+			return true;
503
+		} else {
504
+			if ($add_error) {
505
+				EE_Error::add_error(
506
+					__('The Event Espresso Configuration Settings were not updated.', 'event_espresso'),
507
+					__FILE__,
508
+					__FUNCTION__,
509
+					__LINE__
510
+				);
511
+			}
512
+			return false;
513
+		}
514
+	}
515
+
516
+
517
+	/**
518
+	 *    _verify_config_params
519
+	 *
520
+	 * @access    private
521
+	 * @param    string         $section
522
+	 * @param    string         $name
523
+	 * @param    string         $config_class
524
+	 * @param    EE_Config_Base $config_obj
525
+	 * @param    array          $tests_to_run
526
+	 * @param    bool           $display_errors
527
+	 * @return    bool    TRUE on success, FALSE on fail
528
+	 */
529
+	private function _verify_config_params(
530
+		$section = '',
531
+		$name = '',
532
+		$config_class = '',
533
+		$config_obj = null,
534
+		$tests_to_run = array(1, 2, 3, 4, 5, 6, 7, 8),
535
+		$display_errors = true
536
+	) {
537
+		try {
538
+			foreach ($tests_to_run as $test) {
539
+				switch ($test) {
540
+					// TEST #1 : check that section was set
541
+					case 1:
542
+						if (empty($section)) {
543
+							if ($display_errors) {
544
+								throw new EE_Error(
545
+									sprintf(
546
+										__(
547
+											'No configuration section has been provided while attempting to save "%s".',
548
+											'event_espresso'
549
+										),
550
+										$config_class
551
+									)
552
+								);
553
+							}
554
+							return false;
555
+						}
556
+						break;
557
+					// TEST #2 : check that settings section exists
558
+					case 2:
559
+						if (! isset($this->{$section})) {
560
+							if ($display_errors) {
561
+								throw new EE_Error(
562
+									sprintf(
563
+										__('The "%s" configuration section does not exist.', 'event_espresso'),
564
+										$section
565
+									)
566
+								);
567
+							}
568
+							return false;
569
+						}
570
+						break;
571
+					// TEST #3 : check that section is the proper format
572
+					case 3:
573
+						if (! ($this->{$section} instanceof EE_Config_Base || $this->{$section} instanceof stdClass)
574
+						) {
575
+							if ($display_errors) {
576
+								throw new EE_Error(
577
+									sprintf(
578
+										__(
579
+											'The "%s" configuration settings have not been formatted correctly.',
580
+											'event_espresso'
581
+										),
582
+										$section
583
+									)
584
+								);
585
+							}
586
+							return false;
587
+						}
588
+						break;
589
+					// TEST #4 : check that config section name has been set
590
+					case 4:
591
+						if (empty($name)) {
592
+							if ($display_errors) {
593
+								throw new EE_Error(
594
+									__(
595
+										'No name has been provided for the specific configuration section.',
596
+										'event_espresso'
597
+									)
598
+								);
599
+							}
600
+							return false;
601
+						}
602
+						break;
603
+					// TEST #5 : check that a config class name has been set
604
+					case 5:
605
+						if (empty($config_class)) {
606
+							if ($display_errors) {
607
+								throw new EE_Error(
608
+									__(
609
+										'No class name has been provided for the specific configuration section.',
610
+										'event_espresso'
611
+									)
612
+								);
613
+							}
614
+							return false;
615
+						}
616
+						break;
617
+					// TEST #6 : verify config class is accessible
618
+					case 6:
619
+						if (! class_exists($config_class)) {
620
+							if ($display_errors) {
621
+								throw new EE_Error(
622
+									sprintf(
623
+										__(
624
+											'The "%s" class does not exist. Please ensure that an autoloader has been set for it.',
625
+											'event_espresso'
626
+										),
627
+										$config_class
628
+									)
629
+								);
630
+							}
631
+							return false;
632
+						}
633
+						break;
634
+					// TEST #7 : check that config has even been set
635
+					case 7:
636
+						if (! isset($this->{$section}->{$name})) {
637
+							if ($display_errors) {
638
+								throw new EE_Error(
639
+									sprintf(
640
+										__('No configuration has been set for "%1$s->%2$s".', 'event_espresso'),
641
+										$section,
642
+										$name
643
+									)
644
+								);
645
+							}
646
+							return false;
647
+						} else {
648
+							// and make sure it's not serialized
649
+							$this->{$section}->{$name} = maybe_unserialize($this->{$section}->{$name});
650
+						}
651
+						break;
652
+					// TEST #8 : check that config is the requested type
653
+					case 8:
654
+						if (! $this->{$section}->{$name} instanceof $config_class) {
655
+							if ($display_errors) {
656
+								throw new EE_Error(
657
+									sprintf(
658
+										__(
659
+											'The configuration for "%1$s->%2$s" is not of the "%3$s" class.',
660
+											'event_espresso'
661
+										),
662
+										$section,
663
+										$name,
664
+										$config_class
665
+									)
666
+								);
667
+							}
668
+							return false;
669
+						}
670
+						break;
671
+					// TEST #9 : verify config object
672
+					case 9:
673
+						if (! $config_obj instanceof EE_Config_Base) {
674
+							if ($display_errors) {
675
+								throw new EE_Error(
676
+									sprintf(
677
+										__('The "%s" class is not an instance of EE_Config_Base.', 'event_espresso'),
678
+										print_r($config_obj, true)
679
+									)
680
+								);
681
+							}
682
+							return false;
683
+						}
684
+						break;
685
+				}
686
+			}
687
+		} catch (EE_Error $e) {
688
+			$e->get_error();
689
+		}
690
+		// you have successfully run the gauntlet
691
+		return true;
692
+	}
693
+
694
+
695
+	/**
696
+	 *    _generate_config_option_name
697
+	 *
698
+	 * @access        protected
699
+	 * @param        string $section
700
+	 * @param        string $name
701
+	 * @return        string
702
+	 */
703
+	private function _generate_config_option_name($section = '', $name = '')
704
+	{
705
+		return 'ee_config-' . strtolower($section . '-' . str_replace(array('EE_', 'EED_'), '', $name));
706
+	}
707
+
708
+
709
+	/**
710
+	 *    _set_config_class
711
+	 * ensures that a config class is set, either from a passed config class or one generated from the config name
712
+	 *
713
+	 * @access    private
714
+	 * @param    string $config_class
715
+	 * @param    string $name
716
+	 * @return    string
717
+	 */
718
+	private function _set_config_class($config_class = '', $name = '')
719
+	{
720
+		return ! empty($config_class)
721
+			? $config_class
722
+			: str_replace(' ', '_', ucwords(str_replace('_', ' ', $name))) . '_Config';
723
+	}
724
+
725
+
726
+	/**
727
+	 *    set_config
728
+	 *
729
+	 * @access    protected
730
+	 * @param    string         $section
731
+	 * @param    string         $name
732
+	 * @param    string         $config_class
733
+	 * @param    EE_Config_Base $config_obj
734
+	 * @return    EE_Config_Base
735
+	 */
736
+	public function set_config($section = '', $name = '', $config_class = '', EE_Config_Base $config_obj = null)
737
+	{
738
+		// ensure config class is set to something
739
+		$config_class = $this->_set_config_class($config_class, $name);
740
+		// run tests 1-4, 6, and 7 to verify all config params are set and valid
741
+		if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
742
+			return null;
743
+		}
744
+		$config_option_name = $this->_generate_config_option_name($section, $name);
745
+		// if the config option name hasn't been added yet to the list of option names we're tracking, then do so now
746
+		if (! isset($this->_addon_option_names[ $config_option_name ])) {
747
+			$this->_addon_option_names[ $config_option_name ] = $config_class;
748
+			$this->update_addon_option_names();
749
+		}
750
+		// verify the incoming config object but suppress errors
751
+		if (! $this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
752
+			$config_obj = new $config_class();
753
+		}
754
+		if (get_option($config_option_name)) {
755
+			EE_Config::log($config_option_name);
756
+			update_option($config_option_name, $config_obj);
757
+			$this->{$section}->{$name} = $config_obj;
758
+			return $this->{$section}->{$name};
759
+		} else {
760
+			// create a wp-option for this config
761
+			if (add_option($config_option_name, $config_obj, '', 'no')) {
762
+				$this->{$section}->{$name} = maybe_unserialize($config_obj);
763
+				return $this->{$section}->{$name};
764
+			} else {
765
+				EE_Error::add_error(
766
+					sprintf(__('The "%s" could not be saved to the database.', 'event_espresso'), $config_class),
767
+					__FILE__,
768
+					__FUNCTION__,
769
+					__LINE__
770
+				);
771
+				return null;
772
+			}
773
+		}
774
+	}
775
+
776
+
777
+	/**
778
+	 *    update_config
779
+	 * Important: the config object must ALREADY be set, otherwise this will produce an error.
780
+	 *
781
+	 * @access    public
782
+	 * @param    string                $section
783
+	 * @param    string                $name
784
+	 * @param    EE_Config_Base|string $config_obj
785
+	 * @param    bool                  $throw_errors
786
+	 * @return    bool
787
+	 */
788
+	public function update_config($section = '', $name = '', $config_obj = '', $throw_errors = true)
789
+	{
790
+		// don't allow config updates during WP heartbeats
791
+		if (\EE_Registry::instance()->REQ->get('action', '') === 'heartbeat') {
792
+			return false;
793
+		}
794
+		$config_obj = maybe_unserialize($config_obj);
795
+		// get class name of the incoming object
796
+		$config_class = get_class($config_obj);
797
+		// run tests 1-5 and 9 to verify config
798
+		if (! $this->_verify_config_params(
799
+			$section,
800
+			$name,
801
+			$config_class,
802
+			$config_obj,
803
+			array(1, 2, 3, 4, 7, 9)
804
+		)
805
+		) {
806
+			return false;
807
+		}
808
+		$config_option_name = $this->_generate_config_option_name($section, $name);
809
+		// check if config object has been added to db by seeing if config option name is in $this->_addon_option_names array
810
+		if (! isset($this->_addon_option_names[ $config_option_name ])) {
811
+			// save new config to db
812
+			if ($this->set_config($section, $name, $config_class, $config_obj)) {
813
+				return true;
814
+			}
815
+		} else {
816
+			// first check if the record already exists
817
+			$existing_config = get_option($config_option_name);
818
+			$config_obj = serialize($config_obj);
819
+			// just return if db record is already up to date (NOT type safe comparison)
820
+			if ($existing_config == $config_obj) {
821
+				$this->{$section}->{$name} = $config_obj;
822
+				return true;
823
+			} elseif (update_option($config_option_name, $config_obj)) {
824
+				EE_Config::log($config_option_name);
825
+				// update wp-option for this config class
826
+				$this->{$section}->{$name} = $config_obj;
827
+				return true;
828
+			} elseif ($throw_errors) {
829
+				EE_Error::add_error(
830
+					sprintf(
831
+						__(
832
+							'The "%1$s" object stored at"%2$s" was not successfully updated in the database.',
833
+							'event_espresso'
834
+						),
835
+						$config_class,
836
+						'EE_Config->' . $section . '->' . $name
837
+					),
838
+					__FILE__,
839
+					__FUNCTION__,
840
+					__LINE__
841
+				);
842
+			}
843
+		}
844
+		return false;
845
+	}
846
+
847
+
848
+	/**
849
+	 *    get_config
850
+	 *
851
+	 * @access    public
852
+	 * @param    string $section
853
+	 * @param    string $name
854
+	 * @param    string $config_class
855
+	 * @return    mixed EE_Config_Base | NULL
856
+	 */
857
+	public function get_config($section = '', $name = '', $config_class = '')
858
+	{
859
+		// ensure config class is set to something
860
+		$config_class = $this->_set_config_class($config_class, $name);
861
+		// run tests 1-4, 6 and 7 to verify that all params have been set
862
+		if (! $this->_verify_config_params($section, $name, $config_class, null, array(1, 2, 3, 4, 5, 6))) {
863
+			return null;
864
+		}
865
+		// now test if the requested config object exists, but suppress errors
866
+		if ($this->_verify_config_params($section, $name, $config_class, null, array(7, 8), false)) {
867
+			// config already exists, so pass it back
868
+			return $this->{$section}->{$name};
869
+		}
870
+		// load config option from db if it exists
871
+		$config_obj = $this->get_config_option($this->_generate_config_option_name($section, $name));
872
+		// verify the newly retrieved config object, but suppress errors
873
+		if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9), false)) {
874
+			// config is good, so set it and pass it back
875
+			$this->{$section}->{$name} = $config_obj;
876
+			return $this->{$section}->{$name};
877
+		}
878
+		// oops! $config_obj is not already set and does not exist in the db, so create a new one
879
+		$config_obj = $this->set_config($section, $name, $config_class);
880
+		// verify the newly created config object
881
+		if ($this->_verify_config_params($section, $name, $config_class, $config_obj, array(9))) {
882
+			return $this->{$section}->{$name};
883
+		} else {
884
+			EE_Error::add_error(
885
+				sprintf(__('The "%s" could not be retrieved from the database.', 'event_espresso'), $config_class),
886
+				__FILE__,
887
+				__FUNCTION__,
888
+				__LINE__
889
+			);
890
+		}
891
+		return null;
892
+	}
893
+
894
+
895
+	/**
896
+	 *    get_config_option
897
+	 *
898
+	 * @access    public
899
+	 * @param    string $config_option_name
900
+	 * @return    mixed EE_Config_Base | FALSE
901
+	 */
902
+	public function get_config_option($config_option_name = '')
903
+	{
904
+		// retrieve the wp-option for this config class.
905
+		$config_option = maybe_unserialize(get_option($config_option_name, array()));
906
+		if (empty($config_option)) {
907
+			EE_Config::log($config_option_name . '-NOT-FOUND');
908
+		}
909
+		return $config_option;
910
+	}
911
+
912
+
913
+	/**
914
+	 * log
915
+	 *
916
+	 * @param string $config_option_name
917
+	 */
918
+	public static function log($config_option_name = '')
919
+	{
920
+		if (EE_Config::logging_enabled() && ! empty($config_option_name)) {
921
+			$config_log = get_option(EE_Config::LOG_NAME, array());
922
+			// copy incoming $_REQUEST and sanitize it so we can save it
923
+			$_request = $_REQUEST;
924
+			array_walk_recursive($_request, 'sanitize_text_field');
925
+			$config_log[ (string) microtime(true) ] = array(
926
+				'config_name' => $config_option_name,
927
+				'request'     => $_request,
928
+			);
929
+			update_option(EE_Config::LOG_NAME, $config_log);
930
+		}
931
+	}
932
+
933
+
934
+	/**
935
+	 * trim_log
936
+	 * reduces the size of the config log to the length specified by EE_Config::LOG_LENGTH
937
+	 */
938
+	public static function trim_log()
939
+	{
940
+		if (! EE_Config::logging_enabled()) {
941
+			return;
942
+		}
943
+		$config_log = maybe_unserialize(get_option(EE_Config::LOG_NAME, array()));
944
+		$log_length = count($config_log);
945
+		if ($log_length > EE_Config::LOG_LENGTH) {
946
+			ksort($config_log);
947
+			$config_log = array_slice($config_log, $log_length - EE_Config::LOG_LENGTH, null, true);
948
+			update_option(EE_Config::LOG_NAME, $config_log);
949
+		}
950
+	}
951
+
952
+
953
+	/**
954
+	 *    get_page_for_posts
955
+	 *    if the wp-option "show_on_front" is set to "page", then this is the post_name for the post set in the
956
+	 *    wp-option "page_for_posts", or "posts" if no page is selected
957
+	 *
958
+	 * @access    public
959
+	 * @return    string
960
+	 */
961
+	public static function get_page_for_posts()
962
+	{
963
+		$page_for_posts = get_option('page_for_posts');
964
+		if (! $page_for_posts) {
965
+			return 'posts';
966
+		}
967
+		/** @type WPDB $wpdb */
968
+		global $wpdb;
969
+		$SQL = "SELECT post_name from $wpdb->posts WHERE post_type='posts' OR post_type='page' AND post_status='publish' AND ID=%d";
970
+		return $wpdb->get_var($wpdb->prepare($SQL, $page_for_posts));
971
+	}
972
+
973
+
974
+	/**
975
+	 *    register_shortcodes_and_modules.
976
+	 *    At this point, it's too early to tell if we're maintenance mode or not.
977
+	 *    In fact, this is where we give modules a chance to let core know they exist
978
+	 *    so they can help trigger maintenance mode if it's needed
979
+	 *
980
+	 * @access    public
981
+	 * @return    void
982
+	 */
983
+	public function register_shortcodes_and_modules()
984
+	{
985
+		// allow modules to set hooks for the rest of the system
986
+		EE_Registry::instance()->modules = $this->_register_modules();
987
+	}
988
+
989
+
990
+	/**
991
+	 *    initialize_shortcodes_and_modules
992
+	 *    meaning they can start adding their hooks to get stuff done
993
+	 *
994
+	 * @access    public
995
+	 * @return    void
996
+	 */
997
+	public function initialize_shortcodes_and_modules()
998
+	{
999
+		// allow modules to set hooks for the rest of the system
1000
+		$this->_initialize_modules();
1001
+	}
1002
+
1003
+
1004
+	/**
1005
+	 *    widgets_init
1006
+	 *
1007
+	 * @access private
1008
+	 * @return void
1009
+	 */
1010
+	public function widgets_init()
1011
+	{
1012
+		// only init widgets on admin pages when not in complete maintenance, and
1013
+		// on frontend when not in any maintenance mode
1014
+		if (! EE_Maintenance_Mode::instance()->level()
1015
+			|| (
1016
+				is_admin()
1017
+				&& EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance
1018
+			)
1019
+		) {
1020
+			// grab list of installed widgets
1021
+			$widgets_to_register = glob(EE_WIDGETS . '*', GLOB_ONLYDIR);
1022
+			// filter list of modules to register
1023
+			$widgets_to_register = apply_filters(
1024
+				'FHEE__EE_Config__register_widgets__widgets_to_register',
1025
+				$widgets_to_register
1026
+			);
1027
+			if (! empty($widgets_to_register)) {
1028
+				// cycle thru widget folders
1029
+				foreach ($widgets_to_register as $widget_path) {
1030
+					// add to list of installed widget modules
1031
+					EE_Config::register_ee_widget($widget_path);
1032
+				}
1033
+			}
1034
+			// filter list of installed modules
1035
+			EE_Registry::instance()->widgets = apply_filters(
1036
+				'FHEE__EE_Config__register_widgets__installed_widgets',
1037
+				EE_Registry::instance()->widgets
1038
+			);
1039
+		}
1040
+	}
1041
+
1042
+
1043
+	/**
1044
+	 *    register_ee_widget - makes core aware of this widget
1045
+	 *
1046
+	 * @access    public
1047
+	 * @param    string $widget_path - full path up to and including widget folder
1048
+	 * @return    void
1049
+	 */
1050
+	public static function register_ee_widget($widget_path = null)
1051
+	{
1052
+		do_action('AHEE__EE_Config__register_widget__begin', $widget_path);
1053
+		$widget_ext = '.widget.php';
1054
+		// make all separators match
1055
+		$widget_path = rtrim(str_replace('\\', DS, $widget_path), DS);
1056
+		// does the file path INCLUDE the actual file name as part of the path ?
1057
+		if (strpos($widget_path, $widget_ext) !== false) {
1058
+			// grab and shortcode file name from directory name and break apart at dots
1059
+			$file_name = explode('.', basename($widget_path));
1060
+			// take first segment from file name pieces and remove class prefix if it exists
1061
+			$widget = strpos($file_name[0], 'EEW_') === 0 ? substr($file_name[0], 4) : $file_name[0];
1062
+			// sanitize shortcode directory name
1063
+			$widget = sanitize_key($widget);
1064
+			// now we need to rebuild the shortcode path
1065
+			$widget_path = explode('/', $widget_path);
1066
+			// remove last segment
1067
+			array_pop($widget_path);
1068
+			// glue it back together
1069
+			$widget_path = implode(DS, $widget_path);
1070
+		} else {
1071
+			// grab and sanitize widget directory name
1072
+			$widget = sanitize_key(basename($widget_path));
1073
+		}
1074
+		// create classname from widget directory name
1075
+		$widget = str_replace(' ', '_', ucwords(str_replace('_', ' ', $widget)));
1076
+		// add class prefix
1077
+		$widget_class = 'EEW_' . $widget;
1078
+		// does the widget exist ?
1079
+		if (! is_readable($widget_path . '/' . $widget_class . $widget_ext)) {
1080
+			$msg = sprintf(
1081
+				__(
1082
+					'The requested %s widget file could not be found or is not readable due to file permissions. Please ensure the following path is correct: %s',
1083
+					'event_espresso'
1084
+				),
1085
+				$widget_class,
1086
+				$widget_path . '/' . $widget_class . $widget_ext
1087
+			);
1088
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1089
+			return;
1090
+		}
1091
+		// load the widget class file
1092
+		require_once($widget_path . '/' . $widget_class . $widget_ext);
1093
+		// verify that class exists
1094
+		if (! class_exists($widget_class)) {
1095
+			$msg = sprintf(__('The requested %s widget class does not exist.', 'event_espresso'), $widget_class);
1096
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1097
+			return;
1098
+		}
1099
+		register_widget($widget_class);
1100
+		// add to array of registered widgets
1101
+		EE_Registry::instance()->widgets->{$widget_class} = $widget_path . '/' . $widget_class . $widget_ext;
1102
+	}
1103
+
1104
+
1105
+	/**
1106
+	 *        _register_modules
1107
+	 *
1108
+	 * @access private
1109
+	 * @return array
1110
+	 */
1111
+	private function _register_modules()
1112
+	{
1113
+		// grab list of installed modules
1114
+		$modules_to_register = glob(EE_MODULES . '*', GLOB_ONLYDIR);
1115
+		// filter list of modules to register
1116
+		$modules_to_register = apply_filters(
1117
+			'FHEE__EE_Config__register_modules__modules_to_register',
1118
+			$modules_to_register
1119
+		);
1120
+		if (! empty($modules_to_register)) {
1121
+			// loop through folders
1122
+			foreach ($modules_to_register as $module_path) {
1123
+				/**TEMPORARILY EXCLUDE gateways from modules for time being**/
1124
+				if ($module_path !== EE_MODULES . 'zzz-copy-this-module-template'
1125
+					&& $module_path !== EE_MODULES . 'gateways'
1126
+				) {
1127
+					// add to list of installed modules
1128
+					EE_Config::register_module($module_path);
1129
+				}
1130
+			}
1131
+		}
1132
+		// filter list of installed modules
1133
+		return apply_filters(
1134
+			'FHEE__EE_Config___register_modules__installed_modules',
1135
+			EE_Registry::instance()->modules
1136
+		);
1137
+	}
1138
+
1139
+
1140
+	/**
1141
+	 *    register_module - makes core aware of this module
1142
+	 *
1143
+	 * @access    public
1144
+	 * @param    string $module_path - full path up to and including module folder
1145
+	 * @return    bool
1146
+	 */
1147
+	public static function register_module($module_path = null)
1148
+	{
1149
+		do_action('AHEE__EE_Config__register_module__begin', $module_path);
1150
+		$module_ext = '.module.php';
1151
+		// make all separators match
1152
+		$module_path = str_replace(array('\\', '/'), '/', $module_path);
1153
+		// does the file path INCLUDE the actual file name as part of the path ?
1154
+		if (strpos($module_path, $module_ext) !== false) {
1155
+			// grab and shortcode file name from directory name and break apart at dots
1156
+			$module_file = explode('.', basename($module_path));
1157
+			// now we need to rebuild the shortcode path
1158
+			$module_path = explode('/', $module_path);
1159
+			// remove last segment
1160
+			array_pop($module_path);
1161
+			// glue it back together
1162
+			$module_path = implode('/', $module_path) . '/';
1163
+			// take first segment from file name pieces and sanitize it
1164
+			$module = preg_replace('/[^a-zA-Z0-9_\-]/', '', $module_file[0]);
1165
+			// ensure class prefix is added
1166
+			$module_class = strpos($module, 'EED_') !== 0 ? 'EED_' . $module : $module;
1167
+		} else {
1168
+			// we need to generate the filename based off of the folder name
1169
+			// grab and sanitize module name
1170
+			$module = strtolower(basename($module_path));
1171
+			$module = preg_replace('/[^a-z0-9_\-]/', '', $module);
1172
+			// like trailingslashit()
1173
+			$module_path = rtrim($module_path, '/') . '/';
1174
+			// create classname from module directory name
1175
+			$module = str_replace(' ', '_', ucwords(str_replace('_', ' ', $module)));
1176
+			// add class prefix
1177
+			$module_class = 'EED_' . $module;
1178
+		}
1179
+		// does the module exist ?
1180
+		if (! is_readable($module_path . '/' . $module_class . $module_ext)) {
1181
+			$msg = sprintf(
1182
+				__(
1183
+					'The requested %s module file could not be found or is not readable due to file permissions.',
1184
+					'event_espresso'
1185
+				),
1186
+				$module
1187
+			);
1188
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1189
+			return false;
1190
+		}
1191
+		// load the module class file
1192
+		require_once($module_path . $module_class . $module_ext);
1193
+		// verify that class exists
1194
+		if (! class_exists($module_class)) {
1195
+			$msg = sprintf(__('The requested %s module class does not exist.', 'event_espresso'), $module_class);
1196
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1197
+			return false;
1198
+		}
1199
+		// add to array of registered modules
1200
+		EE_Registry::instance()->modules->{$module_class} = $module_path . $module_class . $module_ext;
1201
+		do_action(
1202
+			'AHEE__EE_Config__register_module__complete',
1203
+			$module_class,
1204
+			EE_Registry::instance()->modules->{$module_class}
1205
+		);
1206
+		return true;
1207
+	}
1208
+
1209
+
1210
+	/**
1211
+	 *    _initialize_modules
1212
+	 *    allow modules to set hooks for the rest of the system
1213
+	 *
1214
+	 * @access private
1215
+	 * @return void
1216
+	 */
1217
+	private function _initialize_modules()
1218
+	{
1219
+		// cycle thru shortcode folders
1220
+		foreach (EE_Registry::instance()->modules as $module_class => $module_path) {
1221
+			// fire the shortcode class's set_hooks methods in case it needs to hook into other parts of the system
1222
+			// which set hooks ?
1223
+			if (is_admin()) {
1224
+				// fire immediately
1225
+				call_user_func(array($module_class, 'set_hooks_admin'));
1226
+			} else {
1227
+				// delay until other systems are online
1228
+				add_action(
1229
+					'AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons',
1230
+					array($module_class, 'set_hooks')
1231
+				);
1232
+			}
1233
+		}
1234
+	}
1235
+
1236
+
1237
+	/**
1238
+	 *    register_route - adds module method routes to route_map
1239
+	 *
1240
+	 * @access    public
1241
+	 * @param    string $route       - "pretty" public alias for module method
1242
+	 * @param    string $module      - module name (classname without EED_ prefix)
1243
+	 * @param    string $method_name - the actual module method to be routed to
1244
+	 * @param    string $key         - url param key indicating a route is being called
1245
+	 * @return    bool
1246
+	 */
1247
+	public static function register_route($route = null, $module = null, $method_name = null, $key = 'ee')
1248
+	{
1249
+		do_action('AHEE__EE_Config__register_route__begin', $route, $module, $method_name);
1250
+		$module = str_replace('EED_', '', $module);
1251
+		$module_class = 'EED_' . $module;
1252
+		if (! isset(EE_Registry::instance()->modules->{$module_class})) {
1253
+			$msg = sprintf(__('The module %s has not been registered.', 'event_espresso'), $module);
1254
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1255
+			return false;
1256
+		}
1257
+		if (empty($route)) {
1258
+			$msg = sprintf(__('No route has been supplied.', 'event_espresso'), $route);
1259
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1260
+			return false;
1261
+		}
1262
+		if (! method_exists('EED_' . $module, $method_name)) {
1263
+			$msg = sprintf(
1264
+				__('A valid class method for the %s route has not been supplied.', 'event_espresso'),
1265
+				$route
1266
+			);
1267
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1268
+			return false;
1269
+		}
1270
+		EE_Config::$_module_route_map[ (string) $key ][ (string) $route ] = array('EED_' . $module, $method_name);
1271
+		return true;
1272
+	}
1273
+
1274
+
1275
+	/**
1276
+	 *    get_route - get module method route
1277
+	 *
1278
+	 * @access    public
1279
+	 * @param    string $route - "pretty" public alias for module method
1280
+	 * @param    string $key   - url param key indicating a route is being called
1281
+	 * @return    string
1282
+	 */
1283
+	public static function get_route($route = null, $key = 'ee')
1284
+	{
1285
+		do_action('AHEE__EE_Config__get_route__begin', $route);
1286
+		$route = (string) apply_filters('FHEE__EE_Config__get_route', $route);
1287
+		if (isset(EE_Config::$_module_route_map[ $key ][ $route ])) {
1288
+			return EE_Config::$_module_route_map[ $key ][ $route ];
1289
+		}
1290
+		return null;
1291
+	}
1292
+
1293
+
1294
+	/**
1295
+	 *    get_routes - get ALL module method routes
1296
+	 *
1297
+	 * @access    public
1298
+	 * @return    array
1299
+	 */
1300
+	public static function get_routes()
1301
+	{
1302
+		return EE_Config::$_module_route_map;
1303
+	}
1304
+
1305
+
1306
+	/**
1307
+	 *    register_forward - allows modules to forward request to another module for further processing
1308
+	 *
1309
+	 * @access    public
1310
+	 * @param    string       $route   - "pretty" public alias for module method
1311
+	 * @param    integer      $status  - integer value corresponding  to status constant strings set in module parent
1312
+	 *                                 class, allows different forwards to be served based on status
1313
+	 * @param    array|string $forward - function name or array( class, method )
1314
+	 * @param    string       $key     - url param key indicating a route is being called
1315
+	 * @return    bool
1316
+	 */
1317
+	public static function register_forward($route = null, $status = 0, $forward = null, $key = 'ee')
1318
+	{
1319
+		do_action('AHEE__EE_Config__register_forward', $route, $status, $forward);
1320
+		if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1321
+			$msg = sprintf(
1322
+				__('The module route %s for this forward has not been registered.', 'event_espresso'),
1323
+				$route
1324
+			);
1325
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1326
+			return false;
1327
+		}
1328
+		if (empty($forward)) {
1329
+			$msg = sprintf(__('No forwarding route has been supplied.', 'event_espresso'), $route);
1330
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1331
+			return false;
1332
+		}
1333
+		if (is_array($forward)) {
1334
+			if (! isset($forward[1])) {
1335
+				$msg = sprintf(
1336
+					__('A class method for the %s forwarding route has not been supplied.', 'event_espresso'),
1337
+					$route
1338
+				);
1339
+				EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1340
+				return false;
1341
+			}
1342
+			if (! method_exists($forward[0], $forward[1])) {
1343
+				$msg = sprintf(
1344
+					__('The class method %s for the %s forwarding route is in invalid.', 'event_espresso'),
1345
+					$forward[1],
1346
+					$route
1347
+				);
1348
+				EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1349
+				return false;
1350
+			}
1351
+		} elseif (! function_exists($forward)) {
1352
+			$msg = sprintf(
1353
+				__('The function %s for the %s forwarding route is in invalid.', 'event_espresso'),
1354
+				$forward,
1355
+				$route
1356
+			);
1357
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1358
+			return false;
1359
+		}
1360
+		EE_Config::$_module_forward_map[ $key ][ $route ][ absint($status) ] = $forward;
1361
+		return true;
1362
+	}
1363
+
1364
+
1365
+	/**
1366
+	 *    get_forward - get forwarding route
1367
+	 *
1368
+	 * @access    public
1369
+	 * @param    string  $route  - "pretty" public alias for module method
1370
+	 * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1371
+	 *                           allows different forwards to be served based on status
1372
+	 * @param    string  $key    - url param key indicating a route is being called
1373
+	 * @return    string
1374
+	 */
1375
+	public static function get_forward($route = null, $status = 0, $key = 'ee')
1376
+	{
1377
+		do_action('AHEE__EE_Config__get_forward__begin', $route, $status);
1378
+		if (isset(EE_Config::$_module_forward_map[ $key ][ $route ][ $status ])) {
1379
+			return apply_filters(
1380
+				'FHEE__EE_Config__get_forward',
1381
+				EE_Config::$_module_forward_map[ $key ][ $route ][ $status ],
1382
+				$route,
1383
+				$status
1384
+			);
1385
+		}
1386
+		return null;
1387
+	}
1388
+
1389
+
1390
+	/**
1391
+	 *    register_forward - allows modules to specify different view templates for different method routes and status
1392
+	 *    results
1393
+	 *
1394
+	 * @access    public
1395
+	 * @param    string  $route  - "pretty" public alias for module method
1396
+	 * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1397
+	 *                           allows different views to be served based on status
1398
+	 * @param    string  $view
1399
+	 * @param    string  $key    - url param key indicating a route is being called
1400
+	 * @return    bool
1401
+	 */
1402
+	public static function register_view($route = null, $status = 0, $view = null, $key = 'ee')
1403
+	{
1404
+		do_action('AHEE__EE_Config__register_view__begin', $route, $status, $view);
1405
+		if (! isset(EE_Config::$_module_route_map[ $key ][ $route ]) || empty($route)) {
1406
+			$msg = sprintf(
1407
+				__('The module route %s for this view has not been registered.', 'event_espresso'),
1408
+				$route
1409
+			);
1410
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1411
+			return false;
1412
+		}
1413
+		if (! is_readable($view)) {
1414
+			$msg = sprintf(
1415
+				__(
1416
+					'The %s view file could not be found or is not readable due to file permissions.',
1417
+					'event_espresso'
1418
+				),
1419
+				$view
1420
+			);
1421
+			EE_Error::add_error($msg . '||' . $msg, __FILE__, __FUNCTION__, __LINE__);
1422
+			return false;
1423
+		}
1424
+		EE_Config::$_module_view_map[ $key ][ $route ][ absint($status) ] = $view;
1425
+		return true;
1426
+	}
1427
+
1428
+
1429
+	/**
1430
+	 *    get_view - get view for route and status
1431
+	 *
1432
+	 * @access    public
1433
+	 * @param    string  $route  - "pretty" public alias for module method
1434
+	 * @param    integer $status - integer value corresponding  to status constant strings set in module parent class,
1435
+	 *                           allows different views to be served based on status
1436
+	 * @param    string  $key    - url param key indicating a route is being called
1437
+	 * @return    string
1438
+	 */
1439
+	public static function get_view($route = null, $status = 0, $key = 'ee')
1440
+	{
1441
+		do_action('AHEE__EE_Config__get_view__begin', $route, $status);
1442
+		if (isset(EE_Config::$_module_view_map[ $key ][ $route ][ $status ])) {
1443
+			return apply_filters(
1444
+				'FHEE__EE_Config__get_view',
1445
+				EE_Config::$_module_view_map[ $key ][ $route ][ $status ],
1446
+				$route,
1447
+				$status
1448
+			);
1449
+		}
1450
+		return null;
1451
+	}
1452
+
1453
+
1454
+	public function update_addon_option_names()
1455
+	{
1456
+		update_option(EE_Config::ADDON_OPTION_NAMES, $this->_addon_option_names);
1457
+	}
1458
+
1459
+
1460
+	public function shutdown()
1461
+	{
1462
+		$this->update_addon_option_names();
1463
+	}
1464
+
1465
+
1466
+	/**
1467
+	 * @return LegacyShortcodesManager
1468
+	 */
1469
+	public static function getLegacyShortcodesManager()
1470
+	{
1471
+
1472
+		if (! EE_Config::instance()->legacy_shortcodes_manager instanceof LegacyShortcodesManager) {
1473
+			EE_Config::instance()->legacy_shortcodes_manager = new LegacyShortcodesManager(
1474
+				EE_Registry::instance()
1475
+			);
1476
+		}
1477
+		return EE_Config::instance()->legacy_shortcodes_manager;
1478
+	}
1479
+
1480
+
1481
+	/**
1482
+	 * register_shortcode - makes core aware of this shortcode
1483
+	 *
1484
+	 * @deprecated 4.9.26
1485
+	 * @param    string $shortcode_path - full path up to and including shortcode folder
1486
+	 * @return    bool
1487
+	 */
1488
+	public static function register_shortcode($shortcode_path = null)
1489
+	{
1490
+		EE_Error::doing_it_wrong(
1491
+			__METHOD__,
1492
+			__(
1493
+				'Usage is deprecated. Use \EventEspresso\core\services\shortcodes\LegacyShortcodesManager::registerShortcode() as direct replacement, or better yet, please see the new \EventEspresso\core\services\shortcodes\ShortcodesManager class.',
1494
+				'event_espresso'
1495
+			),
1496
+			'4.9.26'
1497
+		);
1498
+		return EE_Config::instance()->getLegacyShortcodesManager()->registerShortcode($shortcode_path);
1499
+	}
1500
+}
2262 1501
 
2263
-    /**
2264
-     * ReCaptcha Type
2265
-     *
2266
-     * @var string $recaptcha_type
2267
-     *    options: 'audio', 'image'
2268
-     */
2269
-    public $recaptcha_type;
1502
+/**
1503
+ * Base class used for config classes. These classes should generally not have
1504
+ * magic functions in use, except we'll allow them to magically set and get stuff...
1505
+ * basically, they should just be well-defined stdClasses
1506
+ */
1507
+class EE_Config_Base
1508
+{
2270 1509
 
2271
-    /**
2272
-     * ReCaptcha language
2273
-     *
2274
-     * @var string $recaptcha_language
2275
-     * eg 'en'
2276
-     */
2277
-    public $recaptcha_language;
1510
+	/**
1511
+	 * Utility function for escaping the value of a property and returning.
1512
+	 *
1513
+	 * @param string $property property name (checks to see if exists).
1514
+	 * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1515
+	 * @throws \EE_Error
1516
+	 */
1517
+	public function get_pretty($property)
1518
+	{
1519
+		if (! property_exists($this, $property)) {
1520
+			throw new EE_Error(
1521
+				sprintf(
1522
+					__(
1523
+						'%1$s::get_pretty() has been called with the property %2$s which does not exist on the %1$s config class.',
1524
+						'event_espresso'
1525
+					),
1526
+					get_class($this),
1527
+					$property
1528
+				)
1529
+			);
1530
+		}
1531
+		// just handling escaping of strings for now.
1532
+		if (is_string($this->{$property})) {
1533
+			return stripslashes($this->{$property});
1534
+		}
1535
+		return $this->{$property};
1536
+	}
1537
+
1538
+
1539
+	public function populate()
1540
+	{
1541
+		// grab defaults via a new instance of this class.
1542
+		$class_name = get_class($this);
1543
+		$defaults = new $class_name;
1544
+		// loop through the properties for this class and see if they are set.  If they are NOT, then grab the
1545
+		// default from our $defaults object.
1546
+		foreach (get_object_vars($defaults) as $property => $value) {
1547
+			if ($this->{$property} === null) {
1548
+				$this->{$property} = $value;
1549
+			}
1550
+		}
1551
+		// cleanup
1552
+		unset($defaults);
1553
+	}
1554
+
1555
+
1556
+	/**
1557
+	 *        __isset
1558
+	 *
1559
+	 * @param $a
1560
+	 * @return bool
1561
+	 */
1562
+	public function __isset($a)
1563
+	{
1564
+		return false;
1565
+	}
1566
+
1567
+
1568
+	/**
1569
+	 *        __unset
1570
+	 *
1571
+	 * @param $a
1572
+	 * @return bool
1573
+	 */
1574
+	public function __unset($a)
1575
+	{
1576
+		return false;
1577
+	}
1578
+
1579
+
1580
+	/**
1581
+	 *        __clone
1582
+	 */
1583
+	public function __clone()
1584
+	{
1585
+	}
1586
+
1587
+
1588
+	/**
1589
+	 *        __wakeup
1590
+	 */
1591
+	public function __wakeup()
1592
+	{
1593
+	}
1594
+
1595
+
1596
+	/**
1597
+	 *        __destruct
1598
+	 */
1599
+	public function __destruct()
1600
+	{
1601
+	}
1602
+}
2278 1603
 
2279
-    /**
2280
-     * ReCaptcha public key
2281
-     *
2282
-     * @var string $recaptcha_publickey
2283
-     */
2284
-    public $recaptcha_publickey;
1604
+/**
1605
+ * Class for defining what's in the EE_Config relating to registration settings
1606
+ */
1607
+class EE_Core_Config extends EE_Config_Base
1608
+{
2285 1609
 
2286
-    /**
2287
-     * ReCaptcha private key
2288
-     *
2289
-     * @var string $recaptcha_privatekey
2290
-     */
2291
-    public $recaptcha_privatekey;
1610
+	const OPTION_NAME_UXIP = 'ee_ueip_optin';
1611
+
1612
+
1613
+	public $current_blog_id;
1614
+
1615
+	public $ee_ueip_optin;
1616
+
1617
+	public $ee_ueip_has_notified;
1618
+
1619
+	/**
1620
+	 * Not to be confused with the 4 critical page variables (See
1621
+	 * get_critical_pages_array()), this is just an array of wp posts that have EE
1622
+	 * shortcodes in them. Keys are slugs, values are arrays with only 1 element: where the key is the shortcode
1623
+	 * in the page, and the value is the page's ID. The key 'posts' is basically a duplicate of this same array.
1624
+	 *
1625
+	 * @var array
1626
+	 */
1627
+	public $post_shortcodes;
1628
+
1629
+	public $module_route_map;
1630
+
1631
+	public $module_forward_map;
1632
+
1633
+	public $module_view_map;
1634
+
1635
+	/**
1636
+	 * The next 4 vars are the IDs of critical EE pages.
1637
+	 *
1638
+	 * @var int
1639
+	 */
1640
+	public $reg_page_id;
1641
+
1642
+	public $txn_page_id;
1643
+
1644
+	public $thank_you_page_id;
1645
+
1646
+	public $cancel_page_id;
1647
+
1648
+	/**
1649
+	 * The next 4 vars are the URLs of critical EE pages.
1650
+	 *
1651
+	 * @var int
1652
+	 */
1653
+	public $reg_page_url;
1654
+
1655
+	public $txn_page_url;
1656
+
1657
+	public $thank_you_page_url;
1658
+
1659
+	public $cancel_page_url;
1660
+
1661
+	/**
1662
+	 * The next vars relate to the custom slugs for EE CPT routes
1663
+	 */
1664
+	public $event_cpt_slug;
1665
+
1666
+	/**
1667
+	 * This caches the _ee_ueip_option in case this config is reset in the same
1668
+	 * request across blog switches in a multisite context.
1669
+	 * Avoids extra queries to the db for this option.
1670
+	 *
1671
+	 * @var bool
1672
+	 */
1673
+	public static $ee_ueip_option;
1674
+
1675
+
1676
+	/**
1677
+	 *    class constructor
1678
+	 *
1679
+	 * @access    public
1680
+	 */
1681
+	public function __construct()
1682
+	{
1683
+		// set default organization settings
1684
+		$this->current_blog_id = get_current_blog_id();
1685
+		$this->current_blog_id = $this->current_blog_id === null ? 1 : $this->current_blog_id;
1686
+		$this->ee_ueip_optin = $this->_get_main_ee_ueip_optin();
1687
+		$this->ee_ueip_has_notified = is_main_site() ? get_option('ee_ueip_has_notified', false) : true;
1688
+		$this->post_shortcodes = array();
1689
+		$this->module_route_map = array();
1690
+		$this->module_forward_map = array();
1691
+		$this->module_view_map = array();
1692
+		// critical EE page IDs
1693
+		$this->reg_page_id = 0;
1694
+		$this->txn_page_id = 0;
1695
+		$this->thank_you_page_id = 0;
1696
+		$this->cancel_page_id = 0;
1697
+		// critical EE page URLs
1698
+		$this->reg_page_url = '';
1699
+		$this->txn_page_url = '';
1700
+		$this->thank_you_page_url = '';
1701
+		$this->cancel_page_url = '';
1702
+		// cpt slugs
1703
+		$this->event_cpt_slug = __('events', 'event_espresso');
1704
+		// ueip constant check
1705
+		if (defined('EE_DISABLE_UXIP') && EE_DISABLE_UXIP) {
1706
+			$this->ee_ueip_optin = false;
1707
+			$this->ee_ueip_has_notified = true;
1708
+		}
1709
+	}
1710
+
1711
+
1712
+	/**
1713
+	 * @return array
1714
+	 */
1715
+	public function get_critical_pages_array()
1716
+	{
1717
+		return array(
1718
+			$this->reg_page_id,
1719
+			$this->txn_page_id,
1720
+			$this->thank_you_page_id,
1721
+			$this->cancel_page_id,
1722
+		);
1723
+	}
1724
+
1725
+
1726
+	/**
1727
+	 * @return array
1728
+	 */
1729
+	public function get_critical_pages_shortcodes_array()
1730
+	{
1731
+		return array(
1732
+			$this->reg_page_id       => 'ESPRESSO_CHECKOUT',
1733
+			$this->txn_page_id       => 'ESPRESSO_TXN_PAGE',
1734
+			$this->thank_you_page_id => 'ESPRESSO_THANK_YOU',
1735
+			$this->cancel_page_id    => 'ESPRESSO_CANCELLED',
1736
+		);
1737
+	}
1738
+
1739
+
1740
+	/**
1741
+	 *  gets/returns URL for EE reg_page
1742
+	 *
1743
+	 * @access    public
1744
+	 * @return    string
1745
+	 */
1746
+	public function reg_page_url()
1747
+	{
1748
+		if (! $this->reg_page_url) {
1749
+			$this->reg_page_url = add_query_arg(
1750
+				array('uts' => time()),
1751
+				get_permalink($this->reg_page_id)
1752
+			) . '#checkout';
1753
+		}
1754
+		return $this->reg_page_url;
1755
+	}
1756
+
1757
+
1758
+	/**
1759
+	 *  gets/returns URL for EE txn_page
1760
+	 *
1761
+	 * @param array $query_args like what gets passed to
1762
+	 *                          add_query_arg() as the first argument
1763
+	 * @access    public
1764
+	 * @return    string
1765
+	 */
1766
+	public function txn_page_url($query_args = array())
1767
+	{
1768
+		if (! $this->txn_page_url) {
1769
+			$this->txn_page_url = get_permalink($this->txn_page_id);
1770
+		}
1771
+		if ($query_args) {
1772
+			return add_query_arg($query_args, $this->txn_page_url);
1773
+		} else {
1774
+			return $this->txn_page_url;
1775
+		}
1776
+	}
1777
+
1778
+
1779
+	/**
1780
+	 *  gets/returns URL for EE thank_you_page
1781
+	 *
1782
+	 * @param array $query_args like what gets passed to
1783
+	 *                          add_query_arg() as the first argument
1784
+	 * @access    public
1785
+	 * @return    string
1786
+	 */
1787
+	public function thank_you_page_url($query_args = array())
1788
+	{
1789
+		if (! $this->thank_you_page_url) {
1790
+			$this->thank_you_page_url = get_permalink($this->thank_you_page_id);
1791
+		}
1792
+		if ($query_args) {
1793
+			return add_query_arg($query_args, $this->thank_you_page_url);
1794
+		} else {
1795
+			return $this->thank_you_page_url;
1796
+		}
1797
+	}
1798
+
1799
+
1800
+	/**
1801
+	 *  gets/returns URL for EE cancel_page
1802
+	 *
1803
+	 * @access    public
1804
+	 * @return    string
1805
+	 */
1806
+	public function cancel_page_url()
1807
+	{
1808
+		if (! $this->cancel_page_url) {
1809
+			$this->cancel_page_url = get_permalink($this->cancel_page_id);
1810
+		}
1811
+		return $this->cancel_page_url;
1812
+	}
1813
+
1814
+
1815
+	/**
1816
+	 * Resets all critical page urls to their original state.  Used primarily by the __sleep() magic method currently.
1817
+	 *
1818
+	 * @since 4.7.5
1819
+	 */
1820
+	protected function _reset_urls()
1821
+	{
1822
+		$this->reg_page_url = '';
1823
+		$this->txn_page_url = '';
1824
+		$this->cancel_page_url = '';
1825
+		$this->thank_you_page_url = '';
1826
+	}
1827
+
1828
+
1829
+	/**
1830
+	 * Used to return what the optin value is set for the EE User Experience Program.
1831
+	 * This accounts for multisite and this value being requested for a subsite.  In multisite, the value is set
1832
+	 * on the main site only.
1833
+	 *
1834
+	 * @return bool
1835
+	 */
1836
+	protected function _get_main_ee_ueip_optin()
1837
+	{
1838
+		// if this is the main site then we can just bypass our direct query.
1839
+		if (is_main_site()) {
1840
+			return get_option(self::OPTION_NAME_UXIP, false);
1841
+		}
1842
+		// is this already cached for this request?  If so use it.
1843
+		if (EE_Core_Config::$ee_ueip_option !== null) {
1844
+			return EE_Core_Config::$ee_ueip_option;
1845
+		}
1846
+		global $wpdb;
1847
+		$current_network_main_site = is_multisite() ? get_current_site() : null;
1848
+		$current_main_site_id = ! empty($current_network_main_site) ? $current_network_main_site->blog_id : 1;
1849
+		$option = self::OPTION_NAME_UXIP;
1850
+		// set correct table for query
1851
+		$table_name = $wpdb->get_blog_prefix($current_main_site_id) . 'options';
1852
+		// rather than getting blog option for the $current_main_site_id, we do a direct $wpdb query because
1853
+		// get_blog_option() does a switch_to_blog an that could cause infinite recursion because EE_Core_Config might be
1854
+		// re-constructed on the blog switch.  Note, we are still executing any core wp filters on this option retrieval.
1855
+		// this bit of code is basically a direct copy of get_option without any caching because we are NOT switched to the blog
1856
+		// for the purpose of caching.
1857
+		$pre = apply_filters('pre_option_' . $option, false, $option);
1858
+		if (false !== $pre) {
1859
+			EE_Core_Config::$ee_ueip_option = $pre;
1860
+			return EE_Core_Config::$ee_ueip_option;
1861
+		}
1862
+		$row = $wpdb->get_row(
1863
+			$wpdb->prepare(
1864
+				"SELECT option_value FROM $table_name WHERE option_name = %s LIMIT 1",
1865
+				$option
1866
+			)
1867
+		);
1868
+		if (is_object($row)) {
1869
+			$value = $row->option_value;
1870
+		} else { // option does not exist so use default.
1871
+			EE_Core_Config::$ee_ueip_option =  apply_filters('default_option_' . $option, false, $option);
1872
+			return EE_Core_Config::$ee_ueip_option;
1873
+		}
1874
+		EE_Core_Config::$ee_ueip_option = apply_filters('option_' . $option, maybe_unserialize($value), $option);
1875
+		return EE_Core_Config::$ee_ueip_option;
1876
+	}
1877
+
1878
+
1879
+	/**
1880
+	 * Utility function for escaping the value of a property and returning.
1881
+	 *
1882
+	 * @param string $property property name (checks to see if exists).
1883
+	 * @return mixed if a detected type found return the escaped value, otherwise just the raw value is returned.
1884
+	 * @throws \EE_Error
1885
+	 */
1886
+	public function get_pretty($property)
1887
+	{
1888
+		if ($property === self::OPTION_NAME_UXIP) {
1889
+			return $this->ee_ueip_optin ? 'yes' : 'no';
1890
+		}
1891
+		return parent::get_pretty($property);
1892
+	}
1893
+
1894
+
1895
+	/**
1896
+	 * Currently used to ensure critical page urls have initial values saved to the db instead of any current set values
1897
+	 * on the object.
1898
+	 *
1899
+	 * @return array
1900
+	 */
1901
+	public function __sleep()
1902
+	{
1903
+		// reset all url properties
1904
+		$this->_reset_urls();
1905
+		// return what to save to db
1906
+		return array_keys(get_object_vars($this));
1907
+	}
1908
+}
2292 1909
 
2293
-    /**
2294
-     * array of form names protected by ReCaptcha
2295
-     *
2296
-     * @var array $recaptcha_protected_forms
2297
-     */
2298
-    public $recaptcha_protected_forms;
1910
+/**
1911
+ * Config class for storing info on the Organization
1912
+ */
1913
+class EE_Organization_Config extends EE_Config_Base
1914
+{
2299 1915
 
2300
-    /**
2301
-     * ReCaptcha width
2302
-     *
2303
-     * @var int $recaptcha_width
2304
-     * @deprecated
2305
-     */
2306
-    public $recaptcha_width;
1916
+	/**
1917
+	 * @var string $name
1918
+	 * eg EE4.1
1919
+	 */
1920
+	public $name;
1921
+
1922
+	/**
1923
+	 * @var string $address_1
1924
+	 * eg 123 Onna Road
1925
+	 */
1926
+	public $address_1 = '';
1927
+
1928
+	/**
1929
+	 * @var string $address_2
1930
+	 * eg PO Box 123
1931
+	 */
1932
+	public $address_2 = '';
1933
+
1934
+	/**
1935
+	 * @var string $city
1936
+	 * eg Inna City
1937
+	 */
1938
+	public $city = '';
1939
+
1940
+	/**
1941
+	 * @var int $STA_ID
1942
+	 * eg 4
1943
+	 */
1944
+	public $STA_ID = 0;
1945
+
1946
+	/**
1947
+	 * @var string $CNT_ISO
1948
+	 * eg US
1949
+	 */
1950
+	public $CNT_ISO = '';
1951
+
1952
+	/**
1953
+	 * @var string $zip
1954
+	 * eg 12345  or V1A 2B3
1955
+	 */
1956
+	public $zip = '';
1957
+
1958
+	/**
1959
+	 * @var string $email
1960
+	 * eg [email protected]
1961
+	 */
1962
+	public $email;
1963
+
1964
+	/**
1965
+	 * @var string $phone
1966
+	 * eg. 111-111-1111
1967
+	 */
1968
+	public $phone = '';
1969
+
1970
+	/**
1971
+	 * @var string $vat
1972
+	 * VAT/Tax Number
1973
+	 */
1974
+	public $vat = '';
1975
+
1976
+	/**
1977
+	 * @var string $logo_url
1978
+	 * eg http://www.somedomain.com/wp-content/uploads/kittehs.jpg
1979
+	 */
1980
+	public $logo_url = '';
1981
+
1982
+	/**
1983
+	 * The below are all various properties for holding links to organization social network profiles
1984
+	 *
1985
+	 * @var string
1986
+	 */
1987
+	/**
1988
+	 * facebook (facebook.com/profile.name)
1989
+	 *
1990
+	 * @var string
1991
+	 */
1992
+	public $facebook = '';
1993
+
1994
+	/**
1995
+	 * twitter (twitter.com/twitter_handle)
1996
+	 *
1997
+	 * @var string
1998
+	 */
1999
+	public $twitter = '';
2000
+
2001
+	/**
2002
+	 * linkedin (linkedin.com/in/profile_name)
2003
+	 *
2004
+	 * @var string
2005
+	 */
2006
+	public $linkedin = '';
2007
+
2008
+	/**
2009
+	 * pinterest (www.pinterest.com/profile_name)
2010
+	 *
2011
+	 * @var string
2012
+	 */
2013
+	public $pinterest = '';
2014
+
2015
+	/**
2016
+	 * google+ (google.com/+profileName)
2017
+	 *
2018
+	 * @var string
2019
+	 */
2020
+	public $google = '';
2021
+
2022
+	/**
2023
+	 * instagram (instagram.com/handle)
2024
+	 *
2025
+	 * @var string
2026
+	 */
2027
+	public $instagram = '';
2028
+
2029
+
2030
+	/**
2031
+	 *    class constructor
2032
+	 *
2033
+	 * @access    public
2034
+	 */
2035
+	public function __construct()
2036
+	{
2037
+		// set default organization settings
2038
+		// decode HTML entities from the WP blogname, because it's stored in the DB with HTML entities encoded
2039
+		$this->name = wp_specialchars_decode(get_bloginfo('name'), ENT_QUOTES);
2040
+		$this->email = get_bloginfo('admin_email');
2041
+	}
2042
+}
2307 2043
 
2308
-    /**
2309
-     * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2310
-     *
2311
-     * @var boolean $track_invalid_checkout_access
2312
-     */
2313
-    protected $track_invalid_checkout_access = true;
2044
+/**
2045
+ * Class for defining what's in the EE_Config relating to currency
2046
+ */
2047
+class EE_Currency_Config extends EE_Config_Base
2048
+{
2314 2049
 
2315
-    /**
2316
-     * Whether or not to show the privacy policy consent checkbox
2317
-     *
2318
-     * @var bool
2319
-     */
2320
-    public $consent_checkbox_enabled;
2050
+	/**
2051
+	 * @var string $code
2052
+	 * eg 'US'
2053
+	 */
2054
+	public $code;
2055
+
2056
+	/**
2057
+	 * @var string $name
2058
+	 * eg 'Dollar'
2059
+	 */
2060
+	public $name;
2061
+
2062
+	/**
2063
+	 * plural name
2064
+	 *
2065
+	 * @var string $plural
2066
+	 * eg 'Dollars'
2067
+	 */
2068
+	public $plural;
2069
+
2070
+	/**
2071
+	 * currency sign
2072
+	 *
2073
+	 * @var string $sign
2074
+	 * eg '$'
2075
+	 */
2076
+	public $sign;
2077
+
2078
+	/**
2079
+	 * Whether the currency sign should come before the number or not
2080
+	 *
2081
+	 * @var boolean $sign_b4
2082
+	 */
2083
+	public $sign_b4;
2084
+
2085
+	/**
2086
+	 * How many digits should come after the decimal place
2087
+	 *
2088
+	 * @var int $dec_plc
2089
+	 */
2090
+	public $dec_plc;
2091
+
2092
+	/**
2093
+	 * Symbol to use for decimal mark
2094
+	 *
2095
+	 * @var string $dec_mrk
2096
+	 * eg '.'
2097
+	 */
2098
+	public $dec_mrk;
2099
+
2100
+	/**
2101
+	 * Symbol to use for thousands
2102
+	 *
2103
+	 * @var string $thsnds
2104
+	 * eg ','
2105
+	 */
2106
+	public $thsnds;
2107
+
2108
+
2109
+	/**
2110
+	 *    class constructor
2111
+	 *
2112
+	 * @access    public
2113
+	 * @param string $CNT_ISO
2114
+	 * @throws \EE_Error
2115
+	 */
2116
+	public function __construct($CNT_ISO = '')
2117
+	{
2118
+		/** @var \EventEspresso\core\services\database\TableAnalysis $table_analysis */
2119
+		$table_analysis = EE_Registry::instance()->create('TableAnalysis', array(), true);
2120
+		// get country code from organization settings or use default
2121
+		$ORG_CNT = isset(EE_Registry::instance()->CFG->organization)
2122
+				   && EE_Registry::instance()->CFG->organization instanceof EE_Organization_Config
2123
+			? EE_Registry::instance()->CFG->organization->CNT_ISO
2124
+			: '';
2125
+		// but override if requested
2126
+		$CNT_ISO = ! empty($CNT_ISO) ? $CNT_ISO : $ORG_CNT;
2127
+		// so if that all went well, and we are not in M-Mode (cuz you can't query the db in M-Mode) and double-check the countries table exists
2128
+		if (! empty($CNT_ISO)
2129
+			&& EE_Maintenance_Mode::instance()->models_can_query()
2130
+			&& $table_analysis->tableExists(EE_Registry::instance()->load_model('Country')->table())
2131
+		) {
2132
+			// retrieve the country settings from the db, just in case they have been customized
2133
+			$country = EE_Registry::instance()->load_model('Country')->get_one_by_ID($CNT_ISO);
2134
+			if ($country instanceof EE_Country) {
2135
+				$this->code = $country->currency_code();    // currency code: USD, CAD, EUR
2136
+				$this->name = $country->currency_name_single();    // Dollar
2137
+				$this->plural = $country->currency_name_plural();    // Dollars
2138
+				$this->sign = $country->currency_sign();            // currency sign: $
2139
+				$this->sign_b4 = $country->currency_sign_before(
2140
+				);        // currency sign before or after: $TRUE  or  FALSE$
2141
+				$this->dec_plc = $country->currency_decimal_places();    // decimal places: 2 = 0.00  3 = 0.000
2142
+				$this->dec_mrk = $country->currency_decimal_mark(
2143
+				);    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2144
+				$this->thsnds = $country->currency_thousands_separator(
2145
+				);    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2146
+			}
2147
+		}
2148
+		// fallback to hardcoded defaults, in case the above failed
2149
+		if (empty($this->code)) {
2150
+			// set default currency settings
2151
+			$this->code = 'USD';    // currency code: USD, CAD, EUR
2152
+			$this->name = __('Dollar', 'event_espresso');    // Dollar
2153
+			$this->plural = __('Dollars', 'event_espresso');    // Dollars
2154
+			$this->sign = '$';    // currency sign: $
2155
+			$this->sign_b4 = true;    // currency sign before or after: $TRUE  or  FALSE$
2156
+			$this->dec_plc = 2;    // decimal places: 2 = 0.00  3 = 0.000
2157
+			$this->dec_mrk = '.';    // decimal mark: (comma) ',' = 0,01   or (decimal) '.' = 0.01
2158
+			$this->thsnds = ',';    // thousands separator: (comma) ',' = 1,000   or (decimal) '.' = 1.000
2159
+		}
2160
+	}
2161
+}
2321 2162
 
2322
-    /**
2323
-     * Label text to show on the checkbox
2324
-     *
2325
-     * @var string
2326
-     */
2327
-    public $consent_checkbox_label_text;
2163
+/**
2164
+ * Class for defining what's in the EE_Config relating to registration settings
2165
+ */
2166
+class EE_Registration_Config extends EE_Config_Base
2167
+{
2328 2168
 
2329
-    /*
2169
+	/**
2170
+	 * Default registration status
2171
+	 *
2172
+	 * @var string $default_STS_ID
2173
+	 * eg 'RPP'
2174
+	 */
2175
+	public $default_STS_ID;
2176
+
2177
+	/**
2178
+	 * For new events, this will be the default value for the maximum number of tickets (equivalent to maximum number of
2179
+	 * registrations)
2180
+	 *
2181
+	 * @var int
2182
+	 */
2183
+	public $default_maximum_number_of_tickets;
2184
+
2185
+	/**
2186
+	 * level of validation to apply to email addresses
2187
+	 *
2188
+	 * @var string $email_validation_level
2189
+	 * options: 'basic', 'wp_default', 'i18n', 'i18n_dns'
2190
+	 */
2191
+	public $email_validation_level;
2192
+
2193
+	/**
2194
+	 *    whether or not to show alternate payment options during the reg process if payment status is pending
2195
+	 *
2196
+	 * @var boolean $show_pending_payment_options
2197
+	 */
2198
+	public $show_pending_payment_options;
2199
+
2200
+	/**
2201
+	 * Whether to skip the registration confirmation page
2202
+	 *
2203
+	 * @var boolean $skip_reg_confirmation
2204
+	 */
2205
+	public $skip_reg_confirmation;
2206
+
2207
+	/**
2208
+	 * an array of SPCO reg steps where:
2209
+	 *        the keys denotes the reg step order
2210
+	 *        each element consists of an array with the following elements:
2211
+	 *            "file_path" => the file path to the EE_SPCO_Reg_Step class
2212
+	 *            "class_name" => the specific EE_SPCO_Reg_Step child class name
2213
+	 *            "slug" => the URL param used to trigger the reg step
2214
+	 *
2215
+	 * @var array $reg_steps
2216
+	 */
2217
+	public $reg_steps;
2218
+
2219
+	/**
2220
+	 * Whether registration confirmation should be the last page of SPCO
2221
+	 *
2222
+	 * @var boolean $reg_confirmation_last
2223
+	 */
2224
+	public $reg_confirmation_last;
2225
+
2226
+	/**
2227
+	 * Whether or not to enable the EE Bot Trap
2228
+	 *
2229
+	 * @var boolean $use_bot_trap
2230
+	 */
2231
+	public $use_bot_trap;
2232
+
2233
+	/**
2234
+	 * Whether or not to encrypt some data sent by the EE Bot Trap
2235
+	 *
2236
+	 * @var boolean $use_encryption
2237
+	 */
2238
+	public $use_encryption;
2239
+
2240
+	/**
2241
+	 * Whether or not to use ReCaptcha
2242
+	 *
2243
+	 * @var boolean $use_captcha
2244
+	 */
2245
+	public $use_captcha;
2246
+
2247
+	/**
2248
+	 * ReCaptcha Theme
2249
+	 *
2250
+	 * @var string $recaptcha_theme
2251
+	 *    options: 'dark', 'light', 'invisible'
2252
+	 */
2253
+	public $recaptcha_theme;
2254
+
2255
+	/**
2256
+	 * ReCaptcha Badge - determines the position of the reCAPTCHA badge if using Invisible ReCaptcha.
2257
+	 *
2258
+	 * @var string $recaptcha_badge
2259
+	 *    options: 'bottomright', 'bottomleft', 'inline'
2260
+	 */
2261
+	public $recaptcha_badge;
2262
+
2263
+	/**
2264
+	 * ReCaptcha Type
2265
+	 *
2266
+	 * @var string $recaptcha_type
2267
+	 *    options: 'audio', 'image'
2268
+	 */
2269
+	public $recaptcha_type;
2270
+
2271
+	/**
2272
+	 * ReCaptcha language
2273
+	 *
2274
+	 * @var string $recaptcha_language
2275
+	 * eg 'en'
2276
+	 */
2277
+	public $recaptcha_language;
2278
+
2279
+	/**
2280
+	 * ReCaptcha public key
2281
+	 *
2282
+	 * @var string $recaptcha_publickey
2283
+	 */
2284
+	public $recaptcha_publickey;
2285
+
2286
+	/**
2287
+	 * ReCaptcha private key
2288
+	 *
2289
+	 * @var string $recaptcha_privatekey
2290
+	 */
2291
+	public $recaptcha_privatekey;
2292
+
2293
+	/**
2294
+	 * array of form names protected by ReCaptcha
2295
+	 *
2296
+	 * @var array $recaptcha_protected_forms
2297
+	 */
2298
+	public $recaptcha_protected_forms;
2299
+
2300
+	/**
2301
+	 * ReCaptcha width
2302
+	 *
2303
+	 * @var int $recaptcha_width
2304
+	 * @deprecated
2305
+	 */
2306
+	public $recaptcha_width;
2307
+
2308
+	/**
2309
+	 * Whether or not invalid attempts to directly access the registration checkout page should be tracked.
2310
+	 *
2311
+	 * @var boolean $track_invalid_checkout_access
2312
+	 */
2313
+	protected $track_invalid_checkout_access = true;
2314
+
2315
+	/**
2316
+	 * Whether or not to show the privacy policy consent checkbox
2317
+	 *
2318
+	 * @var bool
2319
+	 */
2320
+	public $consent_checkbox_enabled;
2321
+
2322
+	/**
2323
+	 * Label text to show on the checkbox
2324
+	 *
2325
+	 * @var string
2326
+	 */
2327
+	public $consent_checkbox_label_text;
2328
+
2329
+	/*
2330 2330
      * String describing how long to keep payment logs. Passed into DateTime constructor
2331 2331
      * @var string
2332 2332
      */
2333
-    public $gateway_log_lifespan = '1 week';
2334
-
2335
-    /**
2336
-     * Enable copy attendee info at form
2337
-     *
2338
-     * @var boolean $enable_copy_attendee
2339
-     */
2340
-    protected $copy_attendee_info = true;
2341
-
2342
-
2343
-    /**
2344
-     *    class constructor
2345
-     *
2346
-     * @access    public
2347
-     */
2348
-    public function __construct()
2349
-    {
2350
-        // set default registration settings
2351
-        $this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2352
-        $this->email_validation_level = 'wp_default';
2353
-        $this->show_pending_payment_options = true;
2354
-        $this->skip_reg_confirmation = true;
2355
-        $this->reg_steps = array();
2356
-        $this->reg_confirmation_last = false;
2357
-        $this->use_bot_trap = true;
2358
-        $this->use_encryption = true;
2359
-        $this->use_captcha = false;
2360
-        $this->recaptcha_theme = 'light';
2361
-        $this->recaptcha_badge = 'bottomleft';
2362
-        $this->recaptcha_type = 'image';
2363
-        $this->recaptcha_language = 'en';
2364
-        $this->recaptcha_publickey = null;
2365
-        $this->recaptcha_privatekey = null;
2366
-        $this->recaptcha_protected_forms = array();
2367
-        $this->recaptcha_width = 500;
2368
-        $this->default_maximum_number_of_tickets = 10;
2369
-        $this->consent_checkbox_enabled = false;
2370
-        $this->consent_checkbox_label_text = '';
2371
-        $this->gateway_log_lifespan = '7 days';
2372
-        $this->copy_attendee_info = true;
2373
-    }
2374
-
2375
-
2376
-    /**
2377
-     * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2378
-     *
2379
-     * @since 4.8.8.rc.019
2380
-     */
2381
-    public function do_hooks()
2382
-    {
2383
-        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2384
-        add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2385
-        add_action('setup_theme', array($this, 'setDefaultCheckboxLabelText'));
2386
-    }
2387
-
2388
-
2389
-    /**
2390
-     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the
2391
-     * EVT_default_registration_status field matches the config setting for default_STS_ID.
2392
-     */
2393
-    public function set_default_reg_status_on_EEM_Event()
2394
-    {
2395
-        EEM_Event::set_default_reg_status($this->default_STS_ID);
2396
-    }
2397
-
2398
-
2399
-    /**
2400
-     * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2401
-     * for Events matches the config setting for default_maximum_number_of_tickets
2402
-     */
2403
-    public function set_default_max_ticket_on_EEM_Event()
2404
-    {
2405
-        EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2406
-    }
2407
-
2408
-
2409
-    /**
2410
-     * Sets the default consent checkbox text. This needs to be done a bit later than when EE_Registration_Config is
2411
-     * constructed because that happens before we can get the privacy policy page's permalink.
2412
-     *
2413
-     * @throws InvalidArgumentException
2414
-     * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2415
-     * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2416
-     */
2417
-    public function setDefaultCheckboxLabelText()
2418
-    {
2419
-        if ($this->getConsentCheckboxLabelText() === null
2420
-            || $this->getConsentCheckboxLabelText() === '') {
2421
-            $opening_a_tag = '';
2422
-            $closing_a_tag = '';
2423
-            if (function_exists('get_privacy_policy_url')) {
2424
-                $privacy_page_url = get_privacy_policy_url();
2425
-                if (! empty($privacy_page_url)) {
2426
-                    $opening_a_tag = '<a href="' . $privacy_page_url . '" target="_blank">';
2427
-                    $closing_a_tag = '</a>';
2428
-                }
2429
-            }
2430
-            $loader = LoaderFactory::getLoader();
2431
-            $org_config = $loader->getShared('EE_Organization_Config');
2432
-            /**
2433
-             * @var $org_config EE_Organization_Config
2434
-             */
2435
-
2436
-            $this->setConsentCheckboxLabelText(
2437
-                sprintf(
2438
-                    esc_html__(
2439
-                        'I consent to %1$s storing and using my personal information, according to their %2$sprivacy policy%3$s.',
2440
-                        'event_espresso'
2441
-                    ),
2442
-                    $org_config->name,
2443
-                    $opening_a_tag,
2444
-                    $closing_a_tag
2445
-                )
2446
-            );
2447
-        }
2448
-    }
2449
-
2450
-
2451
-    /**
2452
-     * @return boolean
2453
-     */
2454
-    public function track_invalid_checkout_access()
2455
-    {
2456
-        return $this->track_invalid_checkout_access;
2457
-    }
2458
-
2459
-
2460
-    /**
2461
-     * @param boolean $track_invalid_checkout_access
2462
-     */
2463
-    public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2464
-    {
2465
-        $this->track_invalid_checkout_access = filter_var(
2466
-            $track_invalid_checkout_access,
2467
-            FILTER_VALIDATE_BOOLEAN
2468
-        );
2469
-    }
2470
-
2471
-    /**
2472
-     * @return boolean
2473
-     */
2474
-    public function copyAttendeeInfo()
2475
-    {
2476
-        return $this->copy_attendee_info;
2477
-    }
2478
-
2479
-
2480
-    /**
2481
-     * @param boolean $copy_attendee_info
2482
-     */
2483
-    public function setCopyAttendeeInfo($copy_attendee_info)
2484
-    {
2485
-        $this->copy_attendee_info = filter_var(
2486
-            $copy_attendee_info,
2487
-            FILTER_VALIDATE_BOOLEAN
2488
-        );
2489
-    }
2490
-
2491
-
2492
-    /**
2493
-     * Gets the options to make availalbe for the gateway log lifespan
2494
-     * @return array
2495
-     */
2496
-    public function gatewayLogLifespanOptions()
2497
-    {
2498
-        return (array) apply_filters(
2499
-            'FHEE_EE_Admin_Config__gatewayLogLifespanOptions',
2500
-            array(
2501
-                '1 second' => esc_html__('Don\'t Log At All', 'event_espresso'),
2502
-                '1 day' => esc_html__('1 Day', 'event_espresso'),
2503
-                '7 days' => esc_html__('7 Days', 'event_espresso'),
2504
-                '14 days' => esc_html__('14 Days', 'event_espresso'),
2505
-                '30 days' => esc_html__('30 Days', 'event_espresso')
2506
-            )
2507
-        );
2508
-    }
2509
-
2510
-
2511
-    /**
2512
-     * @return bool
2513
-     */
2514
-    public function isConsentCheckboxEnabled()
2515
-    {
2516
-        return $this->consent_checkbox_enabled;
2517
-    }
2518
-
2519
-
2520
-    /**
2521
-     * @param bool $consent_checkbox_enabled
2522
-     */
2523
-    public function setConsentCheckboxEnabled($consent_checkbox_enabled)
2524
-    {
2525
-        $this->consent_checkbox_enabled = filter_var(
2526
-            $consent_checkbox_enabled,
2527
-            FILTER_VALIDATE_BOOLEAN
2528
-        );
2529
-    }
2530
-
2531
-
2532
-    /**
2533
-     * @return string
2534
-     */
2535
-    public function getConsentCheckboxLabelText()
2536
-    {
2537
-        return $this->consent_checkbox_label_text;
2538
-    }
2539
-
2540
-
2541
-    /**
2542
-     * @param string $consent_checkbox_label_text
2543
-     */
2544
-    public function setConsentCheckboxLabelText($consent_checkbox_label_text)
2545
-    {
2546
-        $this->consent_checkbox_label_text = (string) $consent_checkbox_label_text;
2547
-    }
2333
+	public $gateway_log_lifespan = '1 week';
2334
+
2335
+	/**
2336
+	 * Enable copy attendee info at form
2337
+	 *
2338
+	 * @var boolean $enable_copy_attendee
2339
+	 */
2340
+	protected $copy_attendee_info = true;
2341
+
2342
+
2343
+	/**
2344
+	 *    class constructor
2345
+	 *
2346
+	 * @access    public
2347
+	 */
2348
+	public function __construct()
2349
+	{
2350
+		// set default registration settings
2351
+		$this->default_STS_ID = EEM_Registration::status_id_pending_payment;
2352
+		$this->email_validation_level = 'wp_default';
2353
+		$this->show_pending_payment_options = true;
2354
+		$this->skip_reg_confirmation = true;
2355
+		$this->reg_steps = array();
2356
+		$this->reg_confirmation_last = false;
2357
+		$this->use_bot_trap = true;
2358
+		$this->use_encryption = true;
2359
+		$this->use_captcha = false;
2360
+		$this->recaptcha_theme = 'light';
2361
+		$this->recaptcha_badge = 'bottomleft';
2362
+		$this->recaptcha_type = 'image';
2363
+		$this->recaptcha_language = 'en';
2364
+		$this->recaptcha_publickey = null;
2365
+		$this->recaptcha_privatekey = null;
2366
+		$this->recaptcha_protected_forms = array();
2367
+		$this->recaptcha_width = 500;
2368
+		$this->default_maximum_number_of_tickets = 10;
2369
+		$this->consent_checkbox_enabled = false;
2370
+		$this->consent_checkbox_label_text = '';
2371
+		$this->gateway_log_lifespan = '7 days';
2372
+		$this->copy_attendee_info = true;
2373
+	}
2374
+
2375
+
2376
+	/**
2377
+	 * This is called by the config loader and hooks are initialized AFTER the config has been populated.
2378
+	 *
2379
+	 * @since 4.8.8.rc.019
2380
+	 */
2381
+	public function do_hooks()
2382
+	{
2383
+		add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_reg_status_on_EEM_Event'));
2384
+		add_action('AHEE__EE_Config___load_core_config__end', array($this, 'set_default_max_ticket_on_EEM_Event'));
2385
+		add_action('setup_theme', array($this, 'setDefaultCheckboxLabelText'));
2386
+	}
2387
+
2388
+
2389
+	/**
2390
+	 * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the
2391
+	 * EVT_default_registration_status field matches the config setting for default_STS_ID.
2392
+	 */
2393
+	public function set_default_reg_status_on_EEM_Event()
2394
+	{
2395
+		EEM_Event::set_default_reg_status($this->default_STS_ID);
2396
+	}
2397
+
2398
+
2399
+	/**
2400
+	 * Hooked into `AHEE__EE_Config___load_core_config__end` to ensure the default for the EVT_additional_limit field
2401
+	 * for Events matches the config setting for default_maximum_number_of_tickets
2402
+	 */
2403
+	public function set_default_max_ticket_on_EEM_Event()
2404
+	{
2405
+		EEM_Event::set_default_additional_limit($this->default_maximum_number_of_tickets);
2406
+	}
2407
+
2408
+
2409
+	/**
2410
+	 * Sets the default consent checkbox text. This needs to be done a bit later than when EE_Registration_Config is
2411
+	 * constructed because that happens before we can get the privacy policy page's permalink.
2412
+	 *
2413
+	 * @throws InvalidArgumentException
2414
+	 * @throws \EventEspresso\core\exceptions\InvalidDataTypeException
2415
+	 * @throws \EventEspresso\core\exceptions\InvalidInterfaceException
2416
+	 */
2417
+	public function setDefaultCheckboxLabelText()
2418
+	{
2419
+		if ($this->getConsentCheckboxLabelText() === null
2420
+			|| $this->getConsentCheckboxLabelText() === '') {
2421
+			$opening_a_tag = '';
2422
+			$closing_a_tag = '';
2423
+			if (function_exists('get_privacy_policy_url')) {
2424
+				$privacy_page_url = get_privacy_policy_url();
2425
+				if (! empty($privacy_page_url)) {
2426
+					$opening_a_tag = '<a href="' . $privacy_page_url . '" target="_blank">';
2427
+					$closing_a_tag = '</a>';
2428
+				}
2429
+			}
2430
+			$loader = LoaderFactory::getLoader();
2431
+			$org_config = $loader->getShared('EE_Organization_Config');
2432
+			/**
2433
+			 * @var $org_config EE_Organization_Config
2434
+			 */
2435
+
2436
+			$this->setConsentCheckboxLabelText(
2437
+				sprintf(
2438
+					esc_html__(
2439
+						'I consent to %1$s storing and using my personal information, according to their %2$sprivacy policy%3$s.',
2440
+						'event_espresso'
2441
+					),
2442
+					$org_config->name,
2443
+					$opening_a_tag,
2444
+					$closing_a_tag
2445
+				)
2446
+			);
2447
+		}
2448
+	}
2449
+
2450
+
2451
+	/**
2452
+	 * @return boolean
2453
+	 */
2454
+	public function track_invalid_checkout_access()
2455
+	{
2456
+		return $this->track_invalid_checkout_access;
2457
+	}
2458
+
2459
+
2460
+	/**
2461
+	 * @param boolean $track_invalid_checkout_access
2462
+	 */
2463
+	public function set_track_invalid_checkout_access($track_invalid_checkout_access)
2464
+	{
2465
+		$this->track_invalid_checkout_access = filter_var(
2466
+			$track_invalid_checkout_access,
2467
+			FILTER_VALIDATE_BOOLEAN
2468
+		);
2469
+	}
2470
+
2471
+	/**
2472
+	 * @return boolean
2473
+	 */
2474
+	public function copyAttendeeInfo()
2475
+	{
2476
+		return $this->copy_attendee_info;
2477
+	}
2478
+
2479
+
2480
+	/**
2481
+	 * @param boolean $copy_attendee_info
2482
+	 */
2483
+	public function setCopyAttendeeInfo($copy_attendee_info)
2484
+	{
2485
+		$this->copy_attendee_info = filter_var(
2486
+			$copy_attendee_info,
2487
+			FILTER_VALIDATE_BOOLEAN
2488
+		);
2489
+	}
2490
+
2491
+
2492
+	/**
2493
+	 * Gets the options to make availalbe for the gateway log lifespan
2494
+	 * @return array
2495
+	 */
2496
+	public function gatewayLogLifespanOptions()
2497
+	{
2498
+		return (array) apply_filters(
2499
+			'FHEE_EE_Admin_Config__gatewayLogLifespanOptions',
2500
+			array(
2501
+				'1 second' => esc_html__('Don\'t Log At All', 'event_espresso'),
2502
+				'1 day' => esc_html__('1 Day', 'event_espresso'),
2503
+				'7 days' => esc_html__('7 Days', 'event_espresso'),
2504
+				'14 days' => esc_html__('14 Days', 'event_espresso'),
2505
+				'30 days' => esc_html__('30 Days', 'event_espresso')
2506
+			)
2507
+		);
2508
+	}
2509
+
2510
+
2511
+	/**
2512
+	 * @return bool
2513
+	 */
2514
+	public function isConsentCheckboxEnabled()
2515
+	{
2516
+		return $this->consent_checkbox_enabled;
2517
+	}
2518
+
2519
+
2520
+	/**
2521
+	 * @param bool $consent_checkbox_enabled
2522
+	 */
2523
+	public function setConsentCheckboxEnabled($consent_checkbox_enabled)
2524
+	{
2525
+		$this->consent_checkbox_enabled = filter_var(
2526
+			$consent_checkbox_enabled,
2527
+			FILTER_VALIDATE_BOOLEAN
2528
+		);
2529
+	}
2530
+
2531
+
2532
+	/**
2533
+	 * @return string
2534
+	 */
2535
+	public function getConsentCheckboxLabelText()
2536
+	{
2537
+		return $this->consent_checkbox_label_text;
2538
+	}
2539
+
2540
+
2541
+	/**
2542
+	 * @param string $consent_checkbox_label_text
2543
+	 */
2544
+	public function setConsentCheckboxLabelText($consent_checkbox_label_text)
2545
+	{
2546
+		$this->consent_checkbox_label_text = (string) $consent_checkbox_label_text;
2547
+	}
2548 2548
 }
2549 2549
 
2550 2550
 /**
@@ -2553,180 +2553,180 @@  discard block
 block discarded – undo
2553 2553
 class EE_Admin_Config extends EE_Config_Base
2554 2554
 {
2555 2555
 
2556
-    /**
2557
-     * @var boolean $useAdvancedEditor
2558
-     */
2559
-    private $useAdvancedEditor;
2560
-
2561
-    /**
2562
-     * @var boolean $use_personnel_manager
2563
-     */
2564
-    public $use_personnel_manager;
2565
-
2566
-    /**
2567
-     * @var boolean $use_dashboard_widget
2568
-     */
2569
-    public $use_dashboard_widget;
2570
-
2571
-    /**
2572
-     * @var int $events_in_dashboard
2573
-     */
2574
-    public $events_in_dashboard;
2575
-
2576
-    /**
2577
-     * @var boolean $use_event_timezones
2578
-     */
2579
-    public $use_event_timezones;
2580
-
2581
-    /**
2582
-     * @var string $log_file_name
2583
-     */
2584
-    public $log_file_name;
2585
-
2586
-    /**
2587
-     * @var string $debug_file_name
2588
-     */
2589
-    public $debug_file_name;
2590
-
2591
-    /**
2592
-     * @var boolean $use_remote_logging
2593
-     */
2594
-    public $use_remote_logging;
2595
-
2596
-    /**
2597
-     * @var string $remote_logging_url
2598
-     */
2599
-    public $remote_logging_url;
2600
-
2601
-    /**
2602
-     * @var boolean $show_reg_footer
2603
-     */
2604
-    public $show_reg_footer;
2605
-
2606
-    /**
2607
-     * @var string $affiliate_id
2608
-     */
2609
-    public $affiliate_id;
2610
-
2611
-    /**
2612
-     * help tours on or off (global setting)
2613
-     *
2614
-     * @var boolean
2615
-     */
2616
-    public $help_tour_activation;
2617
-
2618
-    /**
2619
-     * adds extra layer of encoding to session data to prevent serialization errors
2620
-     * but is incompatible with some server configuration errors
2621
-     * if you get "500 internal server errors" during registration, try turning this on
2622
-     * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2623
-     *
2624
-     * @var boolean $encode_session_data
2625
-     */
2626
-    private $encode_session_data = false;
2627
-
2628
-
2629
-    /**
2630
-     *    class constructor
2631
-     *
2632
-     * @access    public
2633
-     */
2634
-    public function __construct()
2635
-    {
2636
-        // set default general admin settings
2637
-        $this->useAdvancedEditor = false;
2638
-        $this->use_personnel_manager = true;
2639
-        $this->use_dashboard_widget = true;
2640
-        $this->events_in_dashboard = 30;
2641
-        $this->use_event_timezones = false;
2642
-        $this->use_remote_logging = false;
2643
-        $this->remote_logging_url = null;
2644
-        $this->show_reg_footer = apply_filters(
2645
-            'FHEE__EE_Admin_Config__show_reg_footer__default',
2646
-            false
2647
-        );
2648
-        $this->affiliate_id = 'default';
2649
-        $this->help_tour_activation = true;
2650
-        $this->encode_session_data = false;
2651
-    }
2652
-
2653
-
2654
-    /**
2655
-     * @param bool $reset
2656
-     * @return string
2657
-     */
2658
-    public function log_file_name($reset = false)
2659
-    {
2660
-        if (empty($this->log_file_name) || $reset) {
2661
-            $this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2662
-            EE_Config::instance()->update_espresso_config(false, false);
2663
-        }
2664
-        return $this->log_file_name;
2665
-    }
2666
-
2667
-
2668
-    /**
2669
-     * @param bool $reset
2670
-     * @return string
2671
-     */
2672
-    public function debug_file_name($reset = false)
2673
-    {
2674
-        if (empty($this->debug_file_name) || $reset) {
2675
-            $this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2676
-            EE_Config::instance()->update_espresso_config(false, false);
2677
-        }
2678
-        return $this->debug_file_name;
2679
-    }
2680
-
2681
-
2682
-    /**
2683
-     * @return string
2684
-     */
2685
-    public function affiliate_id()
2686
-    {
2687
-        return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2688
-    }
2689
-
2690
-
2691
-    /**
2692
-     * @return boolean
2693
-     */
2694
-    public function encode_session_data()
2695
-    {
2696
-        return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2697
-    }
2698
-
2699
-
2700
-    /**
2701
-     * @param boolean $encode_session_data
2702
-     */
2703
-    public function set_encode_session_data($encode_session_data)
2704
-    {
2705
-        $this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2706
-    }
2707
-
2708
-    /**
2709
-     * @return boolean
2710
-     */
2711
-    public function useAdvancedEditor()
2712
-    {
2713
-        $domain = LoaderFactory::getLoader()->getShared('EventEspresso\core\domain\Domain');
2714
-        return $this->useAdvancedEditor && $domain->isCaffeinated();
2715
-    }
2716
-
2717
-    /**
2718
-     * @param boolean $use_advanced_editor
2719
-     */
2720
-    public function setUseAdvancedEditor($use_advanced_editor = true)
2721
-    {
2722
-        $this->useAdvancedEditor = filter_var(
2723
-            apply_filters(
2724
-                'FHEE__EE_Admin_Config__setUseAdvancedEditor__use_advanced_editor',
2725
-                $use_advanced_editor
2726
-            ),
2727
-            FILTER_VALIDATE_BOOLEAN
2728
-        );
2729
-    }
2556
+	/**
2557
+	 * @var boolean $useAdvancedEditor
2558
+	 */
2559
+	private $useAdvancedEditor;
2560
+
2561
+	/**
2562
+	 * @var boolean $use_personnel_manager
2563
+	 */
2564
+	public $use_personnel_manager;
2565
+
2566
+	/**
2567
+	 * @var boolean $use_dashboard_widget
2568
+	 */
2569
+	public $use_dashboard_widget;
2570
+
2571
+	/**
2572
+	 * @var int $events_in_dashboard
2573
+	 */
2574
+	public $events_in_dashboard;
2575
+
2576
+	/**
2577
+	 * @var boolean $use_event_timezones
2578
+	 */
2579
+	public $use_event_timezones;
2580
+
2581
+	/**
2582
+	 * @var string $log_file_name
2583
+	 */
2584
+	public $log_file_name;
2585
+
2586
+	/**
2587
+	 * @var string $debug_file_name
2588
+	 */
2589
+	public $debug_file_name;
2590
+
2591
+	/**
2592
+	 * @var boolean $use_remote_logging
2593
+	 */
2594
+	public $use_remote_logging;
2595
+
2596
+	/**
2597
+	 * @var string $remote_logging_url
2598
+	 */
2599
+	public $remote_logging_url;
2600
+
2601
+	/**
2602
+	 * @var boolean $show_reg_footer
2603
+	 */
2604
+	public $show_reg_footer;
2605
+
2606
+	/**
2607
+	 * @var string $affiliate_id
2608
+	 */
2609
+	public $affiliate_id;
2610
+
2611
+	/**
2612
+	 * help tours on or off (global setting)
2613
+	 *
2614
+	 * @var boolean
2615
+	 */
2616
+	public $help_tour_activation;
2617
+
2618
+	/**
2619
+	 * adds extra layer of encoding to session data to prevent serialization errors
2620
+	 * but is incompatible with some server configuration errors
2621
+	 * if you get "500 internal server errors" during registration, try turning this on
2622
+	 * if you get PHP fatal errors regarding base 64 methods not defined, then turn this off
2623
+	 *
2624
+	 * @var boolean $encode_session_data
2625
+	 */
2626
+	private $encode_session_data = false;
2627
+
2628
+
2629
+	/**
2630
+	 *    class constructor
2631
+	 *
2632
+	 * @access    public
2633
+	 */
2634
+	public function __construct()
2635
+	{
2636
+		// set default general admin settings
2637
+		$this->useAdvancedEditor = false;
2638
+		$this->use_personnel_manager = true;
2639
+		$this->use_dashboard_widget = true;
2640
+		$this->events_in_dashboard = 30;
2641
+		$this->use_event_timezones = false;
2642
+		$this->use_remote_logging = false;
2643
+		$this->remote_logging_url = null;
2644
+		$this->show_reg_footer = apply_filters(
2645
+			'FHEE__EE_Admin_Config__show_reg_footer__default',
2646
+			false
2647
+		);
2648
+		$this->affiliate_id = 'default';
2649
+		$this->help_tour_activation = true;
2650
+		$this->encode_session_data = false;
2651
+	}
2652
+
2653
+
2654
+	/**
2655
+	 * @param bool $reset
2656
+	 * @return string
2657
+	 */
2658
+	public function log_file_name($reset = false)
2659
+	{
2660
+		if (empty($this->log_file_name) || $reset) {
2661
+			$this->log_file_name = sanitize_key('espresso_log_' . md5(uniqid('', true))) . '.txt';
2662
+			EE_Config::instance()->update_espresso_config(false, false);
2663
+		}
2664
+		return $this->log_file_name;
2665
+	}
2666
+
2667
+
2668
+	/**
2669
+	 * @param bool $reset
2670
+	 * @return string
2671
+	 */
2672
+	public function debug_file_name($reset = false)
2673
+	{
2674
+		if (empty($this->debug_file_name) || $reset) {
2675
+			$this->debug_file_name = sanitize_key('espresso_debug_' . md5(uniqid('', true))) . '.txt';
2676
+			EE_Config::instance()->update_espresso_config(false, false);
2677
+		}
2678
+		return $this->debug_file_name;
2679
+	}
2680
+
2681
+
2682
+	/**
2683
+	 * @return string
2684
+	 */
2685
+	public function affiliate_id()
2686
+	{
2687
+		return ! empty($this->affiliate_id) ? $this->affiliate_id : 'default';
2688
+	}
2689
+
2690
+
2691
+	/**
2692
+	 * @return boolean
2693
+	 */
2694
+	public function encode_session_data()
2695
+	{
2696
+		return filter_var($this->encode_session_data, FILTER_VALIDATE_BOOLEAN);
2697
+	}
2698
+
2699
+
2700
+	/**
2701
+	 * @param boolean $encode_session_data
2702
+	 */
2703
+	public function set_encode_session_data($encode_session_data)
2704
+	{
2705
+		$this->encode_session_data = filter_var($encode_session_data, FILTER_VALIDATE_BOOLEAN);
2706
+	}
2707
+
2708
+	/**
2709
+	 * @return boolean
2710
+	 */
2711
+	public function useAdvancedEditor()
2712
+	{
2713
+		$domain = LoaderFactory::getLoader()->getShared('EventEspresso\core\domain\Domain');
2714
+		return $this->useAdvancedEditor && $domain->isCaffeinated();
2715
+	}
2716
+
2717
+	/**
2718
+	 * @param boolean $use_advanced_editor
2719
+	 */
2720
+	public function setUseAdvancedEditor($use_advanced_editor = true)
2721
+	{
2722
+		$this->useAdvancedEditor = filter_var(
2723
+			apply_filters(
2724
+				'FHEE__EE_Admin_Config__setUseAdvancedEditor__use_advanced_editor',
2725
+				$use_advanced_editor
2726
+			),
2727
+			FILTER_VALIDATE_BOOLEAN
2728
+		);
2729
+	}
2730 2730
 }
2731 2731
 
2732 2732
 /**
@@ -2735,70 +2735,70 @@  discard block
 block discarded – undo
2735 2735
 class EE_Template_Config extends EE_Config_Base
2736 2736
 {
2737 2737
 
2738
-    /**
2739
-     * @var boolean $enable_default_style
2740
-     */
2741
-    public $enable_default_style;
2742
-
2743
-    /**
2744
-     * @var string $custom_style_sheet
2745
-     */
2746
-    public $custom_style_sheet;
2747
-
2748
-    /**
2749
-     * @var boolean $display_address_in_regform
2750
-     */
2751
-    public $display_address_in_regform;
2752
-
2753
-    /**
2754
-     * @var int $display_description_on_multi_reg_page
2755
-     */
2756
-    public $display_description_on_multi_reg_page;
2757
-
2758
-    /**
2759
-     * @var boolean $use_custom_templates
2760
-     */
2761
-    public $use_custom_templates;
2762
-
2763
-    /**
2764
-     * @var string $current_espresso_theme
2765
-     */
2766
-    public $current_espresso_theme;
2767
-
2768
-    /**
2769
-     * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2770
-     */
2771
-    public $EED_Ticket_Selector;
2772
-
2773
-    /**
2774
-     * @var EE_Event_Single_Config $EED_Event_Single
2775
-     */
2776
-    public $EED_Event_Single;
2777
-
2778
-    /**
2779
-     * @var EE_Events_Archive_Config $EED_Events_Archive
2780
-     */
2781
-    public $EED_Events_Archive;
2782
-
2783
-
2784
-    /**
2785
-     *    class constructor
2786
-     *
2787
-     * @access    public
2788
-     */
2789
-    public function __construct()
2790
-    {
2791
-        // set default template settings
2792
-        $this->enable_default_style = true;
2793
-        $this->custom_style_sheet = null;
2794
-        $this->display_address_in_regform = true;
2795
-        $this->display_description_on_multi_reg_page = false;
2796
-        $this->use_custom_templates = false;
2797
-        $this->current_espresso_theme = 'Espresso_Arabica_2014';
2798
-        $this->EED_Event_Single = null;
2799
-        $this->EED_Events_Archive = null;
2800
-        $this->EED_Ticket_Selector = null;
2801
-    }
2738
+	/**
2739
+	 * @var boolean $enable_default_style
2740
+	 */
2741
+	public $enable_default_style;
2742
+
2743
+	/**
2744
+	 * @var string $custom_style_sheet
2745
+	 */
2746
+	public $custom_style_sheet;
2747
+
2748
+	/**
2749
+	 * @var boolean $display_address_in_regform
2750
+	 */
2751
+	public $display_address_in_regform;
2752
+
2753
+	/**
2754
+	 * @var int $display_description_on_multi_reg_page
2755
+	 */
2756
+	public $display_description_on_multi_reg_page;
2757
+
2758
+	/**
2759
+	 * @var boolean $use_custom_templates
2760
+	 */
2761
+	public $use_custom_templates;
2762
+
2763
+	/**
2764
+	 * @var string $current_espresso_theme
2765
+	 */
2766
+	public $current_espresso_theme;
2767
+
2768
+	/**
2769
+	 * @var EE_Ticket_Selector_Config $EED_Ticket_Selector
2770
+	 */
2771
+	public $EED_Ticket_Selector;
2772
+
2773
+	/**
2774
+	 * @var EE_Event_Single_Config $EED_Event_Single
2775
+	 */
2776
+	public $EED_Event_Single;
2777
+
2778
+	/**
2779
+	 * @var EE_Events_Archive_Config $EED_Events_Archive
2780
+	 */
2781
+	public $EED_Events_Archive;
2782
+
2783
+
2784
+	/**
2785
+	 *    class constructor
2786
+	 *
2787
+	 * @access    public
2788
+	 */
2789
+	public function __construct()
2790
+	{
2791
+		// set default template settings
2792
+		$this->enable_default_style = true;
2793
+		$this->custom_style_sheet = null;
2794
+		$this->display_address_in_regform = true;
2795
+		$this->display_description_on_multi_reg_page = false;
2796
+		$this->use_custom_templates = false;
2797
+		$this->current_espresso_theme = 'Espresso_Arabica_2014';
2798
+		$this->EED_Event_Single = null;
2799
+		$this->EED_Events_Archive = null;
2800
+		$this->EED_Ticket_Selector = null;
2801
+	}
2802 2802
 }
2803 2803
 
2804 2804
 /**
@@ -2807,114 +2807,114 @@  discard block
 block discarded – undo
2807 2807
 class EE_Map_Config extends EE_Config_Base
2808 2808
 {
2809 2809
 
2810
-    /**
2811
-     * @var boolean $use_google_maps
2812
-     */
2813
-    public $use_google_maps;
2814
-
2815
-    /**
2816
-     * @var string $api_key
2817
-     */
2818
-    public $google_map_api_key;
2819
-
2820
-    /**
2821
-     * @var int $event_details_map_width
2822
-     */
2823
-    public $event_details_map_width;
2824
-
2825
-    /**
2826
-     * @var int $event_details_map_height
2827
-     */
2828
-    public $event_details_map_height;
2829
-
2830
-    /**
2831
-     * @var int $event_details_map_zoom
2832
-     */
2833
-    public $event_details_map_zoom;
2834
-
2835
-    /**
2836
-     * @var boolean $event_details_display_nav
2837
-     */
2838
-    public $event_details_display_nav;
2839
-
2840
-    /**
2841
-     * @var boolean $event_details_nav_size
2842
-     */
2843
-    public $event_details_nav_size;
2844
-
2845
-    /**
2846
-     * @var string $event_details_control_type
2847
-     */
2848
-    public $event_details_control_type;
2849
-
2850
-    /**
2851
-     * @var string $event_details_map_align
2852
-     */
2853
-    public $event_details_map_align;
2854
-
2855
-    /**
2856
-     * @var int $event_list_map_width
2857
-     */
2858
-    public $event_list_map_width;
2859
-
2860
-    /**
2861
-     * @var int $event_list_map_height
2862
-     */
2863
-    public $event_list_map_height;
2864
-
2865
-    /**
2866
-     * @var int $event_list_map_zoom
2867
-     */
2868
-    public $event_list_map_zoom;
2869
-
2870
-    /**
2871
-     * @var boolean $event_list_display_nav
2872
-     */
2873
-    public $event_list_display_nav;
2874
-
2875
-    /**
2876
-     * @var boolean $event_list_nav_size
2877
-     */
2878
-    public $event_list_nav_size;
2879
-
2880
-    /**
2881
-     * @var string $event_list_control_type
2882
-     */
2883
-    public $event_list_control_type;
2884
-
2885
-    /**
2886
-     * @var string $event_list_map_align
2887
-     */
2888
-    public $event_list_map_align;
2889
-
2890
-
2891
-    /**
2892
-     *    class constructor
2893
-     *
2894
-     * @access    public
2895
-     */
2896
-    public function __construct()
2897
-    {
2898
-        // set default map settings
2899
-        $this->use_google_maps = true;
2900
-        $this->google_map_api_key = '';
2901
-        // for event details pages (reg page)
2902
-        $this->event_details_map_width = 585;            // ee_map_width_single
2903
-        $this->event_details_map_height = 362;            // ee_map_height_single
2904
-        $this->event_details_map_zoom = 14;            // ee_map_zoom_single
2905
-        $this->event_details_display_nav = true;            // ee_map_nav_display_single
2906
-        $this->event_details_nav_size = false;            // ee_map_nav_size_single
2907
-        $this->event_details_control_type = 'default';        // ee_map_type_control_single
2908
-        $this->event_details_map_align = 'center';            // ee_map_align_single
2909
-        // for event list pages
2910
-        $this->event_list_map_width = 300;            // ee_map_width
2911
-        $this->event_list_map_height = 185;        // ee_map_height
2912
-        $this->event_list_map_zoom = 12;            // ee_map_zoom
2913
-        $this->event_list_display_nav = false;        // ee_map_nav_display
2914
-        $this->event_list_nav_size = true;            // ee_map_nav_size
2915
-        $this->event_list_control_type = 'dropdown';        // ee_map_type_control
2916
-        $this->event_list_map_align = 'center';            // ee_map_align
2917
-    }
2810
+	/**
2811
+	 * @var boolean $use_google_maps
2812
+	 */
2813
+	public $use_google_maps;
2814
+
2815
+	/**
2816
+	 * @var string $api_key
2817
+	 */
2818
+	public $google_map_api_key;
2819
+
2820
+	/**
2821
+	 * @var int $event_details_map_width
2822
+	 */
2823
+	public $event_details_map_width;
2824
+
2825
+	/**
2826
+	 * @var int $event_details_map_height
2827
+	 */
2828
+	public $event_details_map_height;
2829
+
2830
+	/**
2831
+	 * @var int $event_details_map_zoom
2832
+	 */
2833
+	public $event_details_map_zoom;
2834
+
2835
+	/**
2836
+	 * @var boolean $event_details_display_nav
2837
+	 */
2838
+	public $event_details_display_nav;
2839
+
2840
+	/**
2841
+	 * @var boolean $event_details_nav_size
2842
+	 */
2843
+	public $event_details_nav_size;
2844
+
2845
+	/**
2846
+	 * @var string $event_details_control_type
2847
+	 */
2848
+	public $event_details_control_type;
2849
+
2850
+	/**
2851
+	 * @var string $event_details_map_align
2852
+	 */
2853
+	public $event_details_map_align;
2854
+
2855
+	/**
2856
+	 * @var int $event_list_map_width
2857
+	 */
2858
+	public $event_list_map_width;
2859
+
2860
+	/**
2861
+	 * @var int $event_list_map_height
2862
+	 */
2863
+	public $event_list_map_height;
2864
+
2865
+	/**
2866
+	 * @var int $event_list_map_zoom
2867
+	 */
2868
+	public $event_list_map_zoom;
2869
+
2870
+	/**
2871
+	 * @var boolean $event_list_display_nav
2872
+	 */
2873
+	public $event_list_display_nav;
2874
+
2875
+	/**
2876
+	 * @var boolean $event_list_nav_size
2877
+	 */
2878
+	public $event_list_nav_size;
2879
+
2880
+	/**
2881
+	 * @var string $event_list_control_type
2882
+	 */
2883
+	public $event_list_control_type;
2884
+
2885
+	/**
2886
+	 * @var string $event_list_map_align
2887
+	 */
2888
+	public $event_list_map_align;
2889
+
2890
+
2891
+	/**
2892
+	 *    class constructor
2893
+	 *
2894
+	 * @access    public
2895
+	 */
2896
+	public function __construct()
2897
+	{
2898
+		// set default map settings
2899
+		$this->use_google_maps = true;
2900
+		$this->google_map_api_key = '';
2901
+		// for event details pages (reg page)
2902
+		$this->event_details_map_width = 585;            // ee_map_width_single
2903
+		$this->event_details_map_height = 362;            // ee_map_height_single
2904
+		$this->event_details_map_zoom = 14;            // ee_map_zoom_single
2905
+		$this->event_details_display_nav = true;            // ee_map_nav_display_single
2906
+		$this->event_details_nav_size = false;            // ee_map_nav_size_single
2907
+		$this->event_details_control_type = 'default';        // ee_map_type_control_single
2908
+		$this->event_details_map_align = 'center';            // ee_map_align_single
2909
+		// for event list pages
2910
+		$this->event_list_map_width = 300;            // ee_map_width
2911
+		$this->event_list_map_height = 185;        // ee_map_height
2912
+		$this->event_list_map_zoom = 12;            // ee_map_zoom
2913
+		$this->event_list_display_nav = false;        // ee_map_nav_display
2914
+		$this->event_list_nav_size = true;            // ee_map_nav_size
2915
+		$this->event_list_control_type = 'dropdown';        // ee_map_type_control
2916
+		$this->event_list_map_align = 'center';            // ee_map_align
2917
+	}
2918 2918
 }
2919 2919
 
2920 2920
 /**
@@ -2923,46 +2923,46 @@  discard block
 block discarded – undo
2923 2923
 class EE_Events_Archive_Config extends EE_Config_Base
2924 2924
 {
2925 2925
 
2926
-    public $display_status_banner;
2926
+	public $display_status_banner;
2927 2927
 
2928
-    public $display_description;
2928
+	public $display_description;
2929 2929
 
2930
-    public $display_ticket_selector;
2930
+	public $display_ticket_selector;
2931 2931
 
2932
-    public $display_datetimes;
2932
+	public $display_datetimes;
2933 2933
 
2934
-    public $display_venue;
2934
+	public $display_venue;
2935 2935
 
2936
-    public $display_expired_events;
2936
+	public $display_expired_events;
2937 2937
 
2938
-    public $use_sortable_display_order;
2938
+	public $use_sortable_display_order;
2939 2939
 
2940
-    public $display_order_tickets;
2940
+	public $display_order_tickets;
2941 2941
 
2942
-    public $display_order_datetimes;
2942
+	public $display_order_datetimes;
2943 2943
 
2944
-    public $display_order_event;
2944
+	public $display_order_event;
2945 2945
 
2946
-    public $display_order_venue;
2946
+	public $display_order_venue;
2947 2947
 
2948 2948
 
2949
-    /**
2950
-     *    class constructor
2951
-     */
2952
-    public function __construct()
2953
-    {
2954
-        $this->display_status_banner = 0;
2955
-        $this->display_description = 1;
2956
-        $this->display_ticket_selector = 0;
2957
-        $this->display_datetimes = 1;
2958
-        $this->display_venue = 0;
2959
-        $this->display_expired_events = 0;
2960
-        $this->use_sortable_display_order = false;
2961
-        $this->display_order_tickets = 100;
2962
-        $this->display_order_datetimes = 110;
2963
-        $this->display_order_event = 120;
2964
-        $this->display_order_venue = 130;
2965
-    }
2949
+	/**
2950
+	 *    class constructor
2951
+	 */
2952
+	public function __construct()
2953
+	{
2954
+		$this->display_status_banner = 0;
2955
+		$this->display_description = 1;
2956
+		$this->display_ticket_selector = 0;
2957
+		$this->display_datetimes = 1;
2958
+		$this->display_venue = 0;
2959
+		$this->display_expired_events = 0;
2960
+		$this->use_sortable_display_order = false;
2961
+		$this->display_order_tickets = 100;
2962
+		$this->display_order_datetimes = 110;
2963
+		$this->display_order_event = 120;
2964
+		$this->display_order_venue = 130;
2965
+	}
2966 2966
 }
2967 2967
 
2968 2968
 /**
@@ -2971,34 +2971,34 @@  discard block
 block discarded – undo
2971 2971
 class EE_Event_Single_Config extends EE_Config_Base
2972 2972
 {
2973 2973
 
2974
-    public $display_status_banner_single;
2974
+	public $display_status_banner_single;
2975 2975
 
2976
-    public $display_venue;
2976
+	public $display_venue;
2977 2977
 
2978
-    public $use_sortable_display_order;
2978
+	public $use_sortable_display_order;
2979 2979
 
2980
-    public $display_order_tickets;
2980
+	public $display_order_tickets;
2981 2981
 
2982
-    public $display_order_datetimes;
2982
+	public $display_order_datetimes;
2983 2983
 
2984
-    public $display_order_event;
2984
+	public $display_order_event;
2985 2985
 
2986
-    public $display_order_venue;
2986
+	public $display_order_venue;
2987 2987
 
2988 2988
 
2989
-    /**
2990
-     *    class constructor
2991
-     */
2992
-    public function __construct()
2993
-    {
2994
-        $this->display_status_banner_single = 0;
2995
-        $this->display_venue = 1;
2996
-        $this->use_sortable_display_order = false;
2997
-        $this->display_order_tickets = 100;
2998
-        $this->display_order_datetimes = 110;
2999
-        $this->display_order_event = 120;
3000
-        $this->display_order_venue = 130;
3001
-    }
2989
+	/**
2990
+	 *    class constructor
2991
+	 */
2992
+	public function __construct()
2993
+	{
2994
+		$this->display_status_banner_single = 0;
2995
+		$this->display_venue = 1;
2996
+		$this->use_sortable_display_order = false;
2997
+		$this->display_order_tickets = 100;
2998
+		$this->display_order_datetimes = 110;
2999
+		$this->display_order_event = 120;
3000
+		$this->display_order_venue = 130;
3001
+	}
3002 3002
 }
3003 3003
 
3004 3004
 /**
@@ -3007,172 +3007,172 @@  discard block
 block discarded – undo
3007 3007
 class EE_Ticket_Selector_Config extends EE_Config_Base
3008 3008
 {
3009 3009
 
3010
-    /**
3011
-     * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
3012
-     */
3013
-    const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
3014
-
3015
-    /**
3016
-     * constant to indicate that a datetime selector should only be shown for ticket selectors
3017
-     * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
3018
-     */
3019
-    const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
3020
-
3021
-    /**
3022
-     * @var boolean $show_ticket_sale_columns
3023
-     */
3024
-    public $show_ticket_sale_columns;
3025
-
3026
-    /**
3027
-     * @var boolean $show_ticket_details
3028
-     */
3029
-    public $show_ticket_details;
3030
-
3031
-    /**
3032
-     * @var boolean $show_expired_tickets
3033
-     */
3034
-    public $show_expired_tickets;
3035
-
3036
-    /**
3037
-     * whether or not to display a dropdown box populated with event datetimes
3038
-     * that toggles which tickets are displayed for a ticket selector.
3039
-     * uses one of the *_DATETIME_SELECTOR constants defined above
3040
-     *
3041
-     * @var string $show_datetime_selector
3042
-     */
3043
-    private $show_datetime_selector = 'no_datetime_selector';
3044
-
3045
-    /**
3046
-     * the number of datetimes an event has to have before conditionally displaying a datetime selector
3047
-     *
3048
-     * @var int $datetime_selector_threshold
3049
-     */
3050
-    private $datetime_selector_threshold = 3;
3051
-
3052
-    /**
3053
-     * determines the maximum number of "checked" dates in the date and time filter
3054
-     *
3055
-     * @var int $datetime_selector_checked
3056
-     */
3057
-    private $datetime_selector_max_checked = 10;
3058
-
3059
-
3060
-    /**
3061
-     *    class constructor
3062
-     */
3063
-    public function __construct()
3064
-    {
3065
-        $this->show_ticket_sale_columns = true;
3066
-        $this->show_ticket_details = true;
3067
-        $this->show_expired_tickets = true;
3068
-        $this->show_datetime_selector = \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3069
-        $this->datetime_selector_threshold = 3;
3070
-        $this->datetime_selector_max_checked = 10;
3071
-    }
3072
-
3073
-
3074
-    /**
3075
-     * returns true if a datetime selector should be displayed
3076
-     *
3077
-     * @param array $datetimes
3078
-     * @return bool
3079
-     */
3080
-    public function showDatetimeSelector(array $datetimes)
3081
-    {
3082
-        // if the settings are NOT: don't show OR below threshold, THEN active = true
3083
-        return ! (
3084
-            $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3085
-            || (
3086
-                $this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3087
-                && count($datetimes) < $this->getDatetimeSelectorThreshold()
3088
-            )
3089
-        );
3090
-    }
3091
-
3092
-
3093
-    /**
3094
-     * @return string
3095
-     */
3096
-    public function getShowDatetimeSelector()
3097
-    {
3098
-        return $this->show_datetime_selector;
3099
-    }
3100
-
3101
-
3102
-    /**
3103
-     * @param bool $keys_only
3104
-     * @return array
3105
-     */
3106
-    public function getShowDatetimeSelectorOptions($keys_only = true)
3107
-    {
3108
-        return $keys_only
3109
-            ? array(
3110
-                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3111
-                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3112
-            )
3113
-            : array(
3114
-                \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3115
-                    'Do not show date & time filter',
3116
-                    'event_espresso'
3117
-                ),
3118
-                \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3119
-                    'Maybe show date & time filter',
3120
-                    'event_espresso'
3121
-                ),
3122
-            );
3123
-    }
3124
-
3125
-
3126
-    /**
3127
-     * @param string $show_datetime_selector
3128
-     */
3129
-    public function setShowDatetimeSelector($show_datetime_selector)
3130
-    {
3131
-        $this->show_datetime_selector = in_array(
3132
-            $show_datetime_selector,
3133
-            $this->getShowDatetimeSelectorOptions(),
3134
-            true
3135
-        )
3136
-            ? $show_datetime_selector
3137
-            : \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3138
-    }
3139
-
3140
-
3141
-    /**
3142
-     * @return int
3143
-     */
3144
-    public function getDatetimeSelectorThreshold()
3145
-    {
3146
-        return $this->datetime_selector_threshold;
3147
-    }
3148
-
3149
-
3150
-    /**
3151
-     * @param int $datetime_selector_threshold
3152
-     */
3153
-    public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3154
-    {
3155
-        $datetime_selector_threshold = absint($datetime_selector_threshold);
3156
-        $this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3157
-    }
3158
-
3159
-
3160
-    /**
3161
-     * @return int
3162
-     */
3163
-    public function getDatetimeSelectorMaxChecked()
3164
-    {
3165
-        return $this->datetime_selector_max_checked;
3166
-    }
3167
-
3168
-
3169
-    /**
3170
-     * @param int $datetime_selector_max_checked
3171
-     */
3172
-    public function setDatetimeSelectorMaxChecked($datetime_selector_max_checked)
3173
-    {
3174
-        $this->datetime_selector_max_checked = absint($datetime_selector_max_checked);
3175
-    }
3010
+	/**
3011
+	 * constant to indicate that a datetime selector should NEVER be shown for ticket selectors
3012
+	 */
3013
+	const DO_NOT_SHOW_DATETIME_SELECTOR = 'no_datetime_selector';
3014
+
3015
+	/**
3016
+	 * constant to indicate that a datetime selector should only be shown for ticket selectors
3017
+	 * when the number of datetimes for the event matches the value set for $datetime_selector_threshold
3018
+	 */
3019
+	const MAYBE_SHOW_DATETIME_SELECTOR = 'maybe_datetime_selector';
3020
+
3021
+	/**
3022
+	 * @var boolean $show_ticket_sale_columns
3023
+	 */
3024
+	public $show_ticket_sale_columns;
3025
+
3026
+	/**
3027
+	 * @var boolean $show_ticket_details
3028
+	 */
3029
+	public $show_ticket_details;
3030
+
3031
+	/**
3032
+	 * @var boolean $show_expired_tickets
3033
+	 */
3034
+	public $show_expired_tickets;
3035
+
3036
+	/**
3037
+	 * whether or not to display a dropdown box populated with event datetimes
3038
+	 * that toggles which tickets are displayed for a ticket selector.
3039
+	 * uses one of the *_DATETIME_SELECTOR constants defined above
3040
+	 *
3041
+	 * @var string $show_datetime_selector
3042
+	 */
3043
+	private $show_datetime_selector = 'no_datetime_selector';
3044
+
3045
+	/**
3046
+	 * the number of datetimes an event has to have before conditionally displaying a datetime selector
3047
+	 *
3048
+	 * @var int $datetime_selector_threshold
3049
+	 */
3050
+	private $datetime_selector_threshold = 3;
3051
+
3052
+	/**
3053
+	 * determines the maximum number of "checked" dates in the date and time filter
3054
+	 *
3055
+	 * @var int $datetime_selector_checked
3056
+	 */
3057
+	private $datetime_selector_max_checked = 10;
3058
+
3059
+
3060
+	/**
3061
+	 *    class constructor
3062
+	 */
3063
+	public function __construct()
3064
+	{
3065
+		$this->show_ticket_sale_columns = true;
3066
+		$this->show_ticket_details = true;
3067
+		$this->show_expired_tickets = true;
3068
+		$this->show_datetime_selector = \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3069
+		$this->datetime_selector_threshold = 3;
3070
+		$this->datetime_selector_max_checked = 10;
3071
+	}
3072
+
3073
+
3074
+	/**
3075
+	 * returns true if a datetime selector should be displayed
3076
+	 *
3077
+	 * @param array $datetimes
3078
+	 * @return bool
3079
+	 */
3080
+	public function showDatetimeSelector(array $datetimes)
3081
+	{
3082
+		// if the settings are NOT: don't show OR below threshold, THEN active = true
3083
+		return ! (
3084
+			$this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR
3085
+			|| (
3086
+				$this->getShowDatetimeSelector() === \EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR
3087
+				&& count($datetimes) < $this->getDatetimeSelectorThreshold()
3088
+			)
3089
+		);
3090
+	}
3091
+
3092
+
3093
+	/**
3094
+	 * @return string
3095
+	 */
3096
+	public function getShowDatetimeSelector()
3097
+	{
3098
+		return $this->show_datetime_selector;
3099
+	}
3100
+
3101
+
3102
+	/**
3103
+	 * @param bool $keys_only
3104
+	 * @return array
3105
+	 */
3106
+	public function getShowDatetimeSelectorOptions($keys_only = true)
3107
+	{
3108
+		return $keys_only
3109
+			? array(
3110
+				\EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR,
3111
+				\EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR,
3112
+			)
3113
+			: array(
3114
+				\EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR => esc_html__(
3115
+					'Do not show date & time filter',
3116
+					'event_espresso'
3117
+				),
3118
+				\EE_Ticket_Selector_Config::MAYBE_SHOW_DATETIME_SELECTOR  => esc_html__(
3119
+					'Maybe show date & time filter',
3120
+					'event_espresso'
3121
+				),
3122
+			);
3123
+	}
3124
+
3125
+
3126
+	/**
3127
+	 * @param string $show_datetime_selector
3128
+	 */
3129
+	public function setShowDatetimeSelector($show_datetime_selector)
3130
+	{
3131
+		$this->show_datetime_selector = in_array(
3132
+			$show_datetime_selector,
3133
+			$this->getShowDatetimeSelectorOptions(),
3134
+			true
3135
+		)
3136
+			? $show_datetime_selector
3137
+			: \EE_Ticket_Selector_Config::DO_NOT_SHOW_DATETIME_SELECTOR;
3138
+	}
3139
+
3140
+
3141
+	/**
3142
+	 * @return int
3143
+	 */
3144
+	public function getDatetimeSelectorThreshold()
3145
+	{
3146
+		return $this->datetime_selector_threshold;
3147
+	}
3148
+
3149
+
3150
+	/**
3151
+	 * @param int $datetime_selector_threshold
3152
+	 */
3153
+	public function setDatetimeSelectorThreshold($datetime_selector_threshold)
3154
+	{
3155
+		$datetime_selector_threshold = absint($datetime_selector_threshold);
3156
+		$this->datetime_selector_threshold = $datetime_selector_threshold ? $datetime_selector_threshold : 3;
3157
+	}
3158
+
3159
+
3160
+	/**
3161
+	 * @return int
3162
+	 */
3163
+	public function getDatetimeSelectorMaxChecked()
3164
+	{
3165
+		return $this->datetime_selector_max_checked;
3166
+	}
3167
+
3168
+
3169
+	/**
3170
+	 * @param int $datetime_selector_max_checked
3171
+	 */
3172
+	public function setDatetimeSelectorMaxChecked($datetime_selector_max_checked)
3173
+	{
3174
+		$this->datetime_selector_max_checked = absint($datetime_selector_max_checked);
3175
+	}
3176 3176
 }
3177 3177
 
3178 3178
 /**
@@ -3185,86 +3185,86 @@  discard block
 block discarded – undo
3185 3185
 class EE_Environment_Config extends EE_Config_Base
3186 3186
 {
3187 3187
 
3188
-    /**
3189
-     * Hold any php environment variables that we want to track.
3190
-     *
3191
-     * @var stdClass;
3192
-     */
3193
-    public $php;
3194
-
3195
-
3196
-    /**
3197
-     *    constructor
3198
-     */
3199
-    public function __construct()
3200
-    {
3201
-        $this->php = new stdClass();
3202
-        $this->_set_php_values();
3203
-    }
3204
-
3205
-
3206
-    /**
3207
-     * This sets the php environment variables.
3208
-     *
3209
-     * @since 4.4.0
3210
-     * @return void
3211
-     */
3212
-    protected function _set_php_values()
3213
-    {
3214
-        $this->php->max_input_vars = ini_get('max_input_vars');
3215
-        $this->php->version = phpversion();
3216
-    }
3217
-
3218
-
3219
-    /**
3220
-     * helper method for determining whether input_count is
3221
-     * reaching the potential maximum the server can handle
3222
-     * according to max_input_vars
3223
-     *
3224
-     * @param int   $input_count the count of input vars.
3225
-     * @return array {
3226
-     *                           An array that represents whether available space and if no available space the error
3227
-     *                           message.
3228
-     * @type bool   $has_space   whether more inputs can be added.
3229
-     * @type string $msg         Any message to be displayed.
3230
-     *                           }
3231
-     */
3232
-    public function max_input_vars_limit_check($input_count = 0)
3233
-    {
3234
-        if (! empty($this->php->max_input_vars)
3235
-            && ($input_count >= $this->php->max_input_vars)
3236
-        ) {
3237
-            // check the server setting because the config value could be stale
3238
-            $max_input_vars = ini_get('max_input_vars');
3239
-            if ($input_count >= $max_input_vars) {
3240
-                return sprintf(
3241
-                    esc_html__(
3242
-                        'The maximum number of inputs on this page has been exceeded. You cannot make edits to this page because of your server\'s PHP "max_input_vars" setting.%1$sThere are %2$d inputs and the maximum amount currently allowed by your server is %3$d.%1$sPlease contact your web host and ask them to raise the "max_input_vars" limit.',
3243
-                        'event_espresso'
3244
-                    ),
3245
-                    '<br>',
3246
-                    $input_count,
3247
-                    $max_input_vars
3248
-                );
3249
-            } else {
3250
-                return '';
3251
-            }
3252
-        } else {
3253
-            return '';
3254
-        }
3255
-    }
3256
-
3257
-
3258
-    /**
3259
-     * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3260
-     *
3261
-     * @since 4.4.1
3262
-     * @return void
3263
-     */
3264
-    public function recheck_values()
3265
-    {
3266
-        $this->_set_php_values();
3267
-    }
3188
+	/**
3189
+	 * Hold any php environment variables that we want to track.
3190
+	 *
3191
+	 * @var stdClass;
3192
+	 */
3193
+	public $php;
3194
+
3195
+
3196
+	/**
3197
+	 *    constructor
3198
+	 */
3199
+	public function __construct()
3200
+	{
3201
+		$this->php = new stdClass();
3202
+		$this->_set_php_values();
3203
+	}
3204
+
3205
+
3206
+	/**
3207
+	 * This sets the php environment variables.
3208
+	 *
3209
+	 * @since 4.4.0
3210
+	 * @return void
3211
+	 */
3212
+	protected function _set_php_values()
3213
+	{
3214
+		$this->php->max_input_vars = ini_get('max_input_vars');
3215
+		$this->php->version = phpversion();
3216
+	}
3217
+
3218
+
3219
+	/**
3220
+	 * helper method for determining whether input_count is
3221
+	 * reaching the potential maximum the server can handle
3222
+	 * according to max_input_vars
3223
+	 *
3224
+	 * @param int   $input_count the count of input vars.
3225
+	 * @return array {
3226
+	 *                           An array that represents whether available space and if no available space the error
3227
+	 *                           message.
3228
+	 * @type bool   $has_space   whether more inputs can be added.
3229
+	 * @type string $msg         Any message to be displayed.
3230
+	 *                           }
3231
+	 */
3232
+	public function max_input_vars_limit_check($input_count = 0)
3233
+	{
3234
+		if (! empty($this->php->max_input_vars)
3235
+			&& ($input_count >= $this->php->max_input_vars)
3236
+		) {
3237
+			// check the server setting because the config value could be stale
3238
+			$max_input_vars = ini_get('max_input_vars');
3239
+			if ($input_count >= $max_input_vars) {
3240
+				return sprintf(
3241
+					esc_html__(
3242
+						'The maximum number of inputs on this page has been exceeded. You cannot make edits to this page because of your server\'s PHP "max_input_vars" setting.%1$sThere are %2$d inputs and the maximum amount currently allowed by your server is %3$d.%1$sPlease contact your web host and ask them to raise the "max_input_vars" limit.',
3243
+						'event_espresso'
3244
+					),
3245
+					'<br>',
3246
+					$input_count,
3247
+					$max_input_vars
3248
+				);
3249
+			} else {
3250
+				return '';
3251
+			}
3252
+		} else {
3253
+			return '';
3254
+		}
3255
+	}
3256
+
3257
+
3258
+	/**
3259
+	 * The purpose of this method is just to force rechecking php values so if they've changed, they get updated.
3260
+	 *
3261
+	 * @since 4.4.1
3262
+	 * @return void
3263
+	 */
3264
+	public function recheck_values()
3265
+	{
3266
+		$this->_set_php_values();
3267
+	}
3268 3268
 }
3269 3269
 
3270 3270
 /**
@@ -3277,21 +3277,21 @@  discard block
 block discarded – undo
3277 3277
 class EE_Tax_Config extends EE_Config_Base
3278 3278
 {
3279 3279
 
3280
-    /*
3280
+	/*
3281 3281
      * flag to indicate whether or not to display ticket prices with the taxes included
3282 3282
      *
3283 3283
      * @var boolean $prices_displayed_including_taxes
3284 3284
      */
3285
-    public $prices_displayed_including_taxes;
3285
+	public $prices_displayed_including_taxes;
3286 3286
 
3287 3287
 
3288
-    /**
3289
-     *    class constructor
3290
-     */
3291
-    public function __construct()
3292
-    {
3293
-        $this->prices_displayed_including_taxes = true;
3294
-    }
3288
+	/**
3289
+	 *    class constructor
3290
+	 */
3291
+	public function __construct()
3292
+	{
3293
+		$this->prices_displayed_including_taxes = true;
3294
+	}
3295 3295
 }
3296 3296
 
3297 3297
 /**
@@ -3305,19 +3305,19 @@  discard block
 block discarded – undo
3305 3305
 class EE_Messages_Config extends EE_Config_Base
3306 3306
 {
3307 3307
 
3308
-    /**
3309
-     * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3310
-     * A value of 0 represents never deleting.  Default is 0.
3311
-     *
3312
-     * @var integer
3313
-     */
3314
-    public $delete_threshold;
3308
+	/**
3309
+	 * This is an integer representing the deletion threshold in months for when old messages will get deleted.
3310
+	 * A value of 0 represents never deleting.  Default is 0.
3311
+	 *
3312
+	 * @var integer
3313
+	 */
3314
+	public $delete_threshold;
3315 3315
 
3316 3316
 
3317
-    public function __construct()
3318
-    {
3319
-        $this->delete_threshold = 0;
3320
-    }
3317
+	public function __construct()
3318
+	{
3319
+		$this->delete_threshold = 0;
3320
+	}
3321 3321
 }
3322 3322
 
3323 3323
 /**
@@ -3328,31 +3328,31 @@  discard block
 block discarded – undo
3328 3328
 class EE_Gateway_Config extends EE_Config_Base
3329 3329
 {
3330 3330
 
3331
-    /**
3332
-     * Array with keys that are payment gateways slugs, and values are arrays
3333
-     * with any config info the gateway wants to store
3334
-     *
3335
-     * @var array
3336
-     */
3337
-    public $payment_settings;
3338
-
3339
-    /**
3340
-     * Where keys are gateway slugs, and values are booleans indicating whether or not
3341
-     * the gateway is stored in the uploads directory
3342
-     *
3343
-     * @var array
3344
-     */
3345
-    public $active_gateways;
3346
-
3347
-
3348
-    /**
3349
-     *    class constructor
3350
-     *
3351
-     * @deprecated
3352
-     */
3353
-    public function __construct()
3354
-    {
3355
-        $this->payment_settings = array();
3356
-        $this->active_gateways = array('Invoice' => false);
3357
-    }
3331
+	/**
3332
+	 * Array with keys that are payment gateways slugs, and values are arrays
3333
+	 * with any config info the gateway wants to store
3334
+	 *
3335
+	 * @var array
3336
+	 */
3337
+	public $payment_settings;
3338
+
3339
+	/**
3340
+	 * Where keys are gateway slugs, and values are booleans indicating whether or not
3341
+	 * the gateway is stored in the uploads directory
3342
+	 *
3343
+	 * @var array
3344
+	 */
3345
+	public $active_gateways;
3346
+
3347
+
3348
+	/**
3349
+	 *    class constructor
3350
+	 *
3351
+	 * @deprecated
3352
+	 */
3353
+	public function __construct()
3354
+	{
3355
+		$this->payment_settings = array();
3356
+		$this->active_gateways = array('Invoice' => false);
3357
+	}
3358 3358
 }
Please login to merge, or discard this patch.
admin_pages/events/Events_Admin_Page.core.php 2 patches
Indentation   +2851 added lines, -2851 removed lines patch added patch discarded remove patch
@@ -15,2855 +15,2855 @@
 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
-                'capability' => '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 = [
245
-            'default'                => [
246
-                'nav'           => [
247
-                    'label' => esc_html__('Overview', 'event_espresso'),
248
-                    'order' => 10,
249
-                ],
250
-                'list_table'    => 'Events_Admin_List_Table',
251
-                'help_tabs'     => [
252
-                    'events_overview_help_tab'                       => [
253
-                        'title'    => esc_html__('Events Overview', 'event_espresso'),
254
-                        'filename' => 'events_overview',
255
-                    ],
256
-                    'events_overview_table_column_headings_help_tab' => [
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'               => [
261
-                        'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
262
-                        'filename' => 'events_overview_filters',
263
-                    ],
264
-                    'events_overview_view_help_tab'                  => [
265
-                        'title'    => esc_html__('Events Overview Views', 'event_espresso'),
266
-                        'filename' => 'events_overview_views',
267
-                    ],
268
-                    'events_overview_other_help_tab'                 => [
269
-                        'title'    => esc_html__('Events Overview Other', 'event_espresso'),
270
-                        'filename' => 'events_overview_other',
271
-                    ],
272
-                ],
273
-                'help_tour'     => [
274
-                    'Event_Overview_Help_Tour',
275
-                    // 'New_Features_Test_Help_Tour' for testing multiple help tour
276
-                ],
277
-                'require_nonce' => false,
278
-                'qtips' => ['EE_Event_List_Table_Tips'],
279
-            ],
280
-            'create_new'             => [
281
-                'nav'           => [
282
-                    'label'      => esc_html__('Add Event', 'event_espresso'),
283
-                    'order'      => 5,
284
-                    'persistent' => false,
285
-                ],
286
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
287
-                'help_tabs'     => [
288
-                    'event_editor_help_tab'                            => [
289
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
290
-                        'filename' => 'event_editor',
291
-                    ],
292
-                    'event_editor_title_richtexteditor_help_tab'       => [
293
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
294
-                        'filename' => 'event_editor_title_richtexteditor',
295
-                    ],
296
-                    'event_editor_venue_details_help_tab'              => [
297
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
298
-                        'filename' => 'event_editor_venue_details',
299
-                    ],
300
-                    'event_editor_event_datetimes_help_tab'            => [
301
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
302
-                        'filename' => 'event_editor_event_datetimes',
303
-                    ],
304
-                    'event_editor_event_tickets_help_tab'              => [
305
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
306
-                        'filename' => 'event_editor_event_tickets',
307
-                    ],
308
-                    'event_editor_event_registration_options_help_tab' => [
309
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
310
-                        'filename' => 'event_editor_event_registration_options',
311
-                    ],
312
-                    'event_editor_tags_categories_help_tab'            => [
313
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
314
-                        'filename' => 'event_editor_tags_categories',
315
-                    ],
316
-                    'event_editor_questions_registrants_help_tab'      => [
317
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
318
-                        'filename' => 'event_editor_questions_registrants',
319
-                    ],
320
-                    'event_editor_save_new_event_help_tab'             => [
321
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
322
-                        'filename' => 'event_editor_save_new_event',
323
-                    ],
324
-                    'event_editor_other_help_tab'                      => [
325
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
326
-                        'filename' => 'event_editor_other',
327
-                    ],
328
-                ],
329
-                'help_tour'     => [
330
-                    'Event_Editor_Help_Tour',
331
-                ],
332
-                'require_nonce' => false,
333
-            ],
334
-            'edit'                   => [
335
-                'nav'           => [
336
-                    'label'      => esc_html__('Edit Event', 'event_espresso'),
337
-                    'order'      => 5,
338
-                    'persistent' => false,
339
-                    'url'        => isset($this->_req_data['post'])
340
-                        ? EE_Admin_Page::add_query_args_and_nonce(
341
-                            ['post' => $this->_req_data['post'], 'action' => 'edit'],
342
-                            $this->_current_page_view_url
343
-                        )
344
-                        : $this->_admin_base_url,
345
-                ],
346
-                'metaboxes'     => ['_register_event_editor_meta_boxes'],
347
-                'help_tabs'     => [
348
-                    'event_editor_help_tab'                            => [
349
-                        'title'    => esc_html__('Event Editor', 'event_espresso'),
350
-                        'filename' => 'event_editor',
351
-                    ],
352
-                    'event_editor_title_richtexteditor_help_tab'       => [
353
-                        'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
354
-                        'filename' => 'event_editor_title_richtexteditor',
355
-                    ],
356
-                    'event_editor_venue_details_help_tab'              => [
357
-                        'title'    => esc_html__('Event Venue Details', 'event_espresso'),
358
-                        'filename' => 'event_editor_venue_details',
359
-                    ],
360
-                    'event_editor_event_datetimes_help_tab'            => [
361
-                        'title'    => esc_html__('Event Datetimes', 'event_espresso'),
362
-                        'filename' => 'event_editor_event_datetimes',
363
-                    ],
364
-                    'event_editor_event_tickets_help_tab'              => [
365
-                        'title'    => esc_html__('Event Tickets', 'event_espresso'),
366
-                        'filename' => 'event_editor_event_tickets',
367
-                    ],
368
-                    'event_editor_event_registration_options_help_tab' => [
369
-                        'title'    => esc_html__('Event Registration Options', 'event_espresso'),
370
-                        'filename' => 'event_editor_event_registration_options',
371
-                    ],
372
-                    'event_editor_tags_categories_help_tab'            => [
373
-                        'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
374
-                        'filename' => 'event_editor_tags_categories',
375
-                    ],
376
-                    'event_editor_questions_registrants_help_tab'      => [
377
-                        'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
378
-                        'filename' => 'event_editor_questions_registrants',
379
-                    ],
380
-                    'event_editor_save_new_event_help_tab'             => [
381
-                        'title'    => esc_html__('Save New Event', 'event_espresso'),
382
-                        'filename' => 'event_editor_save_new_event',
383
-                    ],
384
-                    'event_editor_other_help_tab'                      => [
385
-                        'title'    => esc_html__('Event Other', 'event_espresso'),
386
-                        'filename' => 'event_editor_other',
387
-                    ],
388
-                ],
389
-                'require_nonce' => false,
390
-            ],
391
-            'default_event_settings' => [
392
-                'nav'           => [
393
-                    'label' => esc_html__('Default Settings', 'event_espresso'),
394
-                    'order' => 40,
395
-                ],
396
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
397
-                'labels'        => [
398
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
399
-                ],
400
-                'help_tabs'     => [
401
-                    'default_settings_help_tab'        => [
402
-                        'title'    => esc_html__('Default Event Settings', 'event_espresso'),
403
-                        'filename' => 'events_default_settings',
404
-                    ],
405
-                    'default_settings_status_help_tab' => [
406
-                        'title'    => esc_html__('Default Registration Status', 'event_espresso'),
407
-                        'filename' => 'events_default_settings_status',
408
-                    ],
409
-                    'default_maximum_tickets_help_tab' => [
410
-                        'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
411
-                        'filename' => 'events_default_settings_max_tickets',
412
-                    ],
413
-                ],
414
-                'help_tour'     => ['Event_Default_Settings_Help_Tour'],
415
-                'require_nonce' => false,
416
-            ],
417
-            // template settings
418
-            'template_settings'      => [
419
-                'nav'           => [
420
-                    'label' => esc_html__('Templates', 'event_espresso'),
421
-                    'order' => 30,
422
-                ],
423
-                'metaboxes'     => $this->_default_espresso_metaboxes,
424
-                'help_tabs'     => [
425
-                    'general_settings_templates_help_tab' => [
426
-                        'title'    => esc_html__('Templates', 'event_espresso'),
427
-                        'filename' => 'general_settings_templates',
428
-                    ],
429
-                ],
430
-                'help_tour'     => ['Templates_Help_Tour'],
431
-                'require_nonce' => false,
432
-            ],
433
-            // event category stuff
434
-            'add_category'           => [
435
-                'nav'           => [
436
-                    'label'      => esc_html__('Add Category', 'event_espresso'),
437
-                    'order'      => 15,
438
-                    'persistent' => false,
439
-                ],
440
-                'help_tabs'     => [
441
-                    'add_category_help_tab' => [
442
-                        'title'    => esc_html__('Add New Event Category', 'event_espresso'),
443
-                        'filename' => 'events_add_category',
444
-                    ],
445
-                ],
446
-                'help_tour'     => ['Event_Add_Category_Help_Tour'],
447
-                'metaboxes'     => ['_publish_post_box'],
448
-                'require_nonce' => false,
449
-            ],
450
-            'edit_category'          => [
451
-                'nav'           => [
452
-                    'label'      => esc_html__('Edit Category', 'event_espresso'),
453
-                    'order'      => 15,
454
-                    'persistent' => false,
455
-                    'url'        => isset($this->_req_data['EVT_CAT_ID'])
456
-                        ? add_query_arg(
457
-                            ['EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']],
458
-                            $this->_current_page_view_url
459
-                        )
460
-                        : $this->_admin_base_url,
461
-                ],
462
-                'help_tabs'     => [
463
-                    'edit_category_help_tab' => [
464
-                        'title'    => esc_html__('Edit Event Category', 'event_espresso'),
465
-                        'filename' => 'events_edit_category',
466
-                    ],
467
-                ],
468
-                /*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
469
-                'metaboxes'     => ['_publish_post_box'],
470
-                'require_nonce' => false,
471
-            ],
472
-            'category_list'          => [
473
-                'nav'           => [
474
-                    'label' => esc_html__('Categories', 'event_espresso'),
475
-                    'order' => 20,
476
-                ],
477
-                'list_table'    => 'Event_Categories_Admin_List_Table',
478
-                'help_tabs'     => [
479
-                    'events_categories_help_tab'                       => [
480
-                        'title'    => esc_html__('Event Categories', 'event_espresso'),
481
-                        'filename' => 'events_categories',
482
-                    ],
483
-                    'events_categories_table_column_headings_help_tab' => [
484
-                        'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
485
-                        'filename' => 'events_categories_table_column_headings',
486
-                    ],
487
-                    'events_categories_view_help_tab'                  => [
488
-                        'title'    => esc_html__('Event Categories Views', 'event_espresso'),
489
-                        'filename' => 'events_categories_views',
490
-                    ],
491
-                    'events_categories_other_help_tab'                 => [
492
-                        'title'    => esc_html__('Event Categories Other', 'event_espresso'),
493
-                        'filename' => 'events_categories_other',
494
-                    ],
495
-                ],
496
-                'help_tour'     => [
497
-                    'Event_Categories_Help_Tour',
498
-                ],
499
-                'metaboxes'     => $this->_default_espresso_metaboxes,
500
-                'require_nonce' => false,
501
-            ],
502
-        ];
503
-        // only load EE_Event_Editor_Decaf_Tips if domain is not caffeinated
504
-        $domain = $this->loader->getShared('EventEspresso\core\domain\Domain');
505
-        if (! $domain->isCaffeinated()) {
506
-            $this->_page_config['create_new']['qtips'] = ['EE_Event_Editor_Decaf_Tips'];
507
-            $this->_page_config['edit']['qtips'] = ['EE_Event_Editor_Decaf_Tips' ];
508
-        }
509
-    }
510
-
511
-
512
-    /**
513
-     * Used to register any global screen options if necessary for every route in this admin page group.
514
-     */
515
-    protected function _add_screen_options()
516
-    {
517
-    }
518
-
519
-
520
-    /**
521
-     * Implementing the screen options for the 'default' route.
522
-     *
523
-     * @throws InvalidArgumentException
524
-     * @throws InvalidDataTypeException
525
-     * @throws InvalidInterfaceException
526
-     */
527
-    protected function _add_screen_options_default()
528
-    {
529
-        $this->_per_page_screen_option();
530
-    }
531
-
532
-
533
-    /**
534
-     * Implementing screen options for the category list route.
535
-     *
536
-     * @throws InvalidArgumentException
537
-     * @throws InvalidDataTypeException
538
-     * @throws InvalidInterfaceException
539
-     */
540
-    protected function _add_screen_options_category_list()
541
-    {
542
-        $page_title = $this->_admin_page_title;
543
-        $this->_admin_page_title = esc_html__('Categories', 'event_espresso');
544
-        $this->_per_page_screen_option();
545
-        $this->_admin_page_title = $page_title;
546
-    }
547
-
548
-
549
-    /**
550
-     * Used to register any global feature pointers for the admin page group.
551
-     */
552
-    protected function _add_feature_pointers()
553
-    {
554
-    }
555
-
556
-
557
-    /**
558
-     * Registers and enqueues any global scripts and styles for the entire admin page group.
559
-     */
560
-    public function load_scripts_styles()
561
-    {
562
-        wp_register_style(
563
-            'events-admin-css',
564
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
565
-            array(),
566
-            EVENT_ESPRESSO_VERSION
567
-        );
568
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
569
-        wp_enqueue_style('events-admin-css');
570
-        wp_enqueue_style('ee-cat-admin');
571
-        // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
572
-        // registers for all views
573
-        // scripts
574
-        wp_register_script(
575
-            'event_editor_js',
576
-            EVENTS_ASSETS_URL . 'event_editor.js',
577
-            array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
578
-            EVENT_ESPRESSO_VERSION,
579
-            true
580
-        );
581
-    }
582
-
583
-
584
-    /**
585
-     * Enqueuing scripts and styles specific to this view
586
-     */
587
-    public function load_scripts_styles_create_new()
588
-    {
589
-        $this->load_scripts_styles_edit();
590
-    }
591
-
592
-
593
-    /**
594
-     * Enqueuing scripts and styles specific to this view
595
-     */
596
-    public function load_scripts_styles_edit()
597
-    {
598
-        // styles
599
-        wp_enqueue_style('espresso-ui-theme');
600
-        wp_register_style(
601
-            'event-editor-css',
602
-            EVENTS_ASSETS_URL . 'event-editor.css',
603
-            array('ee-admin-css'),
604
-            EVENT_ESPRESSO_VERSION
605
-        );
606
-        wp_enqueue_style('event-editor-css');
607
-        // scripts
608
-        wp_register_script(
609
-            'event-datetime-metabox',
610
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
611
-            array('event_editor_js', 'ee-datepicker'),
612
-            EVENT_ESPRESSO_VERSION
613
-        );
614
-        wp_enqueue_script('event-datetime-metabox');
615
-    }
616
-
617
-
618
-    /**
619
-     * Populating the _views property for the category list table view.
620
-     */
621
-    protected function _set_list_table_views_category_list()
622
-    {
623
-        $this->_views = array(
624
-            'all' => array(
625
-                'slug'        => 'all',
626
-                'label'       => esc_html__('All', 'event_espresso'),
627
-                'count'       => 0,
628
-                'bulk_action' => array(
629
-                    'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
630
-                ),
631
-            ),
632
-        );
633
-    }
634
-
635
-
636
-    /**
637
-     * For adding anything that fires on the admin_init hook for any route within this admin page group.
638
-     */
639
-    public function admin_init()
640
-    {
641
-        EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
642
-            'Do you really want to delete this image? Please remember to update your event to complete the removal.',
643
-            'event_espresso'
644
-        );
645
-    }
646
-
647
-
648
-    /**
649
-     * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
650
-     * group.
651
-     */
652
-    public function admin_notices()
653
-    {
654
-    }
655
-
656
-
657
-    /**
658
-     * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
659
-     * this admin page group.
660
-     */
661
-    public function admin_footer_scripts()
662
-    {
663
-    }
664
-
665
-
666
-    /**
667
-     * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
668
-     * warning (via EE_Error::add_error());
669
-     *
670
-     * @param  EE_Event $event Event object
671
-     * @param string    $req_type
672
-     * @return void
673
-     * @throws EE_Error
674
-     * @access public
675
-     */
676
-    public function verify_event_edit($event = null, $req_type = '')
677
-    {
678
-        // don't need to do this when processing
679
-        if (! empty($req_type)) {
680
-            return;
681
-        }
682
-        // no event?
683
-        if (! $event instanceof EE_Event) {
684
-            $event = $this->_cpt_model_obj;
685
-        }
686
-        // STILL no event?
687
-        if (! $event instanceof EE_Event) {
688
-            return;
689
-        }
690
-        $orig_status = $event->status();
691
-        // first check if event is active.
692
-        if ($orig_status === EEM_Event::cancelled
693
-            || $orig_status === EEM_Event::postponed
694
-            || $event->is_expired()
695
-            || $event->is_inactive()
696
-        ) {
697
-            return;
698
-        }
699
-        // made it here so it IS active... next check that any of the tickets are sold.
700
-        if ($event->is_sold_out(true)) {
701
-            if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
702
-                EE_Error::add_attention(
703
-                    sprintf(
704
-                        esc_html__(
705
-                            '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.',
706
-                            'event_espresso'
707
-                        ),
708
-                        EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
709
-                    )
710
-                );
711
-            }
712
-            return;
713
-        }
714
-        if ($orig_status === EEM_Event::sold_out) {
715
-            EE_Error::add_attention(
716
-                sprintf(
717
-                    esc_html__(
718
-                        '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.',
719
-                        'event_espresso'
720
-                    ),
721
-                    EEH_Template::pretty_status($event->status(), false, 'sentence')
722
-                )
723
-            );
724
-        }
725
-        // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
726
-        if (! $event->tickets_on_sale()) {
727
-            return;
728
-        }
729
-        // made it here so show warning
730
-        $this->_edit_event_warning();
731
-    }
732
-
733
-
734
-    /**
735
-     * This is the text used for when an event is being edited that is public and has tickets for sale.
736
-     * When needed, hook this into a EE_Error::add_error() notice.
737
-     *
738
-     * @access protected
739
-     * @return void
740
-     */
741
-    protected function _edit_event_warning()
742
-    {
743
-        // we don't want to add warnings during these requests
744
-        if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
745
-            return;
746
-        }
747
-        EE_Error::add_attention(
748
-            sprintf(
749
-                esc_html__(
750
-                    'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
751
-                    'event_espresso'
752
-                ),
753
-                '<a class="espresso-help-tab-lnk">',
754
-                '</a>'
755
-            )
756
-        );
757
-    }
758
-
759
-
760
-    /**
761
-     * When a user is creating a new event, notify them if they haven't set their timezone.
762
-     * Otherwise, do the normal logic
763
-     *
764
-     * @return string
765
-     * @throws EE_Error
766
-     * @throws InvalidArgumentException
767
-     * @throws InvalidDataTypeException
768
-     * @throws InvalidInterfaceException
769
-     */
770
-    protected function _create_new_cpt_item()
771
-    {
772
-        $has_timezone_string = get_option('timezone_string');
773
-        // only nag them about setting their timezone if it's their first event, and they haven't already done it
774
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) {
775
-            EE_Error::add_attention(
776
-                sprintf(
777
-                    __(
778
-                        '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',
779
-                        'event_espresso'
780
-                    ),
781
-                    '<br>',
782
-                    '<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
783
-                    . EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
784
-                    . '</select>',
785
-                    '<button class="button button-secondary timezone-submit">',
786
-                    '</button><span class="spinner"></span>'
787
-                ),
788
-                __FILE__,
789
-                __FUNCTION__,
790
-                __LINE__
791
-            );
792
-        }
793
-        parent::_create_new_cpt_item();
794
-    }
795
-
796
-
797
-    /**
798
-     * Sets the _views property for the default route in this admin page group.
799
-     */
800
-    protected function _set_list_table_views_default()
801
-    {
802
-        $this->_views = array(
803
-            'all'   => array(
804
-                'slug'        => 'all',
805
-                'label'       => esc_html__('View All Events', 'event_espresso'),
806
-                'count'       => 0,
807
-                'bulk_action' => array(
808
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
809
-                ),
810
-            ),
811
-            'draft' => array(
812
-                'slug'        => 'draft',
813
-                'label'       => esc_html__('Draft', 'event_espresso'),
814
-                'count'       => 0,
815
-                'bulk_action' => array(
816
-                    'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
817
-                ),
818
-            ),
819
-        );
820
-        if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
821
-            $this->_views['trash'] = array(
822
-                'slug'        => 'trash',
823
-                'label'       => esc_html__('Trash', 'event_espresso'),
824
-                'count'       => 0,
825
-                'bulk_action' => array(
826
-                    'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
827
-                    'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
828
-                ),
829
-            );
830
-        }
831
-    }
832
-
833
-
834
-    /**
835
-     * Provides the legend item array for the default list table view.
836
-     *
837
-     * @return array
838
-     */
839
-    protected function _event_legend_items()
840
-    {
841
-        $items = array(
842
-            'view_details'   => array(
843
-                'class' => 'dashicons dashicons-search',
844
-                'desc'  => esc_html__('View Event', 'event_espresso'),
845
-            ),
846
-            'edit_event'     => array(
847
-                'class' => 'ee-icon ee-icon-calendar-edit',
848
-                'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
849
-            ),
850
-            'view_attendees' => array(
851
-                'class' => 'dashicons dashicons-groups',
852
-                'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
853
-            ),
854
-        );
855
-        $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
856
-        $statuses = array(
857
-            'sold_out_status'  => array(
858
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
859
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
860
-            ),
861
-            'active_status'    => array(
862
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
863
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
864
-            ),
865
-            'upcoming_status'  => array(
866
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
867
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
868
-            ),
869
-            'postponed_status' => array(
870
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
871
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
872
-            ),
873
-            'cancelled_status' => array(
874
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
875
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
876
-            ),
877
-            'expired_status'   => array(
878
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
879
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
880
-            ),
881
-            'inactive_status'  => array(
882
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
883
-                'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
884
-            ),
885
-        );
886
-        $statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
887
-        return array_merge($items, $statuses);
888
-    }
889
-
890
-
891
-    /**
892
-     * @return EEM_Event
893
-     * @throws EE_Error
894
-     * @throws InvalidArgumentException
895
-     * @throws InvalidDataTypeException
896
-     * @throws InvalidInterfaceException
897
-     * @throws ReflectionException
898
-     */
899
-    private function _event_model()
900
-    {
901
-        if (! $this->_event_model instanceof EEM_Event) {
902
-            $this->_event_model = EE_Registry::instance()->load_model('Event');
903
-        }
904
-        return $this->_event_model;
905
-    }
906
-
907
-
908
-    /**
909
-     * Adds extra buttons to the WP CPT permalink field row.
910
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
911
-     *
912
-     * @param  string $return    the current html
913
-     * @param  int    $id        the post id for the page
914
-     * @param  string $new_title What the title is
915
-     * @param  string $new_slug  what the slug is
916
-     * @return string            The new html string for the permalink area
917
-     */
918
-    public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
919
-    {
920
-        // make sure this is only when editing
921
-        if (! empty($id)) {
922
-            $post = get_post($id);
923
-            $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
924
-                       . esc_html__('Shortcode', 'event_espresso')
925
-                       . '</a> ';
926
-            $return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
927
-                       . $post->ID
928
-                       . ']">';
929
-        }
930
-        return $return;
931
-    }
932
-
933
-
934
-    /**
935
-     * _events_overview_list_table
936
-     * This contains the logic for showing the events_overview list
937
-     *
938
-     * @access protected
939
-     * @return void
940
-     * @throws DomainException
941
-     * @throws EE_Error
942
-     * @throws InvalidArgumentException
943
-     * @throws InvalidDataTypeException
944
-     * @throws InvalidInterfaceException
945
-     */
946
-    protected function _events_overview_list_table()
947
-    {
948
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
949
-        $this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
950
-            ? (array) $this->_template_args['after_list_table']
951
-            : array();
952
-        $this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
953
-                . EEH_Template::get_button_or_link(
954
-                    get_post_type_archive_link('espresso_events'),
955
-                    esc_html__('View Event Archive Page', 'event_espresso'),
956
-                    'button'
957
-                );
958
-        $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
959
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
960
-            'create_new',
961
-            'add',
962
-            array(),
963
-            'add-new-h2'
964
-        );
965
-        $this->display_admin_list_table_page_with_no_sidebar();
966
-    }
967
-
968
-
969
-    /**
970
-     * this allows for extra misc actions in the default WP publish box
971
-     *
972
-     * @return void
973
-     * @throws DomainException
974
-     * @throws EE_Error
975
-     * @throws InvalidArgumentException
976
-     * @throws InvalidDataTypeException
977
-     * @throws InvalidInterfaceException
978
-     * @throws ReflectionException
979
-     */
980
-    public function extra_misc_actions_publish_box()
981
-    {
982
-        $this->_generate_publish_box_extra_content();
983
-    }
984
-
985
-
986
-    /**
987
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
988
-     * saved.
989
-     * Typically you would use this to save any additional data.
990
-     * Keep in mind also that "save_post" runs on EVERY post update to the database.
991
-     * ALSO very important.  When a post transitions from scheduled to published,
992
-     * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
993
-     * other meta saves. So MAKE sure that you handle this accordingly.
994
-     *
995
-     * @access protected
996
-     * @abstract
997
-     * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
998
-     * @param object $post    The post object of the cpt that was saved.
999
-     * @return void
1000
-     * @throws EE_Error
1001
-     * @throws InvalidArgumentException
1002
-     * @throws InvalidDataTypeException
1003
-     * @throws InvalidInterfaceException
1004
-     * @throws ReflectionException
1005
-     */
1006
-    protected function _insert_update_cpt_item($post_id, $post)
1007
-    {
1008
-        if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1009
-            // get out we're not processing an event save.
1010
-            return;
1011
-        }
1012
-        $event_values = array(
1013
-            'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
1014
-            'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
1015
-            'EVT_additional_limit'            => min(
1016
-                apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1017
-                ! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
1018
-            ),
1019
-            'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
1020
-                ? $this->_req_data['EVT_default_registration_status']
1021
-                : EE_Registry::instance()->CFG->registration->default_STS_ID,
1022
-            'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
1023
-            'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
1024
-            'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
1025
-                ? $this->_req_data['timezone_string'] : null,
1026
-            'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
1027
-                ? $this->_req_data['externalURL'] : null,
1028
-            'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
1029
-                ? $this->_req_data['event_phone'] : null,
1030
-        );
1031
-        // update event
1032
-        $success = $this->_event_model()->update_by_ID($event_values, $post_id);
1033
-        // 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!
1034
-        $get_one_where = array(
1035
-            $this->_event_model()->primary_key_name() => $post_id,
1036
-            'OR'                                      => array(
1037
-                'status'   => $post->post_status,
1038
-                // if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1039
-                // but the returned object here has a status of "publish", so use the original post status as well
1040
-                'status*1' => $this->_req_data['original_post_status'],
1041
-            ),
1042
-        );
1043
-        $event = $this->_event_model()->get_one(array($get_one_where));
1044
-        // the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1045
-        $event_update_callbacks = apply_filters(
1046
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1047
-            array(
1048
-                array($this, '_default_venue_update'),
1049
-                array($this, '_default_tickets_update'),
1050
-            )
1051
-        );
1052
-        $att_success = true;
1053
-        foreach ($event_update_callbacks as $e_callback) {
1054
-            $_success = is_callable($e_callback)
1055
-                ? $e_callback($event, $this->_req_data)
1056
-                : false;
1057
-            // if ANY of these updates fail then we want the appropriate global error message
1058
-            $att_success = ! $att_success ? $att_success : $_success;
1059
-        }
1060
-        // any errors?
1061
-        if ($success && false === $att_success) {
1062
-            EE_Error::add_error(
1063
-                esc_html__(
1064
-                    'Event Details saved successfully but something went wrong with saving attachments.',
1065
-                    'event_espresso'
1066
-                ),
1067
-                __FILE__,
1068
-                __FUNCTION__,
1069
-                __LINE__
1070
-            );
1071
-        } elseif ($success === false) {
1072
-            EE_Error::add_error(
1073
-                esc_html__('Event Details did not save successfully.', 'event_espresso'),
1074
-                __FILE__,
1075
-                __FUNCTION__,
1076
-                __LINE__
1077
-            );
1078
-        }
1079
-    }
1080
-
1081
-
1082
-    /**
1083
-     * @param int $post_id
1084
-     * @param int $revision_id
1085
-     * @throws EE_Error
1086
-     * @throws InvalidArgumentException
1087
-     * @throws InvalidDataTypeException
1088
-     * @throws InvalidInterfaceException
1089
-     * @throws ReflectionException
1090
-     * @see parent::restore_item()
1091
-     */
1092
-    protected function _restore_cpt_item($post_id, $revision_id)
1093
-    {
1094
-        // copy existing event meta to new post
1095
-        $post_evt = $this->_event_model()->get_one_by_ID($post_id);
1096
-        if ($post_evt instanceof EE_Event) {
1097
-            // meta revision restore
1098
-            $post_evt->restore_revision($revision_id);
1099
-            // related objs restore
1100
-            $post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1101
-        }
1102
-    }
1103
-
1104
-
1105
-    /**
1106
-     * Attach the venue to the Event
1107
-     *
1108
-     * @param EE_Event $evtobj Event Object to add the venue to
1109
-     * @param array    $data   The request data from the form
1110
-     * @return bool           Success or fail.
1111
-     * @throws EE_Error
1112
-     * @throws InvalidArgumentException
1113
-     * @throws InvalidDataTypeException
1114
-     * @throws InvalidInterfaceException
1115
-     * @throws ReflectionException
1116
-     */
1117
-    protected function _default_venue_update(EE_Event $evtobj, $data)
1118
-    {
1119
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1120
-        $venue_model = EE_Registry::instance()->load_model('Venue');
1121
-        $rows_affected = null;
1122
-        $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1123
-        // very important.  If we don't have a venue name...
1124
-        // then we'll get out because not necessary to create empty venue
1125
-        if (empty($data['venue_title'])) {
1126
-            return false;
1127
-        }
1128
-        $venue_array = array(
1129
-            'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1130
-            'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1131
-            'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1132
-            'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1133
-            'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1134
-                : null,
1135
-            'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1136
-            'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1137
-            'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1138
-            'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1139
-            'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1140
-            'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1141
-            'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1142
-            'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1143
-            'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1144
-            'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1145
-            'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1146
-            'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1147
-            'status'              => 'publish',
1148
-        );
1149
-        // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1150
-        if (! empty($venue_id)) {
1151
-            $update_where = array($venue_model->primary_key_name() => $venue_id);
1152
-            $rows_affected = $venue_model->update($venue_array, array($update_where));
1153
-            // 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.
1154
-            $evtobj->_add_relation_to($venue_id, 'Venue');
1155
-            return $rows_affected > 0;
1156
-        }
1157
-        // we insert the venue
1158
-        $venue_id = $venue_model->insert($venue_array);
1159
-        $evtobj->_add_relation_to($venue_id, 'Venue');
1160
-        return ! empty($venue_id) ? true : false;
1161
-        // when we have the ancestor come in it's already been handled by the revision save.
1162
-    }
1163
-
1164
-
1165
-    /**
1166
-     * Handles saving everything related to Tickets (datetimes, tickets, prices)
1167
-     *
1168
-     * @param EE_Event $evtobj The Event object we're attaching data to
1169
-     * @param array    $data   The request data from the form
1170
-     * @return array
1171
-     * @throws EE_Error
1172
-     * @throws InvalidArgumentException
1173
-     * @throws InvalidDataTypeException
1174
-     * @throws InvalidInterfaceException
1175
-     * @throws ReflectionException
1176
-     * @throws Exception
1177
-     */
1178
-    protected function _default_tickets_update(EE_Event $evtobj, $data)
1179
-    {
1180
-        if (EE_Registry::instance()->CFG->admin->useAdvancedEditor()) {
1181
-            return [];
1182
-        }
1183
-        $success = true;
1184
-        $saved_dtt = null;
1185
-        $saved_tickets = array();
1186
-        $incoming_date_formats = array('Y-m-d', 'h:i a');
1187
-        foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1188
-            // trim all values to ensure any excess whitespace is removed.
1189
-            $dtt = array_map('trim', $dtt);
1190
-            $dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1191
-                : $dtt['DTT_EVT_start'];
1192
-            $datetime_values = array(
1193
-                'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1194
-                'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1195
-                'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1196
-                'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1197
-                'DTT_order'     => $row,
1198
-            );
1199
-            // 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.
1200
-            if (! empty($dtt['DTT_ID'])) {
1201
-                $DTM = EE_Registry::instance()
1202
-                                  ->load_model('Datetime', array($evtobj->get_timezone()))
1203
-                                  ->get_one_by_ID($dtt['DTT_ID']);
1204
-                $DTM->set_date_format($incoming_date_formats[0]);
1205
-                $DTM->set_time_format($incoming_date_formats[1]);
1206
-                foreach ($datetime_values as $field => $value) {
1207
-                    $DTM->set($field, $value);
1208
-                }
1209
-                // 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.
1210
-                $saved_dtts[ $DTM->ID() ] = $DTM;
1211
-            } else {
1212
-                $DTM = EE_Registry::instance()->load_class(
1213
-                    'Datetime',
1214
-                    array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1215
-                    false,
1216
-                    false
1217
-                );
1218
-                foreach ($datetime_values as $field => $value) {
1219
-                    $DTM->set($field, $value);
1220
-                }
1221
-            }
1222
-            $DTM->save();
1223
-            $DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1224
-            // load DTT helper
1225
-            // 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.
1226
-            if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1227
-                $DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1228
-                $DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1229
-                $DTT->save();
1230
-            }
1231
-            // 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.
1232
-            $saved_dtt = $DTT;
1233
-            $success = ! $success ? $success : $DTT;
1234
-            // if ANY of these updates fail then we want the appropriate global error message.
1235
-            // //todo this is actually sucky we need a better error message but this is what it is for now.
1236
-        }
1237
-        // no dtts get deleted so we don't do any of that logic here.
1238
-        // update tickets next
1239
-        $old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1240
-        foreach ($data['edit_tickets'] as $row => $tkt) {
1241
-            $incoming_date_formats = array('Y-m-d', 'h:i a');
1242
-            $update_prices = false;
1243
-            $ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1244
-                ? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0;
1245
-            // trim inputs to ensure any excess whitespace is removed.
1246
-            $tkt = array_map('trim', $tkt);
1247
-            if (empty($tkt['TKT_start_date'])) {
1248
-                // let's use now in the set timezone.
1249
-                $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1250
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1251
-            }
1252
-            if (empty($tkt['TKT_end_date'])) {
1253
-                // use the start date of the first datetime
1254
-                $dtt = $evtobj->first_datetime();
1255
-                $tkt['TKT_end_date'] = $dtt->start_date_and_time(
1256
-                    $incoming_date_formats[0],
1257
-                    $incoming_date_formats[1]
1258
-                );
1259
-            }
1260
-            $TKT_values = array(
1261
-                'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1262
-                'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1263
-                'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1264
-                'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1265
-                'TKT_start_date'  => $tkt['TKT_start_date'],
1266
-                'TKT_end_date'    => $tkt['TKT_end_date'],
1267
-                'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1268
-                'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1269
-                'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1270
-                'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1271
-                'TKT_row'         => $row,
1272
-                'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1273
-                'TKT_price'       => $ticket_price,
1274
-            );
1275
-            // 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.
1276
-            if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1277
-                $TKT_values['TKT_ID'] = 0;
1278
-                $TKT_values['TKT_is_default'] = 0;
1279
-                $TKT_values['TKT_price'] = $ticket_price;
1280
-                $update_prices = true;
1281
-            }
1282
-            // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1283
-            // 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.
1284
-            // 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.
1285
-            if (! empty($tkt['TKT_ID'])) {
1286
-                $TKT = EE_Registry::instance()
1287
-                                  ->load_model('Ticket', array($evtobj->get_timezone()))
1288
-                                  ->get_one_by_ID($tkt['TKT_ID']);
1289
-                if ($TKT instanceof EE_Ticket) {
1290
-                    $ticket_sold = $TKT->count_related(
1291
-                        'Registration',
1292
-                        array(
1293
-                            array(
1294
-                                'STS_ID' => array(
1295
-                                    'NOT IN',
1296
-                                    array(EEM_Registration::status_id_incomplete),
1297
-                                ),
1298
-                            ),
1299
-                        )
1300
-                    ) > 0;
1301
-                    // let's just check the total price for the existing ticket and determine if it matches the new
1302
-                    // total price.  if they are different then we create a new ticket (if tickets sold)
1303
-                    // if they aren't different then we go ahead and modify existing ticket.
1304
-                    $create_new_TKT = $ticket_sold && ! $TKT->deleted() && EEH_Money::compare_floats(
1305
-                        $ticket_price,
1306
-                        $TKT->get('TKT_price'),
1307
-                        '!=='
1308
-                    );
1309
-                    $TKT->set_date_format($incoming_date_formats[0]);
1310
-                    $TKT->set_time_format($incoming_date_formats[1]);
1311
-                    // set new values
1312
-                    foreach ($TKT_values as $field => $value) {
1313
-                        if ($field === 'TKT_qty') {
1314
-                            $TKT->set_qty($value);
1315
-                        } else {
1316
-                            $TKT->set($field, $value);
1317
-                        }
1318
-                    }
1319
-                    // if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1320
-                    if ($create_new_TKT) {
1321
-                        // archive the old ticket first
1322
-                        $TKT->set('TKT_deleted', 1);
1323
-                        $TKT->save();
1324
-                        // make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1325
-                        $saved_tickets[ $TKT->ID() ] = $TKT;
1326
-                        // 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.
1327
-                        $TKT = clone $TKT;
1328
-                        $TKT->set('TKT_ID', 0);
1329
-                        $TKT->set('TKT_deleted', 0);
1330
-                        $TKT->set('TKT_price', $ticket_price);
1331
-                        $TKT->set('TKT_sold', 0);
1332
-                        // now we need to make sure that $new prices are created as well and attached to new ticket.
1333
-                        $update_prices = true;
1334
-                    }
1335
-                    // make sure price is set if it hasn't been already
1336
-                    $TKT->set('TKT_price', $ticket_price);
1337
-                }
1338
-            } else {
1339
-                // no TKT_id so a new TKT
1340
-                $TKT_values['TKT_price'] = $ticket_price;
1341
-                $TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1342
-                if ($TKT instanceof EE_Ticket) {
1343
-                    // need to reset values to properly account for the date formats
1344
-                    $TKT->set_date_format($incoming_date_formats[0]);
1345
-                    $TKT->set_time_format($incoming_date_formats[1]);
1346
-                    $TKT->set_timezone($evtobj->get_timezone());
1347
-                    // set new values
1348
-                    foreach ($TKT_values as $field => $value) {
1349
-                        if ($field === 'TKT_qty') {
1350
-                            $TKT->set_qty($value);
1351
-                        } else {
1352
-                            $TKT->set($field, $value);
1353
-                        }
1354
-                    }
1355
-                    $update_prices = true;
1356
-                }
1357
-            }
1358
-            // cap ticket qty by datetime reg limits
1359
-            $TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1360
-            // update ticket.
1361
-            $TKT->save();
1362
-            // 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.
1363
-            if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1364
-                $TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1365
-                $TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1366
-                $TKT->save();
1367
-            }
1368
-            // initially let's add the ticket to the dtt
1369
-            $saved_dtt->_add_relation_to($TKT, 'Ticket');
1370
-            $saved_tickets[ $TKT->ID() ] = $TKT;
1371
-            // add prices to ticket
1372
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1373
-        }
1374
-        // 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.
1375
-        $old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
1376
-        $tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1377
-        foreach ($tickets_removed as $id) {
1378
-            $id = absint($id);
1379
-            // get the ticket for this id
1380
-            $tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1381
-            // 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)
1382
-            $dtts = $tkt_to_remove->get_many_related('Datetime');
1383
-            foreach ($dtts as $dtt) {
1384
-                $tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1385
-            }
1386
-            // 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))
1387
-            $tkt_to_remove->delete_related_permanently('Price');
1388
-            // finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1389
-            $tkt_to_remove->delete_permanently();
1390
-        }
1391
-        return array($saved_dtt, $saved_tickets);
1392
-    }
1393
-
1394
-
1395
-    /**
1396
-     * This attaches a list of given prices to a ticket.
1397
-     * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1398
-     * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1399
-     * price info and prices are automatically "archived" via the ticket.
1400
-     *
1401
-     * @access  private
1402
-     * @param array     $prices     Array of prices from the form.
1403
-     * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1404
-     * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1405
-     * @return  void
1406
-     * @throws EE_Error
1407
-     * @throws InvalidArgumentException
1408
-     * @throws InvalidDataTypeException
1409
-     * @throws InvalidInterfaceException
1410
-     * @throws ReflectionException
1411
-     */
1412
-    private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1413
-    {
1414
-        foreach ($prices as $row => $prc) {
1415
-            $PRC_values = array(
1416
-                'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1417
-                'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1418
-                'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1419
-                'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1420
-                'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1421
-                'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1422
-                'PRC_order'      => $row,
1423
-            );
1424
-            if ($new_prices || empty($PRC_values['PRC_ID'])) {
1425
-                $PRC_values['PRC_ID'] = 0;
1426
-                $PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1427
-            } else {
1428
-                $PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1429
-                // update this price with new values
1430
-                foreach ($PRC_values as $field => $newprc) {
1431
-                    $PRC->set($field, $newprc);
1432
-                }
1433
-                $PRC->save();
1434
-            }
1435
-            $ticket->_add_relation_to($PRC, 'Price');
1436
-        }
1437
-    }
1438
-
1439
-
1440
-    /**
1441
-     * Add in our autosave ajax handlers
1442
-     *
1443
-     */
1444
-    protected function _ee_autosave_create_new()
1445
-    {
1446
-    }
1447
-
1448
-
1449
-    /**
1450
-     * More autosave handlers.
1451
-     */
1452
-    protected function _ee_autosave_edit()
1453
-    {
1454
-    }
1455
-
1456
-
1457
-    /**
1458
-     *    _generate_publish_box_extra_content
1459
-     *
1460
-     * @throws DomainException
1461
-     * @throws EE_Error
1462
-     * @throws InvalidArgumentException
1463
-     * @throws InvalidDataTypeException
1464
-     * @throws InvalidInterfaceException
1465
-     * @throws ReflectionException
1466
-     */
1467
-    private function _generate_publish_box_extra_content()
1468
-    {
1469
-        // load formatter helper
1470
-        // args for getting related registrations
1471
-        $approved_query_args = array(
1472
-            array(
1473
-                'REG_deleted' => 0,
1474
-                'STS_ID'      => EEM_Registration::status_id_approved,
1475
-            ),
1476
-        );
1477
-        $not_approved_query_args = array(
1478
-            array(
1479
-                'REG_deleted' => 0,
1480
-                'STS_ID'      => EEM_Registration::status_id_not_approved,
1481
-            ),
1482
-        );
1483
-        $pending_payment_query_args = array(
1484
-            array(
1485
-                'REG_deleted' => 0,
1486
-                'STS_ID'      => EEM_Registration::status_id_pending_payment,
1487
-            ),
1488
-        );
1489
-        // publish box
1490
-        $publish_box_extra_args = array(
1491
-            'view_approved_reg_url'        => add_query_arg(
1492
-                array(
1493
-                    'action'      => 'default',
1494
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1495
-                    '_reg_status' => EEM_Registration::status_id_approved,
1496
-                ),
1497
-                REG_ADMIN_URL
1498
-            ),
1499
-            'view_not_approved_reg_url'    => add_query_arg(
1500
-                array(
1501
-                    'action'      => 'default',
1502
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1503
-                    '_reg_status' => EEM_Registration::status_id_not_approved,
1504
-                ),
1505
-                REG_ADMIN_URL
1506
-            ),
1507
-            'view_pending_payment_reg_url' => add_query_arg(
1508
-                array(
1509
-                    'action'      => 'default',
1510
-                    'event_id'    => $this->_cpt_model_obj->ID(),
1511
-                    '_reg_status' => EEM_Registration::status_id_pending_payment,
1512
-                ),
1513
-                REG_ADMIN_URL
1514
-            ),
1515
-            'approved_regs'                => $this->_cpt_model_obj->count_related(
1516
-                'Registration',
1517
-                $approved_query_args
1518
-            ),
1519
-            'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1520
-                'Registration',
1521
-                $not_approved_query_args
1522
-            ),
1523
-            'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1524
-                'Registration',
1525
-                $pending_payment_query_args
1526
-            ),
1527
-            'misc_pub_section_class'       => apply_filters(
1528
-                'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1529
-                'misc-pub-section'
1530
-            ),
1531
-        );
1532
-        ob_start();
1533
-        do_action(
1534
-            'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1535
-            $this->_cpt_model_obj
1536
-        );
1537
-        $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1538
-        // load template
1539
-        EEH_Template::display_template(
1540
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1541
-            $publish_box_extra_args
1542
-        );
1543
-    }
1544
-
1545
-
1546
-    /**
1547
-     * @return EE_Event
1548
-     */
1549
-    public function get_event_object()
1550
-    {
1551
-        return $this->_cpt_model_obj;
1552
-    }
1553
-
1554
-
1555
-
1556
-
1557
-    /** METABOXES * */
1558
-    /**
1559
-     * _register_event_editor_meta_boxes
1560
-     * add all metaboxes related to the event_editor
1561
-     *
1562
-     * @return void
1563
-     * @throws EE_Error
1564
-     * @throws InvalidArgumentException
1565
-     * @throws InvalidDataTypeException
1566
-     * @throws InvalidInterfaceException
1567
-     * @throws ReflectionException
1568
-     */
1569
-    protected function _register_event_editor_meta_boxes()
1570
-    {
1571
-        $this->verify_cpt_object();
1572
-        if (! EE_Registry::instance()->CFG->admin->useAdvancedEditor()) {
1573
-            add_meta_box(
1574
-                'espresso_event_editor_tickets',
1575
-                esc_html__('Event Datetime & Ticket', 'event_espresso'),
1576
-                [$this, 'ticket_metabox'],
1577
-                $this->page_slug,
1578
-                'normal',
1579
-                'high'
1580
-            );
1581
-        }
1582
-        add_meta_box(
1583
-            'espresso_event_editor_event_options',
1584
-            esc_html__('Event Registration Options', 'event_espresso'),
1585
-            array($this, 'registration_options_meta_box'),
1586
-            $this->page_slug,
1587
-            'side'
1588
-        );
1589
-        // NOTE: if you're looking for other metaboxes in here,
1590
-        // where a metabox has a related management page in the admin
1591
-        // you will find it setup in the related management page's "_Hooks" file.
1592
-        // i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1593
-    }
1594
-
1595
-
1596
-    /**
1597
-     * @throws DomainException
1598
-     * @throws EE_Error
1599
-     * @throws InvalidArgumentException
1600
-     * @throws InvalidDataTypeException
1601
-     * @throws InvalidInterfaceException
1602
-     * @throws ReflectionException
1603
-     */
1604
-    public function ticket_metabox()
1605
-    {
1606
-        $existing_datetime_ids = $existing_ticket_ids = array();
1607
-        // defaults for template args
1608
-        $template_args = array(
1609
-            'existing_datetime_ids'    => '',
1610
-            'event_datetime_help_link' => '',
1611
-            'ticket_options_help_link' => '',
1612
-            'time'                     => null,
1613
-            'ticket_rows'              => '',
1614
-            'existing_ticket_ids'      => '',
1615
-            'total_ticket_rows'        => 1,
1616
-            'ticket_js_structure'      => '',
1617
-            'trash_icon'               => 'ee-lock-icon',
1618
-            'disabled'                 => '',
1619
-        );
1620
-        $event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1621
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1622
-        /**
1623
-         * 1. Start with retrieving Datetimes
1624
-         * 2. Fore each datetime get related tickets
1625
-         * 3. For each ticket get related prices
1626
-         */
1627
-        $times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1628
-        /** @type EE_Datetime $first_datetime */
1629
-        $first_datetime = reset($times);
1630
-        // do we get related tickets?
1631
-        if ($first_datetime instanceof EE_Datetime
1632
-            && $first_datetime->ID() !== 0
1633
-        ) {
1634
-            $existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1635
-            $template_args['time'] = $first_datetime;
1636
-            $related_tickets = $first_datetime->tickets(
1637
-                array(
1638
-                    array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1639
-                    'default_where_conditions' => 'none',
1640
-                )
1641
-            );
1642
-            if (! empty($related_tickets)) {
1643
-                $template_args['total_ticket_rows'] = count($related_tickets);
1644
-                $row = 0;
1645
-                foreach ($related_tickets as $ticket) {
1646
-                    $existing_ticket_ids[] = $ticket->get('TKT_ID');
1647
-                    $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1648
-                    $row++;
1649
-                }
1650
-            } else {
1651
-                $template_args['total_ticket_rows'] = 1;
1652
-                /** @type EE_Ticket $ticket */
1653
-                $ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1654
-                $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1655
-            }
1656
-        } else {
1657
-            $template_args['time'] = $times[0];
1658
-            /** @type EE_Ticket $ticket */
1659
-            $ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1660
-            $template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1661
-            // NOTE: we're just sending the first default row
1662
-            // (decaf can't manage default tickets so this should be sufficient);
1663
-        }
1664
-        $template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1665
-            'event_editor_event_datetimes_help_tab'
1666
-        );
1667
-        $template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1668
-        $template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1669
-        $template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1670
-        $template_args['ticket_js_structure'] = $this->_get_ticket_row(
1671
-            EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1672
-            true
1673
-        );
1674
-        $template = apply_filters(
1675
-            'FHEE__Events_Admin_Page__ticket_metabox__template',
1676
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1677
-        );
1678
-        EEH_Template::display_template($template, $template_args);
1679
-    }
1680
-
1681
-
1682
-    /**
1683
-     * Setup an individual ticket form for the decaf event editor page
1684
-     *
1685
-     * @access private
1686
-     * @param EE_Ticket $ticket   the ticket object
1687
-     * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1688
-     * @param int       $row
1689
-     * @return string generated html for the ticket row.
1690
-     * @throws DomainException
1691
-     * @throws EE_Error
1692
-     * @throws InvalidArgumentException
1693
-     * @throws InvalidDataTypeException
1694
-     * @throws InvalidInterfaceException
1695
-     * @throws ReflectionException
1696
-     */
1697
-    private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1698
-    {
1699
-        $template_args = array(
1700
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1701
-            'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1702
-                : '',
1703
-            'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1704
-            'TKT_ID'              => $ticket->get('TKT_ID'),
1705
-            'TKT_name'            => $ticket->get('TKT_name'),
1706
-            'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1707
-            'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1708
-            'TKT_is_default'      => $ticket->get('TKT_is_default'),
1709
-            'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1710
-            'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1711
-            'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1712
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1713
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1714
-                ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1715
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1716
-                : ' disabled=disabled',
1717
-        );
1718
-        $price = $ticket->ID() !== 0
1719
-            ? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1720
-            : EE_Registry::instance()->load_model('Price')->create_default_object();
1721
-        $price_args = array(
1722
-            'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1723
-            'PRC_amount'            => $price->get('PRC_amount'),
1724
-            'PRT_ID'                => $price->get('PRT_ID'),
1725
-            'PRC_ID'                => $price->get('PRC_ID'),
1726
-            'PRC_is_default'        => $price->get('PRC_is_default'),
1727
-        );
1728
-        // make sure we have default start and end dates if skeleton
1729
-        // handle rows that should NOT be empty
1730
-        if (empty($template_args['TKT_start_date'])) {
1731
-            // if empty then the start date will be now.
1732
-            $template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1733
-        }
1734
-        if (empty($template_args['TKT_end_date'])) {
1735
-            // get the earliest datetime (if present);
1736
-            $earliest_dtt = $this->_cpt_model_obj->ID() > 0
1737
-                ? $this->_cpt_model_obj->get_first_related(
1738
-                    'Datetime',
1739
-                    array('order_by' => array('DTT_EVT_start' => 'ASC'))
1740
-                )
1741
-                : null;
1742
-            if (! empty($earliest_dtt)) {
1743
-                $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1744
-            } else {
1745
-                $template_args['TKT_end_date'] = date(
1746
-                    'Y-m-d h:i a',
1747
-                    mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))
1748
-                );
1749
-            }
1750
-        }
1751
-        $template_args = array_merge($template_args, $price_args);
1752
-        $template = apply_filters(
1753
-            'FHEE__Events_Admin_Page__get_ticket_row__template',
1754
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1755
-            $ticket
1756
-        );
1757
-        return EEH_Template::display_template($template, $template_args, true);
1758
-    }
1759
-
1760
-
1761
-    /**
1762
-     * @throws DomainException
1763
-     * @throws EE_Error
1764
-     */
1765
-    public function registration_options_meta_box()
1766
-    {
1767
-        $yes_no_values = array(
1768
-            array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1769
-            array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1770
-        );
1771
-        $default_reg_status_values = EEM_Registration::reg_status_array(
1772
-            array(
1773
-                EEM_Registration::status_id_cancelled,
1774
-                EEM_Registration::status_id_declined,
1775
-                EEM_Registration::status_id_incomplete,
1776
-            ),
1777
-            true
1778
-        );
1779
-        // $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1780
-        $template_args['_event'] = $this->_cpt_model_obj;
1781
-        $template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1782
-        $template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1783
-        $template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1784
-            'default_reg_status',
1785
-            $default_reg_status_values,
1786
-            $this->_cpt_model_obj->default_registration_status()
1787
-        );
1788
-        $template_args['display_description'] = EEH_Form_Fields::select_input(
1789
-            'display_desc',
1790
-            $yes_no_values,
1791
-            $this->_cpt_model_obj->display_description()
1792
-        );
1793
-        $template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1794
-            'display_ticket_selector',
1795
-            $yes_no_values,
1796
-            $this->_cpt_model_obj->display_ticket_selector(),
1797
-            '',
1798
-            '',
1799
-            false
1800
-        );
1801
-        $template_args['additional_registration_options'] = apply_filters(
1802
-            'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1803
-            '',
1804
-            $template_args,
1805
-            $yes_no_values,
1806
-            $default_reg_status_values
1807
-        );
1808
-        EEH_Template::display_template(
1809
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1810
-            $template_args
1811
-        );
1812
-    }
1813
-
1814
-
1815
-    /**
1816
-     * _get_events()
1817
-     * This method simply returns all the events (for the given _view and paging)
1818
-     *
1819
-     * @access public
1820
-     * @param int  $per_page     count of items per page (20 default);
1821
-     * @param int  $current_page what is the current page being viewed.
1822
-     * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1823
-     *                           If FALSE then we return an array of event objects
1824
-     *                           that match the given _view and paging parameters.
1825
-     * @return array an array of event objects.
1826
-     * @throws EE_Error
1827
-     * @throws InvalidArgumentException
1828
-     * @throws InvalidDataTypeException
1829
-     * @throws InvalidInterfaceException
1830
-     * @throws ReflectionException
1831
-     * @throws Exception
1832
-     * @throws Exception
1833
-     * @throws Exception
1834
-     */
1835
-    public function get_events($per_page = 10, $current_page = 1, $count = false)
1836
-    {
1837
-        $EEME = $this->_event_model();
1838
-        $offset = ($current_page - 1) * $per_page;
1839
-        $limit = $count ? null : $offset . ',' . $per_page;
1840
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1841
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
1842
-        if (isset($this->_req_data['month_range'])) {
1843
-            $pieces = explode(' ', $this->_req_data['month_range'], 3);
1844
-            // simulate the FIRST day of the month, that fixes issues for months like February
1845
-            // where PHP doesn't know what to assume for date.
1846
-            // @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1847
-            $month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1848
-            $year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1849
-        }
1850
-        $where = array();
1851
-        $status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1852
-        // determine what post_status our condition will have for the query.
1853
-        switch ($status) {
1854
-            case 'month':
1855
-            case 'today':
1856
-            case null:
1857
-            case 'all':
1858
-                break;
1859
-            case 'draft':
1860
-                $where['status'] = array('IN', array('draft', 'auto-draft'));
1861
-                break;
1862
-            default:
1863
-                $where['status'] = $status;
1864
-        }
1865
-        // categories?
1866
-        $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1867
-            ? $this->_req_data['EVT_CAT'] : null;
1868
-        if (! empty($category)) {
1869
-            $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1870
-            $where['Term_Taxonomy.term_id'] = $category;
1871
-        }
1872
-        // date where conditions
1873
-        $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1874
-        if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] !== '') {
1875
-            $DateTime = new DateTime(
1876
-                $year_r . '-' . $month_r . '-01 00:00:00',
1877
-                new DateTimeZone('UTC')
1878
-            );
1879
-            $start = $DateTime->getTimestamp();
1880
-            // set the datetime to be the end of the month
1881
-            $DateTime->setDate(
1882
-                $year_r,
1883
-                $month_r,
1884
-                $DateTime->format('t')
1885
-            )->setTime(23, 59, 59);
1886
-            $end = $DateTime->getTimestamp();
1887
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1888
-        } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'today') {
1889
-            $DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1890
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1891
-            $end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1892
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1893
-        } elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'month') {
1894
-            $now = date('Y-m-01');
1895
-            $DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1896
-            $start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1897
-            $end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1898
-                            ->setTime(23, 59, 59)
1899
-                            ->format(implode(' ', $start_formats));
1900
-            $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1901
-        }
1902
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1903
-            $where['EVT_wp_user'] = get_current_user_id();
1904
-        } elseif (! isset($where['status'])
1905
-            && ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')
1906
-        ) {
1907
-            $where['OR'] = array(
1908
-                'status*restrict_private' => array('!=', 'private'),
1909
-                'AND'                     => array(
1910
-                    'status*inclusive' => array('=', 'private'),
1911
-                    'EVT_wp_user'      => get_current_user_id(),
1912
-                ),
1913
-            );
1914
-        }
1915
-
1916
-        if (isset($this->_req_data['EVT_wp_user'])
1917
-            && (int) $this->_req_data['EVT_wp_user'] !== (int) get_current_user_id()
1918
-            && EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1919
-        ) {
1920
-            $where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1921
-        }
1922
-        // search query handling
1923
-        if (isset($this->_req_data['s'])) {
1924
-            $search_string = '%' . $this->_req_data['s'] . '%';
1925
-            $where['OR'] = array(
1926
-                'EVT_name'       => array('LIKE', $search_string),
1927
-                'EVT_desc'       => array('LIKE', $search_string),
1928
-                'EVT_short_desc' => array('LIKE', $search_string),
1929
-            );
1930
-        }
1931
-        // filter events by venue.
1932
-        if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) {
1933
-            $where['Venue.VNU_ID'] = absint($this->_req_data['venue']);
1934
-        }
1935
-        $where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1936
-        $query_params = apply_filters(
1937
-            'FHEE__Events_Admin_Page__get_events__query_params',
1938
-            array(
1939
-                $where,
1940
-                'limit'    => $limit,
1941
-                'order_by' => $orderby,
1942
-                'order'    => $order,
1943
-                'group_by' => 'EVT_ID',
1944
-            ),
1945
-            $this->_req_data
1946
-        );
1947
-
1948
-        // let's first check if we have special requests coming in.
1949
-        if (isset($this->_req_data['active_status'])) {
1950
-            switch ($this->_req_data['active_status']) {
1951
-                case 'upcoming':
1952
-                    return $EEME->get_upcoming_events($query_params, $count);
1953
-                    break;
1954
-                case 'expired':
1955
-                    return $EEME->get_expired_events($query_params, $count);
1956
-                    break;
1957
-                case 'active':
1958
-                    return $EEME->get_active_events($query_params, $count);
1959
-                    break;
1960
-                case 'inactive':
1961
-                    return $EEME->get_inactive_events($query_params, $count);
1962
-                    break;
1963
-            }
1964
-        }
1965
-
1966
-        $events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1967
-        return $events;
1968
-    }
1969
-
1970
-
1971
-    /**
1972
-     * handling for WordPress CPT actions (trash, restore, delete)
1973
-     *
1974
-     * @param string $post_id
1975
-     * @throws EE_Error
1976
-     * @throws InvalidArgumentException
1977
-     * @throws InvalidDataTypeException
1978
-     * @throws InvalidInterfaceException
1979
-     * @throws ReflectionException
1980
-     */
1981
-    public function trash_cpt_item($post_id)
1982
-    {
1983
-        $this->_req_data['EVT_ID'] = $post_id;
1984
-        $this->_trash_or_restore_event('trash', false);
1985
-    }
1986
-
1987
-
1988
-    /**
1989
-     * @param string $post_id
1990
-     * @throws EE_Error
1991
-     * @throws InvalidArgumentException
1992
-     * @throws InvalidDataTypeException
1993
-     * @throws InvalidInterfaceException
1994
-     * @throws ReflectionException
1995
-     */
1996
-    public function restore_cpt_item($post_id)
1997
-    {
1998
-        $this->_req_data['EVT_ID'] = $post_id;
1999
-        $this->_trash_or_restore_event('draft', false);
2000
-    }
2001
-
2002
-
2003
-    /**
2004
-     * @param string $post_id
2005
-     * @throws EE_Error
2006
-     * @throws InvalidArgumentException
2007
-     * @throws InvalidDataTypeException
2008
-     * @throws InvalidInterfaceException
2009
-     * @throws ReflectionException
2010
-     */
2011
-    public function delete_cpt_item($post_id)
2012
-    {
2013
-        $this->_req_data['EVT_ID'] = $post_id;
2014
-        $this->_delete_event(false);
2015
-    }
2016
-
2017
-
2018
-    /**
2019
-     * _trash_or_restore_event
2020
-     *
2021
-     * @access protected
2022
-     * @param string $event_status
2023
-     * @param bool   $redirect_after
2024
-     * @throws EE_Error
2025
-     * @throws InvalidArgumentException
2026
-     * @throws InvalidDataTypeException
2027
-     * @throws InvalidInterfaceException
2028
-     * @throws ReflectionException
2029
-     */
2030
-    protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2031
-    {
2032
-        // determine the event id and set to array.
2033
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
2034
-        // loop thru events
2035
-        if ($EVT_ID) {
2036
-            // clean status
2037
-            $event_status = sanitize_key($event_status);
2038
-            // grab status
2039
-            if (! empty($event_status)) {
2040
-                $success = $this->_change_event_status($EVT_ID, $event_status);
2041
-            } else {
2042
-                $success = false;
2043
-                $msg = esc_html__(
2044
-                    'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2045
-                    'event_espresso'
2046
-                );
2047
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2048
-            }
2049
-        } else {
2050
-            $success = false;
2051
-            $msg = esc_html__(
2052
-                'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2053
-                'event_espresso'
2054
-            );
2055
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2056
-        }
2057
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2058
-        if ($redirect_after) {
2059
-            $this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
2060
-        }
2061
-    }
2062
-
2063
-
2064
-    /**
2065
-     * _trash_or_restore_events
2066
-     *
2067
-     * @access protected
2068
-     * @param string $event_status
2069
-     * @return void
2070
-     * @throws EE_Error
2071
-     * @throws InvalidArgumentException
2072
-     * @throws InvalidDataTypeException
2073
-     * @throws InvalidInterfaceException
2074
-     * @throws ReflectionException
2075
-     */
2076
-    protected function _trash_or_restore_events($event_status = 'trash')
2077
-    {
2078
-        // clean status
2079
-        $event_status = sanitize_key($event_status);
2080
-        // grab status
2081
-        if (! empty($event_status)) {
2082
-            $success = true;
2083
-            // determine the event id and set to array.
2084
-            $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2085
-            // loop thru events
2086
-            foreach ($EVT_IDs as $EVT_ID) {
2087
-                if ($EVT_ID = absint($EVT_ID)) {
2088
-                    $results = $this->_change_event_status($EVT_ID, $event_status);
2089
-                    $success = $results !== false ? $success : false;
2090
-                } else {
2091
-                    $msg = sprintf(
2092
-                        esc_html__(
2093
-                            'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2094
-                            'event_espresso'
2095
-                        ),
2096
-                        $EVT_ID
2097
-                    );
2098
-                    EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2099
-                    $success = false;
2100
-                }
2101
-            }
2102
-        } else {
2103
-            $success = false;
2104
-            $msg = esc_html__(
2105
-                'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2106
-                'event_espresso'
2107
-            );
2108
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2109
-        }
2110
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2111
-        $success = $success ? 2 : false;
2112
-        $action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2113
-        $this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
2114
-    }
2115
-
2116
-
2117
-    /**
2118
-     * _trash_or_restore_events
2119
-     *
2120
-     * @access  private
2121
-     * @param int    $EVT_ID
2122
-     * @param string $event_status
2123
-     * @return bool
2124
-     * @throws EE_Error
2125
-     * @throws InvalidArgumentException
2126
-     * @throws InvalidDataTypeException
2127
-     * @throws InvalidInterfaceException
2128
-     * @throws ReflectionException
2129
-     */
2130
-    private function _change_event_status($EVT_ID = 0, $event_status = '')
2131
-    {
2132
-        // grab event id
2133
-        if (! $EVT_ID) {
2134
-            $msg = esc_html__(
2135
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2136
-                'event_espresso'
2137
-            );
2138
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2139
-            return false;
2140
-        }
2141
-        $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2142
-        // clean status
2143
-        $event_status = sanitize_key($event_status);
2144
-        // grab status
2145
-        if (empty($event_status)) {
2146
-            $msg = esc_html__(
2147
-                'An error occurred. No Event Status or an invalid Event Status was received.',
2148
-                'event_espresso'
2149
-            );
2150
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2151
-            return false;
2152
-        }
2153
-        // was event trashed or restored ?
2154
-        switch ($event_status) {
2155
-            case 'draft':
2156
-                $action = 'restored from the trash';
2157
-                $hook = 'AHEE_event_restored_from_trash';
2158
-                break;
2159
-            case 'trash':
2160
-                $action = 'moved to the trash';
2161
-                $hook = 'AHEE_event_moved_to_trash';
2162
-                break;
2163
-            default:
2164
-                $action = 'updated';
2165
-                $hook = false;
2166
-        }
2167
-        // use class to change status
2168
-        $this->_cpt_model_obj->set_status($event_status);
2169
-        $success = $this->_cpt_model_obj->save();
2170
-        if ($success === false) {
2171
-            $msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2172
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2173
-            return false;
2174
-        }
2175
-        if ($hook) {
2176
-            do_action($hook);
2177
-        }
2178
-        return true;
2179
-    }
2180
-
2181
-
2182
-    /**
2183
-     * _delete_event
2184
-     *
2185
-     * @access protected
2186
-     * @param bool $redirect_after
2187
-     * @throws EE_Error
2188
-     * @throws InvalidArgumentException
2189
-     * @throws InvalidDataTypeException
2190
-     * @throws InvalidInterfaceException
2191
-     * @throws ReflectionException
2192
-     */
2193
-    protected function _delete_event($redirect_after = true)
2194
-    {
2195
-        // determine the event id and set to array.
2196
-        $EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2197
-        $EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2198
-        // loop thru events
2199
-        if ($EVT_ID) {
2200
-            $success = $this->_permanently_delete_event($EVT_ID);
2201
-            // get list of events with no prices
2202
-            $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2203
-            // remove this event from the list of events with no prices
2204
-            if (isset($espresso_no_ticket_prices[ $EVT_ID ])) {
2205
-                unset($espresso_no_ticket_prices[ $EVT_ID ]);
2206
-            }
2207
-            update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2208
-        } else {
2209
-            $success = false;
2210
-            $msg = esc_html__(
2211
-                'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2212
-                'event_espresso'
2213
-            );
2214
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2215
-        }
2216
-        if ($redirect_after) {
2217
-            $this->_redirect_after_action(
2218
-                $success,
2219
-                'Event',
2220
-                'deleted',
2221
-                array('action' => 'default', 'status' => 'trash')
2222
-            );
2223
-        }
2224
-    }
2225
-
2226
-
2227
-    /**
2228
-     * _delete_events
2229
-     *
2230
-     * @access protected
2231
-     * @return void
2232
-     * @throws EE_Error
2233
-     * @throws InvalidArgumentException
2234
-     * @throws InvalidDataTypeException
2235
-     * @throws InvalidInterfaceException
2236
-     * @throws ReflectionException
2237
-     */
2238
-    protected function _delete_events()
2239
-    {
2240
-        $success = true;
2241
-        // get list of events with no prices
2242
-        $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2243
-        // determine the event id and set to array.
2244
-        $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2245
-        // loop thru events
2246
-        foreach ($EVT_IDs as $EVT_ID) {
2247
-            $EVT_ID = absint($EVT_ID);
2248
-            if ($EVT_ID) {
2249
-                $results = $this->_permanently_delete_event($EVT_ID);
2250
-                $success = $results !== false ? $success : false;
2251
-                // remove this event from the list of events with no prices
2252
-                unset($espresso_no_ticket_prices[ $EVT_ID ]);
2253
-            } else {
2254
-                $success = false;
2255
-                $msg = esc_html__(
2256
-                    'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2257
-                    'event_espresso'
2258
-                );
2259
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2260
-            }
2261
-        }
2262
-        update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2263
-        // in order to force a pluralized result message we need to send back a success status greater than 1
2264
-        $success = $success ? 2 : false;
2265
-        $this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2266
-    }
2267
-
2268
-
2269
-    /**
2270
-     * _permanently_delete_event
2271
-     *
2272
-     * @access  private
2273
-     * @param int $EVT_ID
2274
-     * @return bool
2275
-     * @throws EE_Error
2276
-     * @throws InvalidArgumentException
2277
-     * @throws InvalidDataTypeException
2278
-     * @throws InvalidInterfaceException
2279
-     * @throws ReflectionException
2280
-     */
2281
-    private function _permanently_delete_event($EVT_ID = 0)
2282
-    {
2283
-        // grab event id
2284
-        if (! $EVT_ID) {
2285
-            $msg = esc_html__(
2286
-                'An error occurred. No Event ID or an invalid Event ID was received.',
2287
-                'event_espresso'
2288
-            );
2289
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2290
-            return false;
2291
-        }
2292
-        if (! $this->_cpt_model_obj instanceof EE_Event
2293
-            || $this->_cpt_model_obj->ID() !== $EVT_ID
2294
-        ) {
2295
-            $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2296
-        }
2297
-        if (! $this->_cpt_model_obj instanceof EE_Event) {
2298
-            return false;
2299
-        }
2300
-        // need to delete related tickets and prices first.
2301
-        $datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2302
-        foreach ($datetimes as $datetime) {
2303
-            $this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2304
-            $tickets = $datetime->get_many_related('Ticket');
2305
-            foreach ($tickets as $ticket) {
2306
-                $ticket->_remove_relation_to($datetime, 'Datetime');
2307
-                $ticket->delete_related_permanently('Price');
2308
-                $ticket->delete_permanently();
2309
-            }
2310
-            $datetime->delete();
2311
-        }
2312
-        // what about related venues or terms?
2313
-        $venues = $this->_cpt_model_obj->get_many_related('Venue');
2314
-        foreach ($venues as $venue) {
2315
-            $this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2316
-        }
2317
-        // any attached question groups?
2318
-        $question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2319
-        if (! empty($question_groups)) {
2320
-            foreach ($question_groups as $question_group) {
2321
-                $this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2322
-            }
2323
-        }
2324
-        // Message Template Groups
2325
-        $this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2326
-        /** @type EE_Term_Taxonomy[] $term_taxonomies */
2327
-        $term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2328
-        foreach ($term_taxonomies as $term_taxonomy) {
2329
-            $this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2330
-        }
2331
-        $success = $this->_cpt_model_obj->delete_permanently();
2332
-        // did it all go as planned ?
2333
-        if ($success) {
2334
-            $msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2335
-            EE_Error::add_success($msg);
2336
-        } else {
2337
-            $msg = sprintf(
2338
-                esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2339
-                $EVT_ID
2340
-            );
2341
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2342
-            return false;
2343
-        }
2344
-        do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2345
-        return true;
2346
-    }
2347
-
2348
-
2349
-    /**
2350
-     * get total number of events
2351
-     *
2352
-     * @access public
2353
-     * @return int
2354
-     * @throws EE_Error
2355
-     * @throws InvalidArgumentException
2356
-     * @throws InvalidDataTypeException
2357
-     * @throws InvalidInterfaceException
2358
-     */
2359
-    public function total_events()
2360
-    {
2361
-        $count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2362
-        return $count;
2363
-    }
2364
-
2365
-
2366
-    /**
2367
-     * get total number of draft events
2368
-     *
2369
-     * @access public
2370
-     * @return int
2371
-     * @throws EE_Error
2372
-     * @throws InvalidArgumentException
2373
-     * @throws InvalidDataTypeException
2374
-     * @throws InvalidInterfaceException
2375
-     */
2376
-    public function total_events_draft()
2377
-    {
2378
-        $where = array(
2379
-            'status' => array('IN', array('draft', 'auto-draft')),
2380
-        );
2381
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2382
-        return $count;
2383
-    }
2384
-
2385
-
2386
-    /**
2387
-     * get total number of trashed events
2388
-     *
2389
-     * @access public
2390
-     * @return int
2391
-     * @throws EE_Error
2392
-     * @throws InvalidArgumentException
2393
-     * @throws InvalidDataTypeException
2394
-     * @throws InvalidInterfaceException
2395
-     */
2396
-    public function total_trashed_events()
2397
-    {
2398
-        $where = array(
2399
-            'status' => 'trash',
2400
-        );
2401
-        $count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2402
-        return $count;
2403
-    }
2404
-
2405
-
2406
-    /**
2407
-     *    _default_event_settings
2408
-     *    This generates the Default Settings Tab
2409
-     *
2410
-     * @return void
2411
-     * @throws DomainException
2412
-     * @throws EE_Error
2413
-     * @throws InvalidArgumentException
2414
-     * @throws InvalidDataTypeException
2415
-     * @throws InvalidInterfaceException
2416
-     */
2417
-    protected function _default_event_settings()
2418
-    {
2419
-        $this->_set_add_edit_form_tags('update_default_event_settings');
2420
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
2421
-        $this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2422
-        $this->display_admin_page_with_sidebar();
2423
-    }
2424
-
2425
-
2426
-    /**
2427
-     * Return the form for event settings.
2428
-     *
2429
-     * @return EE_Form_Section_Proper
2430
-     * @throws EE_Error
2431
-     */
2432
-    protected function _default_event_settings_form()
2433
-    {
2434
-        $registration_config = EE_Registry::instance()->CFG->registration;
2435
-        $registration_stati_for_selection = EEM_Registration::reg_status_array(
2436
-            // exclude
2437
-            array(
2438
-                EEM_Registration::status_id_cancelled,
2439
-                EEM_Registration::status_id_declined,
2440
-                EEM_Registration::status_id_incomplete,
2441
-                EEM_Registration::status_id_wait_list,
2442
-            ),
2443
-            true
2444
-        );
2445
-        return new EE_Form_Section_Proper(
2446
-            array(
2447
-                'name'            => 'update_default_event_settings',
2448
-                'html_id'         => 'update_default_event_settings',
2449
-                'html_class'      => 'form-table',
2450
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2451
-                'subsections'     => apply_filters(
2452
-                    'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2453
-                    array(
2454
-                        'default_reg_status'  => new EE_Select_Input(
2455
-                            $registration_stati_for_selection,
2456
-                            array(
2457
-                                'default'         => isset($registration_config->default_STS_ID)
2458
-                                                     && array_key_exists(
2459
-                                                         $registration_config->default_STS_ID,
2460
-                                                         $registration_stati_for_selection
2461
-                                                     )
2462
-                                    ? sanitize_text_field($registration_config->default_STS_ID)
2463
-                                    : EEM_Registration::status_id_pending_payment,
2464
-                                'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2465
-                                                     . EEH_Template::get_help_tab_link(
2466
-                                                         'default_settings_status_help_tab'
2467
-                                                     ),
2468
-                                'html_help_text'  => esc_html__(
2469
-                                    '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.',
2470
-                                    'event_espresso'
2471
-                                ),
2472
-                            )
2473
-                        ),
2474
-                        'default_max_tickets' => new EE_Integer_Input(
2475
-                            array(
2476
-                                'default'         => isset($registration_config->default_maximum_number_of_tickets)
2477
-                                    ? $registration_config->default_maximum_number_of_tickets
2478
-                                    : EEM_Event::get_default_additional_limit(),
2479
-                                'html_label_text' => esc_html__(
2480
-                                    'Default Maximum Tickets Allowed Per Order:',
2481
-                                    'event_espresso'
2482
-                                )
2483
-                                                     . EEH_Template::get_help_tab_link(
2484
-                                                         'default_maximum_tickets_help_tab"'
2485
-                                                     ),
2486
-                                'html_help_text'  => esc_html__(
2487
-                                    'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2488
-                                    'event_espresso'
2489
-                                ),
2490
-                            )
2491
-                        ),
2492
-                    )
2493
-                ),
2494
-            )
2495
-        );
2496
-    }
2497
-
2498
-
2499
-    /**
2500
-     * @return void
2501
-     * @throws EE_Error
2502
-     * @throws InvalidArgumentException
2503
-     * @throws InvalidDataTypeException
2504
-     * @throws InvalidInterfaceException
2505
-     */
2506
-    protected function _update_default_event_settings()
2507
-    {
2508
-        $form = $this->_default_event_settings_form();
2509
-        if ($form->was_submitted()) {
2510
-            $form->receive_form_submission();
2511
-            if ($form->is_valid()) {
2512
-                $registration_config = EE_Registry::instance()->CFG->registration;
2513
-                $valid_data = $form->valid_data();
2514
-                if (isset($valid_data['default_reg_status'])) {
2515
-                    $registration_config->default_STS_ID = $valid_data['default_reg_status'];
2516
-                }
2517
-                if (isset($valid_data['default_max_tickets'])) {
2518
-                    $registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2519
-                }
2520
-                do_action(
2521
-                    'AHEE__Events_Admin_Page___update_default_event_settings',
2522
-                    $valid_data,
2523
-                    EE_Registry::instance()->CFG,
2524
-                    $this
2525
-                );
2526
-                // update because data was valid!
2527
-                EE_Registry::instance()->CFG->update_espresso_config();
2528
-                EE_Error::overwrite_success();
2529
-                EE_Error::add_success(
2530
-                    __('Default Event Settings were updated', 'event_espresso')
2531
-                );
2532
-            }
2533
-        }
2534
-        $this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true);
2535
-    }
2536
-
2537
-
2538
-    /*************        Templates        *************/
2539
-    protected function _template_settings()
2540
-    {
2541
-        $this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2542
-        $this->_template_args['preview_img'] = '<img src="'
2543
-                                               . EVENTS_ASSETS_URL
2544
-                                               . '/images/'
2545
-                                               . 'caffeinated_template_features.jpg" alt="'
2546
-                                               . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2547
-                                               . '" />';
2548
-        $this->_template_args['preview_text'] = '<strong>'
2549
-                                                . esc_html__(
2550
-                                                    '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.',
2551
-                                                    'event_espresso'
2552
-                                                ) . '</strong>';
2553
-        $this->display_admin_caf_preview_page('template_settings_tab');
2554
-    }
2555
-
2556
-
2557
-    /** Event Category Stuff **/
2558
-    /**
2559
-     * set the _category property with the category object for the loaded page.
2560
-     *
2561
-     * @access private
2562
-     * @return void
2563
-     */
2564
-    private function _set_category_object()
2565
-    {
2566
-        if (isset($this->_category->id) && ! empty($this->_category->id)) {
2567
-            return;
2568
-        } //already have the category object so get out.
2569
-        // set default category object
2570
-        $this->_set_empty_category_object();
2571
-        // only set if we've got an id
2572
-        if (! isset($this->_req_data['EVT_CAT_ID'])) {
2573
-            return;
2574
-        }
2575
-        $category_id = absint($this->_req_data['EVT_CAT_ID']);
2576
-        $term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2577
-        if (! empty($term)) {
2578
-            $this->_category->category_name = $term->name;
2579
-            $this->_category->category_identifier = $term->slug;
2580
-            $this->_category->category_desc = $term->description;
2581
-            $this->_category->id = $term->term_id;
2582
-            $this->_category->parent = $term->parent;
2583
-        }
2584
-    }
2585
-
2586
-
2587
-    /**
2588
-     * Clears out category properties.
2589
-     */
2590
-    private function _set_empty_category_object()
2591
-    {
2592
-        $this->_category = new stdClass();
2593
-        $this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2594
-        $this->_category->id = $this->_category->parent = 0;
2595
-    }
2596
-
2597
-
2598
-    /**
2599
-     * @throws DomainException
2600
-     * @throws EE_Error
2601
-     * @throws InvalidArgumentException
2602
-     * @throws InvalidDataTypeException
2603
-     * @throws InvalidInterfaceException
2604
-     */
2605
-    protected function _category_list_table()
2606
-    {
2607
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2608
-        $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2609
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2610
-            'add_category',
2611
-            'add_category',
2612
-            array(),
2613
-            'add-new-h2'
2614
-        );
2615
-        $this->display_admin_list_table_page_with_sidebar();
2616
-    }
2617
-
2618
-
2619
-    /**
2620
-     * Output category details view.
2621
-     *
2622
-     * @param string $view
2623
-     * @throws DomainException
2624
-     * @throws EE_Error
2625
-     * @throws InvalidArgumentException
2626
-     * @throws InvalidDataTypeException
2627
-     * @throws InvalidInterfaceException
2628
-     */
2629
-    protected function _category_details($view)
2630
-    {
2631
-        // load formatter helper
2632
-        // load field generator helper
2633
-        $route = $view === 'edit' ? 'update_category' : 'insert_category';
2634
-        $this->_set_add_edit_form_tags($route);
2635
-        $this->_set_category_object();
2636
-        $id = ! empty($this->_category->id) ? $this->_category->id : '';
2637
-        $delete_action = 'delete_category';
2638
-        // custom redirect
2639
-        $redirect = EE_Admin_Page::add_query_args_and_nonce(
2640
-            array('action' => 'category_list'),
2641
-            $this->_admin_base_url
2642
-        );
2643
-        $this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2644
-        // take care of contents
2645
-        $this->_template_args['admin_page_content'] = $this->_category_details_content();
2646
-        $this->display_admin_page_with_sidebar();
2647
-    }
2648
-
2649
-
2650
-    /**
2651
-     * Output category details content.
2652
-     *
2653
-     * @throws DomainException
2654
-     */
2655
-    protected function _category_details_content()
2656
-    {
2657
-        $editor_args['category_desc'] = array(
2658
-            'type'          => 'wp_editor',
2659
-            'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2660
-            'class'         => 'my_editor_custom',
2661
-            'wpeditor_args' => array('media_buttons' => false),
2662
-        );
2663
-        $_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2664
-        $all_terms = get_terms(
2665
-            array(EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY),
2666
-            array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2667
-        );
2668
-        // setup category select for term parents.
2669
-        $category_select_values[] = array(
2670
-            'text' => esc_html__('No Parent', 'event_espresso'),
2671
-            'id'   => 0,
2672
-        );
2673
-        foreach ($all_terms as $term) {
2674
-            $category_select_values[] = array(
2675
-                'text' => $term->name,
2676
-                'id'   => $term->term_id,
2677
-            );
2678
-        }
2679
-        $category_select = EEH_Form_Fields::select_input(
2680
-            'category_parent',
2681
-            $category_select_values,
2682
-            $this->_category->parent
2683
-        );
2684
-        $template_args = array(
2685
-            'category'                 => $this->_category,
2686
-            'category_select'          => $category_select,
2687
-            'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2688
-            'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2689
-            'disable'                  => '',
2690
-            'disabled_message'         => false,
2691
-        );
2692
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2693
-        return EEH_Template::display_template($template, $template_args, true);
2694
-    }
2695
-
2696
-
2697
-    /**
2698
-     * Handles deleting categories.
2699
-     */
2700
-    protected function _delete_categories()
2701
-    {
2702
-        $cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2703
-            : (array) $this->_req_data['category_id'];
2704
-        foreach ($cat_ids as $cat_id) {
2705
-            $this->_delete_category($cat_id);
2706
-        }
2707
-        // doesn't matter what page we're coming from... we're going to the same place after delete.
2708
-        $query_args = array(
2709
-            'action' => 'category_list',
2710
-        );
2711
-        $this->_redirect_after_action(0, '', '', $query_args);
2712
-    }
2713
-
2714
-
2715
-    /**
2716
-     * Handles deleting specific category.
2717
-     *
2718
-     * @param int $cat_id
2719
-     */
2720
-    protected function _delete_category($cat_id)
2721
-    {
2722
-        $cat_id = absint($cat_id);
2723
-        wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2724
-    }
2725
-
2726
-
2727
-    /**
2728
-     * Handles triggering the update or insertion of a new category.
2729
-     *
2730
-     * @param bool $new_category true means we're triggering the insert of a new category.
2731
-     * @throws EE_Error
2732
-     * @throws InvalidArgumentException
2733
-     * @throws InvalidDataTypeException
2734
-     * @throws InvalidInterfaceException
2735
-     */
2736
-    protected function _insert_or_update_category($new_category)
2737
-    {
2738
-        $cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2739
-        $success = 0; // we already have a success message so lets not send another.
2740
-        if ($cat_id) {
2741
-            $query_args = array(
2742
-                'action'     => 'edit_category',
2743
-                'EVT_CAT_ID' => $cat_id,
2744
-            );
2745
-        } else {
2746
-            $query_args = array('action' => 'add_category');
2747
-        }
2748
-        $this->_redirect_after_action($success, '', '', $query_args, true);
2749
-    }
2750
-
2751
-
2752
-    /**
2753
-     * Inserts or updates category
2754
-     *
2755
-     * @param bool $update (true indicates we're updating a category).
2756
-     * @return bool|mixed|string
2757
-     */
2758
-    private function _insert_category($update = false)
2759
-    {
2760
-        $cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2761
-        $category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2762
-        $category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2763
-        $category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2764
-        if (empty($category_name)) {
2765
-            $msg = esc_html__('You must add a name for the category.', 'event_espresso');
2766
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2767
-            return false;
2768
-        }
2769
-        $term_args = array(
2770
-            'name'        => $category_name,
2771
-            'description' => $category_desc,
2772
-            'parent'      => $category_parent,
2773
-        );
2774
-        // was the category_identifier input disabled?
2775
-        if (isset($this->_req_data['category_identifier'])) {
2776
-            $term_args['slug'] = $this->_req_data['category_identifier'];
2777
-        }
2778
-        $insert_ids = $update
2779
-            ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2780
-            : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2781
-        if (! is_array($insert_ids)) {
2782
-            $msg = esc_html__(
2783
-                'An error occurred and the category has not been saved to the database.',
2784
-                'event_espresso'
2785
-            );
2786
-            EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2787
-        } else {
2788
-            $cat_id = $insert_ids['term_id'];
2789
-            $msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2790
-            EE_Error::add_success($msg);
2791
-        }
2792
-        return $cat_id;
2793
-    }
2794
-
2795
-
2796
-    /**
2797
-     * Gets categories or count of categories matching the arguments in the request.
2798
-     *
2799
-     * @param int  $per_page
2800
-     * @param int  $current_page
2801
-     * @param bool $count
2802
-     * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int
2803
-     * @throws EE_Error
2804
-     * @throws InvalidArgumentException
2805
-     * @throws InvalidDataTypeException
2806
-     * @throws InvalidInterfaceException
2807
-     */
2808
-    public function get_categories($per_page = 10, $current_page = 1, $count = false)
2809
-    {
2810
-        // testing term stuff
2811
-        $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2812
-        $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2813
-        $limit = ($current_page - 1) * $per_page;
2814
-        $where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2815
-        if (isset($this->_req_data['s'])) {
2816
-            $sstr = '%' . $this->_req_data['s'] . '%';
2817
-            $where['OR'] = array(
2818
-                'Term.name'   => array('LIKE', $sstr),
2819
-                'description' => array('LIKE', $sstr),
2820
-            );
2821
-        }
2822
-        $query_params = array(
2823
-            $where,
2824
-            'order_by'   => array($orderby => $order),
2825
-            'limit'      => $limit . ',' . $per_page,
2826
-            'force_join' => array('Term'),
2827
-        );
2828
-        $categories = $count
2829
-            ? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2830
-            : EEM_Term_Taxonomy::instance()->get_all($query_params);
2831
-        return $categories;
2832
-    }
2833
-
2834
-    /* end category stuff */
2835
-    /**************/
2836
-
2837
-
2838
-    /**
2839
-     * Callback for the `ee_save_timezone_setting` ajax action.
2840
-     *
2841
-     * @throws EE_Error
2842
-     * @throws InvalidArgumentException
2843
-     * @throws InvalidDataTypeException
2844
-     * @throws InvalidInterfaceException
2845
-     */
2846
-    public function save_timezonestring_setting()
2847
-    {
2848
-        $timezone_string = isset($this->_req_data['timezone_selected'])
2849
-            ? $this->_req_data['timezone_selected']
2850
-            : '';
2851
-        if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2852
-            EE_Error::add_error(
2853
-                esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2854
-                __FILE__,
2855
-                __FUNCTION__,
2856
-                __LINE__
2857
-            );
2858
-            $this->_template_args['error'] = true;
2859
-            $this->_return_json();
2860
-        }
2861
-
2862
-        update_option('timezone_string', $timezone_string);
2863
-        EE_Error::add_success(
2864
-            esc_html__('Your timezone string was updated.', 'event_espresso')
2865
-        );
2866
-        $this->_template_args['success'] = true;
2867
-        $this->_return_json(true, array('action' => 'create_new'));
2868
-    }
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
+				'capability' => '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 = [
245
+			'default'                => [
246
+				'nav'           => [
247
+					'label' => esc_html__('Overview', 'event_espresso'),
248
+					'order' => 10,
249
+				],
250
+				'list_table'    => 'Events_Admin_List_Table',
251
+				'help_tabs'     => [
252
+					'events_overview_help_tab'                       => [
253
+						'title'    => esc_html__('Events Overview', 'event_espresso'),
254
+						'filename' => 'events_overview',
255
+					],
256
+					'events_overview_table_column_headings_help_tab' => [
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'               => [
261
+						'title'    => esc_html__('Events Overview Filters', 'event_espresso'),
262
+						'filename' => 'events_overview_filters',
263
+					],
264
+					'events_overview_view_help_tab'                  => [
265
+						'title'    => esc_html__('Events Overview Views', 'event_espresso'),
266
+						'filename' => 'events_overview_views',
267
+					],
268
+					'events_overview_other_help_tab'                 => [
269
+						'title'    => esc_html__('Events Overview Other', 'event_espresso'),
270
+						'filename' => 'events_overview_other',
271
+					],
272
+				],
273
+				'help_tour'     => [
274
+					'Event_Overview_Help_Tour',
275
+					// 'New_Features_Test_Help_Tour' for testing multiple help tour
276
+				],
277
+				'require_nonce' => false,
278
+				'qtips' => ['EE_Event_List_Table_Tips'],
279
+			],
280
+			'create_new'             => [
281
+				'nav'           => [
282
+					'label'      => esc_html__('Add Event', 'event_espresso'),
283
+					'order'      => 5,
284
+					'persistent' => false,
285
+				],
286
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
287
+				'help_tabs'     => [
288
+					'event_editor_help_tab'                            => [
289
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
290
+						'filename' => 'event_editor',
291
+					],
292
+					'event_editor_title_richtexteditor_help_tab'       => [
293
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
294
+						'filename' => 'event_editor_title_richtexteditor',
295
+					],
296
+					'event_editor_venue_details_help_tab'              => [
297
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
298
+						'filename' => 'event_editor_venue_details',
299
+					],
300
+					'event_editor_event_datetimes_help_tab'            => [
301
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
302
+						'filename' => 'event_editor_event_datetimes',
303
+					],
304
+					'event_editor_event_tickets_help_tab'              => [
305
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
306
+						'filename' => 'event_editor_event_tickets',
307
+					],
308
+					'event_editor_event_registration_options_help_tab' => [
309
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
310
+						'filename' => 'event_editor_event_registration_options',
311
+					],
312
+					'event_editor_tags_categories_help_tab'            => [
313
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
314
+						'filename' => 'event_editor_tags_categories',
315
+					],
316
+					'event_editor_questions_registrants_help_tab'      => [
317
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
318
+						'filename' => 'event_editor_questions_registrants',
319
+					],
320
+					'event_editor_save_new_event_help_tab'             => [
321
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
322
+						'filename' => 'event_editor_save_new_event',
323
+					],
324
+					'event_editor_other_help_tab'                      => [
325
+						'title'    => esc_html__('Event Other', 'event_espresso'),
326
+						'filename' => 'event_editor_other',
327
+					],
328
+				],
329
+				'help_tour'     => [
330
+					'Event_Editor_Help_Tour',
331
+				],
332
+				'require_nonce' => false,
333
+			],
334
+			'edit'                   => [
335
+				'nav'           => [
336
+					'label'      => esc_html__('Edit Event', 'event_espresso'),
337
+					'order'      => 5,
338
+					'persistent' => false,
339
+					'url'        => isset($this->_req_data['post'])
340
+						? EE_Admin_Page::add_query_args_and_nonce(
341
+							['post' => $this->_req_data['post'], 'action' => 'edit'],
342
+							$this->_current_page_view_url
343
+						)
344
+						: $this->_admin_base_url,
345
+				],
346
+				'metaboxes'     => ['_register_event_editor_meta_boxes'],
347
+				'help_tabs'     => [
348
+					'event_editor_help_tab'                            => [
349
+						'title'    => esc_html__('Event Editor', 'event_espresso'),
350
+						'filename' => 'event_editor',
351
+					],
352
+					'event_editor_title_richtexteditor_help_tab'       => [
353
+						'title'    => esc_html__('Event Title & Rich Text Editor', 'event_espresso'),
354
+						'filename' => 'event_editor_title_richtexteditor',
355
+					],
356
+					'event_editor_venue_details_help_tab'              => [
357
+						'title'    => esc_html__('Event Venue Details', 'event_espresso'),
358
+						'filename' => 'event_editor_venue_details',
359
+					],
360
+					'event_editor_event_datetimes_help_tab'            => [
361
+						'title'    => esc_html__('Event Datetimes', 'event_espresso'),
362
+						'filename' => 'event_editor_event_datetimes',
363
+					],
364
+					'event_editor_event_tickets_help_tab'              => [
365
+						'title'    => esc_html__('Event Tickets', 'event_espresso'),
366
+						'filename' => 'event_editor_event_tickets',
367
+					],
368
+					'event_editor_event_registration_options_help_tab' => [
369
+						'title'    => esc_html__('Event Registration Options', 'event_espresso'),
370
+						'filename' => 'event_editor_event_registration_options',
371
+					],
372
+					'event_editor_tags_categories_help_tab'            => [
373
+						'title'    => esc_html__('Event Tags & Categories', 'event_espresso'),
374
+						'filename' => 'event_editor_tags_categories',
375
+					],
376
+					'event_editor_questions_registrants_help_tab'      => [
377
+						'title'    => esc_html__('Questions for Registrants', 'event_espresso'),
378
+						'filename' => 'event_editor_questions_registrants',
379
+					],
380
+					'event_editor_save_new_event_help_tab'             => [
381
+						'title'    => esc_html__('Save New Event', 'event_espresso'),
382
+						'filename' => 'event_editor_save_new_event',
383
+					],
384
+					'event_editor_other_help_tab'                      => [
385
+						'title'    => esc_html__('Event Other', 'event_espresso'),
386
+						'filename' => 'event_editor_other',
387
+					],
388
+				],
389
+				'require_nonce' => false,
390
+			],
391
+			'default_event_settings' => [
392
+				'nav'           => [
393
+					'label' => esc_html__('Default Settings', 'event_espresso'),
394
+					'order' => 40,
395
+				],
396
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, ['_publish_post_box']),
397
+				'labels'        => [
398
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
399
+				],
400
+				'help_tabs'     => [
401
+					'default_settings_help_tab'        => [
402
+						'title'    => esc_html__('Default Event Settings', 'event_espresso'),
403
+						'filename' => 'events_default_settings',
404
+					],
405
+					'default_settings_status_help_tab' => [
406
+						'title'    => esc_html__('Default Registration Status', 'event_espresso'),
407
+						'filename' => 'events_default_settings_status',
408
+					],
409
+					'default_maximum_tickets_help_tab' => [
410
+						'title'    => esc_html__('Default Maximum Tickets Per Order', 'event_espresso'),
411
+						'filename' => 'events_default_settings_max_tickets',
412
+					],
413
+				],
414
+				'help_tour'     => ['Event_Default_Settings_Help_Tour'],
415
+				'require_nonce' => false,
416
+			],
417
+			// template settings
418
+			'template_settings'      => [
419
+				'nav'           => [
420
+					'label' => esc_html__('Templates', 'event_espresso'),
421
+					'order' => 30,
422
+				],
423
+				'metaboxes'     => $this->_default_espresso_metaboxes,
424
+				'help_tabs'     => [
425
+					'general_settings_templates_help_tab' => [
426
+						'title'    => esc_html__('Templates', 'event_espresso'),
427
+						'filename' => 'general_settings_templates',
428
+					],
429
+				],
430
+				'help_tour'     => ['Templates_Help_Tour'],
431
+				'require_nonce' => false,
432
+			],
433
+			// event category stuff
434
+			'add_category'           => [
435
+				'nav'           => [
436
+					'label'      => esc_html__('Add Category', 'event_espresso'),
437
+					'order'      => 15,
438
+					'persistent' => false,
439
+				],
440
+				'help_tabs'     => [
441
+					'add_category_help_tab' => [
442
+						'title'    => esc_html__('Add New Event Category', 'event_espresso'),
443
+						'filename' => 'events_add_category',
444
+					],
445
+				],
446
+				'help_tour'     => ['Event_Add_Category_Help_Tour'],
447
+				'metaboxes'     => ['_publish_post_box'],
448
+				'require_nonce' => false,
449
+			],
450
+			'edit_category'          => [
451
+				'nav'           => [
452
+					'label'      => esc_html__('Edit Category', 'event_espresso'),
453
+					'order'      => 15,
454
+					'persistent' => false,
455
+					'url'        => isset($this->_req_data['EVT_CAT_ID'])
456
+						? add_query_arg(
457
+							['EVT_CAT_ID' => $this->_req_data['EVT_CAT_ID']],
458
+							$this->_current_page_view_url
459
+						)
460
+						: $this->_admin_base_url,
461
+				],
462
+				'help_tabs'     => [
463
+					'edit_category_help_tab' => [
464
+						'title'    => esc_html__('Edit Event Category', 'event_espresso'),
465
+						'filename' => 'events_edit_category',
466
+					],
467
+				],
468
+				/*'help_tour' => array('Event_Edit_Category_Help_Tour'),*/
469
+				'metaboxes'     => ['_publish_post_box'],
470
+				'require_nonce' => false,
471
+			],
472
+			'category_list'          => [
473
+				'nav'           => [
474
+					'label' => esc_html__('Categories', 'event_espresso'),
475
+					'order' => 20,
476
+				],
477
+				'list_table'    => 'Event_Categories_Admin_List_Table',
478
+				'help_tabs'     => [
479
+					'events_categories_help_tab'                       => [
480
+						'title'    => esc_html__('Event Categories', 'event_espresso'),
481
+						'filename' => 'events_categories',
482
+					],
483
+					'events_categories_table_column_headings_help_tab' => [
484
+						'title'    => esc_html__('Event Categories Table Column Headings', 'event_espresso'),
485
+						'filename' => 'events_categories_table_column_headings',
486
+					],
487
+					'events_categories_view_help_tab'                  => [
488
+						'title'    => esc_html__('Event Categories Views', 'event_espresso'),
489
+						'filename' => 'events_categories_views',
490
+					],
491
+					'events_categories_other_help_tab'                 => [
492
+						'title'    => esc_html__('Event Categories Other', 'event_espresso'),
493
+						'filename' => 'events_categories_other',
494
+					],
495
+				],
496
+				'help_tour'     => [
497
+					'Event_Categories_Help_Tour',
498
+				],
499
+				'metaboxes'     => $this->_default_espresso_metaboxes,
500
+				'require_nonce' => false,
501
+			],
502
+		];
503
+		// only load EE_Event_Editor_Decaf_Tips if domain is not caffeinated
504
+		$domain = $this->loader->getShared('EventEspresso\core\domain\Domain');
505
+		if (! $domain->isCaffeinated()) {
506
+			$this->_page_config['create_new']['qtips'] = ['EE_Event_Editor_Decaf_Tips'];
507
+			$this->_page_config['edit']['qtips'] = ['EE_Event_Editor_Decaf_Tips' ];
508
+		}
509
+	}
510
+
511
+
512
+	/**
513
+	 * Used to register any global screen options if necessary for every route in this admin page group.
514
+	 */
515
+	protected function _add_screen_options()
516
+	{
517
+	}
518
+
519
+
520
+	/**
521
+	 * Implementing the screen options for the 'default' route.
522
+	 *
523
+	 * @throws InvalidArgumentException
524
+	 * @throws InvalidDataTypeException
525
+	 * @throws InvalidInterfaceException
526
+	 */
527
+	protected function _add_screen_options_default()
528
+	{
529
+		$this->_per_page_screen_option();
530
+	}
531
+
532
+
533
+	/**
534
+	 * Implementing screen options for the category list route.
535
+	 *
536
+	 * @throws InvalidArgumentException
537
+	 * @throws InvalidDataTypeException
538
+	 * @throws InvalidInterfaceException
539
+	 */
540
+	protected function _add_screen_options_category_list()
541
+	{
542
+		$page_title = $this->_admin_page_title;
543
+		$this->_admin_page_title = esc_html__('Categories', 'event_espresso');
544
+		$this->_per_page_screen_option();
545
+		$this->_admin_page_title = $page_title;
546
+	}
547
+
548
+
549
+	/**
550
+	 * Used to register any global feature pointers for the admin page group.
551
+	 */
552
+	protected function _add_feature_pointers()
553
+	{
554
+	}
555
+
556
+
557
+	/**
558
+	 * Registers and enqueues any global scripts and styles for the entire admin page group.
559
+	 */
560
+	public function load_scripts_styles()
561
+	{
562
+		wp_register_style(
563
+			'events-admin-css',
564
+			EVENTS_ASSETS_URL . 'events-admin-page.css',
565
+			array(),
566
+			EVENT_ESPRESSO_VERSION
567
+		);
568
+		wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
569
+		wp_enqueue_style('events-admin-css');
570
+		wp_enqueue_style('ee-cat-admin');
571
+		// todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
572
+		// registers for all views
573
+		// scripts
574
+		wp_register_script(
575
+			'event_editor_js',
576
+			EVENTS_ASSETS_URL . 'event_editor.js',
577
+			array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
578
+			EVENT_ESPRESSO_VERSION,
579
+			true
580
+		);
581
+	}
582
+
583
+
584
+	/**
585
+	 * Enqueuing scripts and styles specific to this view
586
+	 */
587
+	public function load_scripts_styles_create_new()
588
+	{
589
+		$this->load_scripts_styles_edit();
590
+	}
591
+
592
+
593
+	/**
594
+	 * Enqueuing scripts and styles specific to this view
595
+	 */
596
+	public function load_scripts_styles_edit()
597
+	{
598
+		// styles
599
+		wp_enqueue_style('espresso-ui-theme');
600
+		wp_register_style(
601
+			'event-editor-css',
602
+			EVENTS_ASSETS_URL . 'event-editor.css',
603
+			array('ee-admin-css'),
604
+			EVENT_ESPRESSO_VERSION
605
+		);
606
+		wp_enqueue_style('event-editor-css');
607
+		// scripts
608
+		wp_register_script(
609
+			'event-datetime-metabox',
610
+			EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
611
+			array('event_editor_js', 'ee-datepicker'),
612
+			EVENT_ESPRESSO_VERSION
613
+		);
614
+		wp_enqueue_script('event-datetime-metabox');
615
+	}
616
+
617
+
618
+	/**
619
+	 * Populating the _views property for the category list table view.
620
+	 */
621
+	protected function _set_list_table_views_category_list()
622
+	{
623
+		$this->_views = array(
624
+			'all' => array(
625
+				'slug'        => 'all',
626
+				'label'       => esc_html__('All', 'event_espresso'),
627
+				'count'       => 0,
628
+				'bulk_action' => array(
629
+					'delete_categories' => esc_html__('Delete Permanently', 'event_espresso'),
630
+				),
631
+			),
632
+		);
633
+	}
634
+
635
+
636
+	/**
637
+	 * For adding anything that fires on the admin_init hook for any route within this admin page group.
638
+	 */
639
+	public function admin_init()
640
+	{
641
+		EE_Registry::$i18n_js_strings['image_confirm'] = esc_html__(
642
+			'Do you really want to delete this image? Please remember to update your event to complete the removal.',
643
+			'event_espresso'
644
+		);
645
+	}
646
+
647
+
648
+	/**
649
+	 * For adding anything that should be triggered on the admin_notices hook for any route within this admin page
650
+	 * group.
651
+	 */
652
+	public function admin_notices()
653
+	{
654
+	}
655
+
656
+
657
+	/**
658
+	 * For adding anything that should be triggered on the `admin_print_footer_scripts` hook for any route within
659
+	 * this admin page group.
660
+	 */
661
+	public function admin_footer_scripts()
662
+	{
663
+	}
664
+
665
+
666
+	/**
667
+	 * Call this function to verify if an event is public and has tickets for sale.  If it does, then we need to show a
668
+	 * warning (via EE_Error::add_error());
669
+	 *
670
+	 * @param  EE_Event $event Event object
671
+	 * @param string    $req_type
672
+	 * @return void
673
+	 * @throws EE_Error
674
+	 * @access public
675
+	 */
676
+	public function verify_event_edit($event = null, $req_type = '')
677
+	{
678
+		// don't need to do this when processing
679
+		if (! empty($req_type)) {
680
+			return;
681
+		}
682
+		// no event?
683
+		if (! $event instanceof EE_Event) {
684
+			$event = $this->_cpt_model_obj;
685
+		}
686
+		// STILL no event?
687
+		if (! $event instanceof EE_Event) {
688
+			return;
689
+		}
690
+		$orig_status = $event->status();
691
+		// first check if event is active.
692
+		if ($orig_status === EEM_Event::cancelled
693
+			|| $orig_status === EEM_Event::postponed
694
+			|| $event->is_expired()
695
+			|| $event->is_inactive()
696
+		) {
697
+			return;
698
+		}
699
+		// made it here so it IS active... next check that any of the tickets are sold.
700
+		if ($event->is_sold_out(true)) {
701
+			if ($orig_status !== EEM_Event::sold_out && $event->status() !== $orig_status) {
702
+				EE_Error::add_attention(
703
+					sprintf(
704
+						esc_html__(
705
+							'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.',
706
+							'event_espresso'
707
+						),
708
+						EEH_Template::pretty_status(EEM_Event::sold_out, false, 'sentence')
709
+					)
710
+				);
711
+			}
712
+			return;
713
+		}
714
+		if ($orig_status === EEM_Event::sold_out) {
715
+			EE_Error::add_attention(
716
+				sprintf(
717
+					esc_html__(
718
+						'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.',
719
+						'event_espresso'
720
+					),
721
+					EEH_Template::pretty_status($event->status(), false, 'sentence')
722
+				)
723
+			);
724
+		}
725
+		// now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
726
+		if (! $event->tickets_on_sale()) {
727
+			return;
728
+		}
729
+		// made it here so show warning
730
+		$this->_edit_event_warning();
731
+	}
732
+
733
+
734
+	/**
735
+	 * This is the text used for when an event is being edited that is public and has tickets for sale.
736
+	 * When needed, hook this into a EE_Error::add_error() notice.
737
+	 *
738
+	 * @access protected
739
+	 * @return void
740
+	 */
741
+	protected function _edit_event_warning()
742
+	{
743
+		// we don't want to add warnings during these requests
744
+		if (isset($this->_req_data['action']) && $this->_req_data['action'] === 'editpost') {
745
+			return;
746
+		}
747
+		EE_Error::add_attention(
748
+			sprintf(
749
+				esc_html__(
750
+					'Your event is open for registration. Making changes may disrupt any transactions in progress. %sLearn more%s',
751
+					'event_espresso'
752
+				),
753
+				'<a class="espresso-help-tab-lnk">',
754
+				'</a>'
755
+			)
756
+		);
757
+	}
758
+
759
+
760
+	/**
761
+	 * When a user is creating a new event, notify them if they haven't set their timezone.
762
+	 * Otherwise, do the normal logic
763
+	 *
764
+	 * @return string
765
+	 * @throws EE_Error
766
+	 * @throws InvalidArgumentException
767
+	 * @throws InvalidDataTypeException
768
+	 * @throws InvalidInterfaceException
769
+	 */
770
+	protected function _create_new_cpt_item()
771
+	{
772
+		$has_timezone_string = get_option('timezone_string');
773
+		// only nag them about setting their timezone if it's their first event, and they haven't already done it
774
+		if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) {
775
+			EE_Error::add_attention(
776
+				sprintf(
777
+					__(
778
+						'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',
779
+						'event_espresso'
780
+					),
781
+					'<br>',
782
+					'<select id="timezone_string" name="timezone_string" aria-describedby="timezone-description">'
783
+					. EEH_DTT_Helper::wp_timezone_choice('', EEH_DTT_Helper::get_user_locale())
784
+					. '</select>',
785
+					'<button class="button button-secondary timezone-submit">',
786
+					'</button><span class="spinner"></span>'
787
+				),
788
+				__FILE__,
789
+				__FUNCTION__,
790
+				__LINE__
791
+			);
792
+		}
793
+		parent::_create_new_cpt_item();
794
+	}
795
+
796
+
797
+	/**
798
+	 * Sets the _views property for the default route in this admin page group.
799
+	 */
800
+	protected function _set_list_table_views_default()
801
+	{
802
+		$this->_views = array(
803
+			'all'   => array(
804
+				'slug'        => 'all',
805
+				'label'       => esc_html__('View All Events', 'event_espresso'),
806
+				'count'       => 0,
807
+				'bulk_action' => array(
808
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
809
+				),
810
+			),
811
+			'draft' => array(
812
+				'slug'        => 'draft',
813
+				'label'       => esc_html__('Draft', 'event_espresso'),
814
+				'count'       => 0,
815
+				'bulk_action' => array(
816
+					'trash_events' => esc_html__('Move to Trash', 'event_espresso'),
817
+				),
818
+			),
819
+		);
820
+		if (EE_Registry::instance()->CAP->current_user_can('ee_delete_events', 'espresso_events_trash_events')) {
821
+			$this->_views['trash'] = array(
822
+				'slug'        => 'trash',
823
+				'label'       => esc_html__('Trash', 'event_espresso'),
824
+				'count'       => 0,
825
+				'bulk_action' => array(
826
+					'restore_events' => esc_html__('Restore From Trash', 'event_espresso'),
827
+					'delete_events'  => esc_html__('Delete Permanently', 'event_espresso'),
828
+				),
829
+			);
830
+		}
831
+	}
832
+
833
+
834
+	/**
835
+	 * Provides the legend item array for the default list table view.
836
+	 *
837
+	 * @return array
838
+	 */
839
+	protected function _event_legend_items()
840
+	{
841
+		$items = array(
842
+			'view_details'   => array(
843
+				'class' => 'dashicons dashicons-search',
844
+				'desc'  => esc_html__('View Event', 'event_espresso'),
845
+			),
846
+			'edit_event'     => array(
847
+				'class' => 'ee-icon ee-icon-calendar-edit',
848
+				'desc'  => esc_html__('Edit Event Details', 'event_espresso'),
849
+			),
850
+			'view_attendees' => array(
851
+				'class' => 'dashicons dashicons-groups',
852
+				'desc'  => esc_html__('View Registrations for Event', 'event_espresso'),
853
+			),
854
+		);
855
+		$items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
856
+		$statuses = array(
857
+			'sold_out_status'  => array(
858
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
859
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
860
+			),
861
+			'active_status'    => array(
862
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
863
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
864
+			),
865
+			'upcoming_status'  => array(
866
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
867
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
868
+			),
869
+			'postponed_status' => array(
870
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
871
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
872
+			),
873
+			'cancelled_status' => array(
874
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
875
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
876
+			),
877
+			'expired_status'   => array(
878
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
879
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
880
+			),
881
+			'inactive_status'  => array(
882
+				'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
883
+				'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
884
+			),
885
+		);
886
+		$statuses = apply_filters('FHEE__Events_Admin_Page__event_legend_items__statuses', $statuses);
887
+		return array_merge($items, $statuses);
888
+	}
889
+
890
+
891
+	/**
892
+	 * @return EEM_Event
893
+	 * @throws EE_Error
894
+	 * @throws InvalidArgumentException
895
+	 * @throws InvalidDataTypeException
896
+	 * @throws InvalidInterfaceException
897
+	 * @throws ReflectionException
898
+	 */
899
+	private function _event_model()
900
+	{
901
+		if (! $this->_event_model instanceof EEM_Event) {
902
+			$this->_event_model = EE_Registry::instance()->load_model('Event');
903
+		}
904
+		return $this->_event_model;
905
+	}
906
+
907
+
908
+	/**
909
+	 * Adds extra buttons to the WP CPT permalink field row.
910
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
911
+	 *
912
+	 * @param  string $return    the current html
913
+	 * @param  int    $id        the post id for the page
914
+	 * @param  string $new_title What the title is
915
+	 * @param  string $new_slug  what the slug is
916
+	 * @return string            The new html string for the permalink area
917
+	 */
918
+	public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
919
+	{
920
+		// make sure this is only when editing
921
+		if (! empty($id)) {
922
+			$post = get_post($id);
923
+			$return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
924
+					   . esc_html__('Shortcode', 'event_espresso')
925
+					   . '</a> ';
926
+			$return .= '<input id="shortcode" type="hidden" value="[ESPRESSO_TICKET_SELECTOR event_id='
927
+					   . $post->ID
928
+					   . ']">';
929
+		}
930
+		return $return;
931
+	}
932
+
933
+
934
+	/**
935
+	 * _events_overview_list_table
936
+	 * This contains the logic for showing the events_overview list
937
+	 *
938
+	 * @access protected
939
+	 * @return void
940
+	 * @throws DomainException
941
+	 * @throws EE_Error
942
+	 * @throws InvalidArgumentException
943
+	 * @throws InvalidDataTypeException
944
+	 * @throws InvalidInterfaceException
945
+	 */
946
+	protected function _events_overview_list_table()
947
+	{
948
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
949
+		$this->_template_args['after_list_table'] = ! empty($this->_template_args['after_list_table'])
950
+			? (array) $this->_template_args['after_list_table']
951
+			: array();
952
+		$this->_template_args['after_list_table']['view_event_list_button'] = EEH_HTML::br()
953
+				. EEH_Template::get_button_or_link(
954
+					get_post_type_archive_link('espresso_events'),
955
+					esc_html__('View Event Archive Page', 'event_espresso'),
956
+					'button'
957
+				);
958
+		$this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
959
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
960
+			'create_new',
961
+			'add',
962
+			array(),
963
+			'add-new-h2'
964
+		);
965
+		$this->display_admin_list_table_page_with_no_sidebar();
966
+	}
967
+
968
+
969
+	/**
970
+	 * this allows for extra misc actions in the default WP publish box
971
+	 *
972
+	 * @return void
973
+	 * @throws DomainException
974
+	 * @throws EE_Error
975
+	 * @throws InvalidArgumentException
976
+	 * @throws InvalidDataTypeException
977
+	 * @throws InvalidInterfaceException
978
+	 * @throws ReflectionException
979
+	 */
980
+	public function extra_misc_actions_publish_box()
981
+	{
982
+		$this->_generate_publish_box_extra_content();
983
+	}
984
+
985
+
986
+	/**
987
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
988
+	 * saved.
989
+	 * Typically you would use this to save any additional data.
990
+	 * Keep in mind also that "save_post" runs on EVERY post update to the database.
991
+	 * ALSO very important.  When a post transitions from scheduled to published,
992
+	 * the save_post action is fired but you will NOT have any _POST data containing any extra info you may have from
993
+	 * other meta saves. So MAKE sure that you handle this accordingly.
994
+	 *
995
+	 * @access protected
996
+	 * @abstract
997
+	 * @param string $post_id The ID of the cpt that was saved (so you can link relationally)
998
+	 * @param object $post    The post object of the cpt that was saved.
999
+	 * @return void
1000
+	 * @throws EE_Error
1001
+	 * @throws InvalidArgumentException
1002
+	 * @throws InvalidDataTypeException
1003
+	 * @throws InvalidInterfaceException
1004
+	 * @throws ReflectionException
1005
+	 */
1006
+	protected function _insert_update_cpt_item($post_id, $post)
1007
+	{
1008
+		if ($post instanceof WP_Post && $post->post_type !== 'espresso_events') {
1009
+			// get out we're not processing an event save.
1010
+			return;
1011
+		}
1012
+		$event_values = array(
1013
+			'EVT_display_desc'                => ! empty($this->_req_data['display_desc']) ? 1 : 0,
1014
+			'EVT_display_ticket_selector'     => ! empty($this->_req_data['display_ticket_selector']) ? 1 : 0,
1015
+			'EVT_additional_limit'            => min(
1016
+				apply_filters('FHEE__EE_Events_Admin__insert_update_cpt_item__EVT_additional_limit_max', 255),
1017
+				! empty($this->_req_data['additional_limit']) ? $this->_req_data['additional_limit'] : null
1018
+			),
1019
+			'EVT_default_registration_status' => ! empty($this->_req_data['EVT_default_registration_status'])
1020
+				? $this->_req_data['EVT_default_registration_status']
1021
+				: EE_Registry::instance()->CFG->registration->default_STS_ID,
1022
+			'EVT_member_only'                 => ! empty($this->_req_data['member_only']) ? 1 : 0,
1023
+			'EVT_allow_overflow'              => ! empty($this->_req_data['EVT_allow_overflow']) ? 1 : 0,
1024
+			'EVT_timezone_string'             => ! empty($this->_req_data['timezone_string'])
1025
+				? $this->_req_data['timezone_string'] : null,
1026
+			'EVT_external_URL'                => ! empty($this->_req_data['externalURL'])
1027
+				? $this->_req_data['externalURL'] : null,
1028
+			'EVT_phone'                       => ! empty($this->_req_data['event_phone'])
1029
+				? $this->_req_data['event_phone'] : null,
1030
+		);
1031
+		// update event
1032
+		$success = $this->_event_model()->update_by_ID($event_values, $post_id);
1033
+		// 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!
1034
+		$get_one_where = array(
1035
+			$this->_event_model()->primary_key_name() => $post_id,
1036
+			'OR'                                      => array(
1037
+				'status'   => $post->post_status,
1038
+				// if trying to "Publish" a sold out event, it's status will get switched back to "sold_out" in the db,
1039
+				// but the returned object here has a status of "publish", so use the original post status as well
1040
+				'status*1' => $this->_req_data['original_post_status'],
1041
+			),
1042
+		);
1043
+		$event = $this->_event_model()->get_one(array($get_one_where));
1044
+		// the following are default callbacks for event attachment updates that can be overridden by caffeinated functionality and/or addons.
1045
+		$event_update_callbacks = apply_filters(
1046
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
1047
+			array(
1048
+				array($this, '_default_venue_update'),
1049
+				array($this, '_default_tickets_update'),
1050
+			)
1051
+		);
1052
+		$att_success = true;
1053
+		foreach ($event_update_callbacks as $e_callback) {
1054
+			$_success = is_callable($e_callback)
1055
+				? $e_callback($event, $this->_req_data)
1056
+				: false;
1057
+			// if ANY of these updates fail then we want the appropriate global error message
1058
+			$att_success = ! $att_success ? $att_success : $_success;
1059
+		}
1060
+		// any errors?
1061
+		if ($success && false === $att_success) {
1062
+			EE_Error::add_error(
1063
+				esc_html__(
1064
+					'Event Details saved successfully but something went wrong with saving attachments.',
1065
+					'event_espresso'
1066
+				),
1067
+				__FILE__,
1068
+				__FUNCTION__,
1069
+				__LINE__
1070
+			);
1071
+		} elseif ($success === false) {
1072
+			EE_Error::add_error(
1073
+				esc_html__('Event Details did not save successfully.', 'event_espresso'),
1074
+				__FILE__,
1075
+				__FUNCTION__,
1076
+				__LINE__
1077
+			);
1078
+		}
1079
+	}
1080
+
1081
+
1082
+	/**
1083
+	 * @param int $post_id
1084
+	 * @param int $revision_id
1085
+	 * @throws EE_Error
1086
+	 * @throws InvalidArgumentException
1087
+	 * @throws InvalidDataTypeException
1088
+	 * @throws InvalidInterfaceException
1089
+	 * @throws ReflectionException
1090
+	 * @see parent::restore_item()
1091
+	 */
1092
+	protected function _restore_cpt_item($post_id, $revision_id)
1093
+	{
1094
+		// copy existing event meta to new post
1095
+		$post_evt = $this->_event_model()->get_one_by_ID($post_id);
1096
+		if ($post_evt instanceof EE_Event) {
1097
+			// meta revision restore
1098
+			$post_evt->restore_revision($revision_id);
1099
+			// related objs restore
1100
+			$post_evt->restore_revision($revision_id, array('Venue', 'Datetime', 'Price'));
1101
+		}
1102
+	}
1103
+
1104
+
1105
+	/**
1106
+	 * Attach the venue to the Event
1107
+	 *
1108
+	 * @param EE_Event $evtobj Event Object to add the venue to
1109
+	 * @param array    $data   The request data from the form
1110
+	 * @return bool           Success or fail.
1111
+	 * @throws EE_Error
1112
+	 * @throws InvalidArgumentException
1113
+	 * @throws InvalidDataTypeException
1114
+	 * @throws InvalidInterfaceException
1115
+	 * @throws ReflectionException
1116
+	 */
1117
+	protected function _default_venue_update(EE_Event $evtobj, $data)
1118
+	{
1119
+		require_once(EE_MODELS . 'EEM_Venue.model.php');
1120
+		$venue_model = EE_Registry::instance()->load_model('Venue');
1121
+		$rows_affected = null;
1122
+		$venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
1123
+		// very important.  If we don't have a venue name...
1124
+		// then we'll get out because not necessary to create empty venue
1125
+		if (empty($data['venue_title'])) {
1126
+			return false;
1127
+		}
1128
+		$venue_array = array(
1129
+			'VNU_wp_user'         => $evtobj->get('EVT_wp_user'),
1130
+			'VNU_name'            => ! empty($data['venue_title']) ? $data['venue_title'] : null,
1131
+			'VNU_desc'            => ! empty($data['venue_description']) ? $data['venue_description'] : null,
1132
+			'VNU_identifier'      => ! empty($data['venue_identifier']) ? $data['venue_identifier'] : null,
1133
+			'VNU_short_desc'      => ! empty($data['venue_short_description']) ? $data['venue_short_description']
1134
+				: null,
1135
+			'VNU_address'         => ! empty($data['address']) ? $data['address'] : null,
1136
+			'VNU_address2'        => ! empty($data['address2']) ? $data['address2'] : null,
1137
+			'VNU_city'            => ! empty($data['city']) ? $data['city'] : null,
1138
+			'STA_ID'              => ! empty($data['state']) ? $data['state'] : null,
1139
+			'CNT_ISO'             => ! empty($data['countries']) ? $data['countries'] : null,
1140
+			'VNU_zip'             => ! empty($data['zip']) ? $data['zip'] : null,
1141
+			'VNU_phone'           => ! empty($data['venue_phone']) ? $data['venue_phone'] : null,
1142
+			'VNU_capacity'        => ! empty($data['venue_capacity']) ? $data['venue_capacity'] : null,
1143
+			'VNU_url'             => ! empty($data['venue_url']) ? $data['venue_url'] : null,
1144
+			'VNU_virtual_phone'   => ! empty($data['virtual_phone']) ? $data['virtual_phone'] : null,
1145
+			'VNU_virtual_url'     => ! empty($data['virtual_url']) ? $data['virtual_url'] : null,
1146
+			'VNU_enable_for_gmap' => isset($data['enable_for_gmap']) ? 1 : 0,
1147
+			'status'              => 'publish',
1148
+		);
1149
+		// if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1150
+		if (! empty($venue_id)) {
1151
+			$update_where = array($venue_model->primary_key_name() => $venue_id);
1152
+			$rows_affected = $venue_model->update($venue_array, array($update_where));
1153
+			// 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.
1154
+			$evtobj->_add_relation_to($venue_id, 'Venue');
1155
+			return $rows_affected > 0;
1156
+		}
1157
+		// we insert the venue
1158
+		$venue_id = $venue_model->insert($venue_array);
1159
+		$evtobj->_add_relation_to($venue_id, 'Venue');
1160
+		return ! empty($venue_id) ? true : false;
1161
+		// when we have the ancestor come in it's already been handled by the revision save.
1162
+	}
1163
+
1164
+
1165
+	/**
1166
+	 * Handles saving everything related to Tickets (datetimes, tickets, prices)
1167
+	 *
1168
+	 * @param EE_Event $evtobj The Event object we're attaching data to
1169
+	 * @param array    $data   The request data from the form
1170
+	 * @return array
1171
+	 * @throws EE_Error
1172
+	 * @throws InvalidArgumentException
1173
+	 * @throws InvalidDataTypeException
1174
+	 * @throws InvalidInterfaceException
1175
+	 * @throws ReflectionException
1176
+	 * @throws Exception
1177
+	 */
1178
+	protected function _default_tickets_update(EE_Event $evtobj, $data)
1179
+	{
1180
+		if (EE_Registry::instance()->CFG->admin->useAdvancedEditor()) {
1181
+			return [];
1182
+		}
1183
+		$success = true;
1184
+		$saved_dtt = null;
1185
+		$saved_tickets = array();
1186
+		$incoming_date_formats = array('Y-m-d', 'h:i a');
1187
+		foreach ($data['edit_event_datetimes'] as $row => $dtt) {
1188
+			// trim all values to ensure any excess whitespace is removed.
1189
+			$dtt = array_map('trim', $dtt);
1190
+			$dtt['DTT_EVT_end'] = isset($dtt['DTT_EVT_end']) && ! empty($dtt['DTT_EVT_end']) ? $dtt['DTT_EVT_end']
1191
+				: $dtt['DTT_EVT_start'];
1192
+			$datetime_values = array(
1193
+				'DTT_ID'        => ! empty($dtt['DTT_ID']) ? $dtt['DTT_ID'] : null,
1194
+				'DTT_EVT_start' => $dtt['DTT_EVT_start'],
1195
+				'DTT_EVT_end'   => $dtt['DTT_EVT_end'],
1196
+				'DTT_reg_limit' => empty($dtt['DTT_reg_limit']) ? EE_INF : $dtt['DTT_reg_limit'],
1197
+				'DTT_order'     => $row,
1198
+			);
1199
+			// 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.
1200
+			if (! empty($dtt['DTT_ID'])) {
1201
+				$DTM = EE_Registry::instance()
1202
+								  ->load_model('Datetime', array($evtobj->get_timezone()))
1203
+								  ->get_one_by_ID($dtt['DTT_ID']);
1204
+				$DTM->set_date_format($incoming_date_formats[0]);
1205
+				$DTM->set_time_format($incoming_date_formats[1]);
1206
+				foreach ($datetime_values as $field => $value) {
1207
+					$DTM->set($field, $value);
1208
+				}
1209
+				// 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.
1210
+				$saved_dtts[ $DTM->ID() ] = $DTM;
1211
+			} else {
1212
+				$DTM = EE_Registry::instance()->load_class(
1213
+					'Datetime',
1214
+					array($datetime_values, $evtobj->get_timezone(), $incoming_date_formats),
1215
+					false,
1216
+					false
1217
+				);
1218
+				foreach ($datetime_values as $field => $value) {
1219
+					$DTM->set($field, $value);
1220
+				}
1221
+			}
1222
+			$DTM->save();
1223
+			$DTT = $evtobj->_add_relation_to($DTM, 'Datetime');
1224
+			// load DTT helper
1225
+			// 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.
1226
+			if ($DTT->get_raw('DTT_EVT_start') > $DTT->get_raw('DTT_EVT_end')) {
1227
+				$DTT->set('DTT_EVT_end', $DTT->get('DTT_EVT_start'));
1228
+				$DTT = EEH_DTT_Helper::date_time_add($DTT, 'DTT_EVT_end', 'days');
1229
+				$DTT->save();
1230
+			}
1231
+			// 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.
1232
+			$saved_dtt = $DTT;
1233
+			$success = ! $success ? $success : $DTT;
1234
+			// if ANY of these updates fail then we want the appropriate global error message.
1235
+			// //todo this is actually sucky we need a better error message but this is what it is for now.
1236
+		}
1237
+		// no dtts get deleted so we don't do any of that logic here.
1238
+		// update tickets next
1239
+		$old_tickets = isset($data['ticket_IDs']) ? explode(',', $data['ticket_IDs']) : array();
1240
+		foreach ($data['edit_tickets'] as $row => $tkt) {
1241
+			$incoming_date_formats = array('Y-m-d', 'h:i a');
1242
+			$update_prices = false;
1243
+			$ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1244
+				? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0;
1245
+			// trim inputs to ensure any excess whitespace is removed.
1246
+			$tkt = array_map('trim', $tkt);
1247
+			if (empty($tkt['TKT_start_date'])) {
1248
+				// let's use now in the set timezone.
1249
+				$now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1250
+				$tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1251
+			}
1252
+			if (empty($tkt['TKT_end_date'])) {
1253
+				// use the start date of the first datetime
1254
+				$dtt = $evtobj->first_datetime();
1255
+				$tkt['TKT_end_date'] = $dtt->start_date_and_time(
1256
+					$incoming_date_formats[0],
1257
+					$incoming_date_formats[1]
1258
+				);
1259
+			}
1260
+			$TKT_values = array(
1261
+				'TKT_ID'          => ! empty($tkt['TKT_ID']) ? $tkt['TKT_ID'] : null,
1262
+				'TTM_ID'          => ! empty($tkt['TTM_ID']) ? $tkt['TTM_ID'] : 0,
1263
+				'TKT_name'        => ! empty($tkt['TKT_name']) ? $tkt['TKT_name'] : '',
1264
+				'TKT_description' => ! empty($tkt['TKT_description']) ? $tkt['TKT_description'] : '',
1265
+				'TKT_start_date'  => $tkt['TKT_start_date'],
1266
+				'TKT_end_date'    => $tkt['TKT_end_date'],
1267
+				'TKT_qty'         => ! isset($tkt['TKT_qty']) || $tkt['TKT_qty'] === '' ? EE_INF : $tkt['TKT_qty'],
1268
+				'TKT_uses'        => ! isset($tkt['TKT_uses']) || $tkt['TKT_uses'] === '' ? EE_INF : $tkt['TKT_uses'],
1269
+				'TKT_min'         => empty($tkt['TKT_min']) ? 0 : $tkt['TKT_min'],
1270
+				'TKT_max'         => empty($tkt['TKT_max']) ? EE_INF : $tkt['TKT_max'],
1271
+				'TKT_row'         => $row,
1272
+				'TKT_order'       => isset($tkt['TKT_order']) ? $tkt['TKT_order'] : $row,
1273
+				'TKT_price'       => $ticket_price,
1274
+			);
1275
+			// 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.
1276
+			if (isset($tkt['TKT_is_default']) && $tkt['TKT_is_default']) {
1277
+				$TKT_values['TKT_ID'] = 0;
1278
+				$TKT_values['TKT_is_default'] = 0;
1279
+				$TKT_values['TKT_price'] = $ticket_price;
1280
+				$update_prices = true;
1281
+			}
1282
+			// if we have a TKT_ID then we need to get that existing TKT_obj and update it
1283
+			// 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.
1284
+			// 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.
1285
+			if (! empty($tkt['TKT_ID'])) {
1286
+				$TKT = EE_Registry::instance()
1287
+								  ->load_model('Ticket', array($evtobj->get_timezone()))
1288
+								  ->get_one_by_ID($tkt['TKT_ID']);
1289
+				if ($TKT instanceof EE_Ticket) {
1290
+					$ticket_sold = $TKT->count_related(
1291
+						'Registration',
1292
+						array(
1293
+							array(
1294
+								'STS_ID' => array(
1295
+									'NOT IN',
1296
+									array(EEM_Registration::status_id_incomplete),
1297
+								),
1298
+							),
1299
+						)
1300
+					) > 0;
1301
+					// let's just check the total price for the existing ticket and determine if it matches the new
1302
+					// total price.  if they are different then we create a new ticket (if tickets sold)
1303
+					// if they aren't different then we go ahead and modify existing ticket.
1304
+					$create_new_TKT = $ticket_sold && ! $TKT->deleted() && EEH_Money::compare_floats(
1305
+						$ticket_price,
1306
+						$TKT->get('TKT_price'),
1307
+						'!=='
1308
+					);
1309
+					$TKT->set_date_format($incoming_date_formats[0]);
1310
+					$TKT->set_time_format($incoming_date_formats[1]);
1311
+					// set new values
1312
+					foreach ($TKT_values as $field => $value) {
1313
+						if ($field === 'TKT_qty') {
1314
+							$TKT->set_qty($value);
1315
+						} else {
1316
+							$TKT->set($field, $value);
1317
+						}
1318
+					}
1319
+					// if $create_new_TKT is false then we can safely update the existing ticket.  Otherwise we have to create a new ticket.
1320
+					if ($create_new_TKT) {
1321
+						// archive the old ticket first
1322
+						$TKT->set('TKT_deleted', 1);
1323
+						$TKT->save();
1324
+						// make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1325
+						$saved_tickets[ $TKT->ID() ] = $TKT;
1326
+						// 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.
1327
+						$TKT = clone $TKT;
1328
+						$TKT->set('TKT_ID', 0);
1329
+						$TKT->set('TKT_deleted', 0);
1330
+						$TKT->set('TKT_price', $ticket_price);
1331
+						$TKT->set('TKT_sold', 0);
1332
+						// now we need to make sure that $new prices are created as well and attached to new ticket.
1333
+						$update_prices = true;
1334
+					}
1335
+					// make sure price is set if it hasn't been already
1336
+					$TKT->set('TKT_price', $ticket_price);
1337
+				}
1338
+			} else {
1339
+				// no TKT_id so a new TKT
1340
+				$TKT_values['TKT_price'] = $ticket_price;
1341
+				$TKT = EE_Registry::instance()->load_class('Ticket', array($TKT_values), false, false);
1342
+				if ($TKT instanceof EE_Ticket) {
1343
+					// need to reset values to properly account for the date formats
1344
+					$TKT->set_date_format($incoming_date_formats[0]);
1345
+					$TKT->set_time_format($incoming_date_formats[1]);
1346
+					$TKT->set_timezone($evtobj->get_timezone());
1347
+					// set new values
1348
+					foreach ($TKT_values as $field => $value) {
1349
+						if ($field === 'TKT_qty') {
1350
+							$TKT->set_qty($value);
1351
+						} else {
1352
+							$TKT->set($field, $value);
1353
+						}
1354
+					}
1355
+					$update_prices = true;
1356
+				}
1357
+			}
1358
+			// cap ticket qty by datetime reg limits
1359
+			$TKT->set_qty(min($TKT->qty(), $TKT->qty('reg_limit')));
1360
+			// update ticket.
1361
+			$TKT->save();
1362
+			// 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.
1363
+			if ($TKT->get_raw('TKT_start_date') > $TKT->get_raw('TKT_end_date')) {
1364
+				$TKT->set('TKT_end_date', $TKT->get('TKT_start_date'));
1365
+				$TKT = EEH_DTT_Helper::date_time_add($TKT, 'TKT_end_date', 'days');
1366
+				$TKT->save();
1367
+			}
1368
+			// initially let's add the ticket to the dtt
1369
+			$saved_dtt->_add_relation_to($TKT, 'Ticket');
1370
+			$saved_tickets[ $TKT->ID() ] = $TKT;
1371
+			// add prices to ticket
1372
+			$this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1373
+		}
1374
+		// 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.
1375
+		$old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
1376
+		$tickets_removed = array_diff($old_tickets, array_keys($saved_tickets));
1377
+		foreach ($tickets_removed as $id) {
1378
+			$id = absint($id);
1379
+			// get the ticket for this id
1380
+			$tkt_to_remove = EE_Registry::instance()->load_model('Ticket')->get_one_by_ID($id);
1381
+			// 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)
1382
+			$dtts = $tkt_to_remove->get_many_related('Datetime');
1383
+			foreach ($dtts as $dtt) {
1384
+				$tkt_to_remove->_remove_relation_to($dtt, 'Datetime');
1385
+			}
1386
+			// 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))
1387
+			$tkt_to_remove->delete_related_permanently('Price');
1388
+			// finally let's delete this ticket (which should not be blocked at this point b/c we've removed all our relationships)
1389
+			$tkt_to_remove->delete_permanently();
1390
+		}
1391
+		return array($saved_dtt, $saved_tickets);
1392
+	}
1393
+
1394
+
1395
+	/**
1396
+	 * This attaches a list of given prices to a ticket.
1397
+	 * Note we dont' have to worry about ever removing relationships (or archiving prices) because if there is a change
1398
+	 * in price information on a ticket, a new ticket is created anyways so the archived ticket will retain the old
1399
+	 * price info and prices are automatically "archived" via the ticket.
1400
+	 *
1401
+	 * @access  private
1402
+	 * @param array     $prices     Array of prices from the form.
1403
+	 * @param EE_Ticket $ticket     EE_Ticket object that prices are being attached to.
1404
+	 * @param bool      $new_prices Whether attach existing incoming prices or create new ones.
1405
+	 * @return  void
1406
+	 * @throws EE_Error
1407
+	 * @throws InvalidArgumentException
1408
+	 * @throws InvalidDataTypeException
1409
+	 * @throws InvalidInterfaceException
1410
+	 * @throws ReflectionException
1411
+	 */
1412
+	private function _add_prices_to_ticket($prices, EE_Ticket $ticket, $new_prices = false)
1413
+	{
1414
+		foreach ($prices as $row => $prc) {
1415
+			$PRC_values = array(
1416
+				'PRC_ID'         => ! empty($prc['PRC_ID']) ? $prc['PRC_ID'] : null,
1417
+				'PRT_ID'         => ! empty($prc['PRT_ID']) ? $prc['PRT_ID'] : null,
1418
+				'PRC_amount'     => ! empty($prc['PRC_amount']) ? $prc['PRC_amount'] : 0,
1419
+				'PRC_name'       => ! empty($prc['PRC_name']) ? $prc['PRC_name'] : '',
1420
+				'PRC_desc'       => ! empty($prc['PRC_desc']) ? $prc['PRC_desc'] : '',
1421
+				'PRC_is_default' => 0, // make sure prices are NOT set as default from this context
1422
+				'PRC_order'      => $row,
1423
+			);
1424
+			if ($new_prices || empty($PRC_values['PRC_ID'])) {
1425
+				$PRC_values['PRC_ID'] = 0;
1426
+				$PRC = EE_Registry::instance()->load_class('Price', array($PRC_values), false, false);
1427
+			} else {
1428
+				$PRC = EE_Registry::instance()->load_model('Price')->get_one_by_ID($prc['PRC_ID']);
1429
+				// update this price with new values
1430
+				foreach ($PRC_values as $field => $newprc) {
1431
+					$PRC->set($field, $newprc);
1432
+				}
1433
+				$PRC->save();
1434
+			}
1435
+			$ticket->_add_relation_to($PRC, 'Price');
1436
+		}
1437
+	}
1438
+
1439
+
1440
+	/**
1441
+	 * Add in our autosave ajax handlers
1442
+	 *
1443
+	 */
1444
+	protected function _ee_autosave_create_new()
1445
+	{
1446
+	}
1447
+
1448
+
1449
+	/**
1450
+	 * More autosave handlers.
1451
+	 */
1452
+	protected function _ee_autosave_edit()
1453
+	{
1454
+	}
1455
+
1456
+
1457
+	/**
1458
+	 *    _generate_publish_box_extra_content
1459
+	 *
1460
+	 * @throws DomainException
1461
+	 * @throws EE_Error
1462
+	 * @throws InvalidArgumentException
1463
+	 * @throws InvalidDataTypeException
1464
+	 * @throws InvalidInterfaceException
1465
+	 * @throws ReflectionException
1466
+	 */
1467
+	private function _generate_publish_box_extra_content()
1468
+	{
1469
+		// load formatter helper
1470
+		// args for getting related registrations
1471
+		$approved_query_args = array(
1472
+			array(
1473
+				'REG_deleted' => 0,
1474
+				'STS_ID'      => EEM_Registration::status_id_approved,
1475
+			),
1476
+		);
1477
+		$not_approved_query_args = array(
1478
+			array(
1479
+				'REG_deleted' => 0,
1480
+				'STS_ID'      => EEM_Registration::status_id_not_approved,
1481
+			),
1482
+		);
1483
+		$pending_payment_query_args = array(
1484
+			array(
1485
+				'REG_deleted' => 0,
1486
+				'STS_ID'      => EEM_Registration::status_id_pending_payment,
1487
+			),
1488
+		);
1489
+		// publish box
1490
+		$publish_box_extra_args = array(
1491
+			'view_approved_reg_url'        => add_query_arg(
1492
+				array(
1493
+					'action'      => 'default',
1494
+					'event_id'    => $this->_cpt_model_obj->ID(),
1495
+					'_reg_status' => EEM_Registration::status_id_approved,
1496
+				),
1497
+				REG_ADMIN_URL
1498
+			),
1499
+			'view_not_approved_reg_url'    => add_query_arg(
1500
+				array(
1501
+					'action'      => 'default',
1502
+					'event_id'    => $this->_cpt_model_obj->ID(),
1503
+					'_reg_status' => EEM_Registration::status_id_not_approved,
1504
+				),
1505
+				REG_ADMIN_URL
1506
+			),
1507
+			'view_pending_payment_reg_url' => add_query_arg(
1508
+				array(
1509
+					'action'      => 'default',
1510
+					'event_id'    => $this->_cpt_model_obj->ID(),
1511
+					'_reg_status' => EEM_Registration::status_id_pending_payment,
1512
+				),
1513
+				REG_ADMIN_URL
1514
+			),
1515
+			'approved_regs'                => $this->_cpt_model_obj->count_related(
1516
+				'Registration',
1517
+				$approved_query_args
1518
+			),
1519
+			'not_approved_regs'            => $this->_cpt_model_obj->count_related(
1520
+				'Registration',
1521
+				$not_approved_query_args
1522
+			),
1523
+			'pending_payment_regs'         => $this->_cpt_model_obj->count_related(
1524
+				'Registration',
1525
+				$pending_payment_query_args
1526
+			),
1527
+			'misc_pub_section_class'       => apply_filters(
1528
+				'FHEE_Events_Admin_Page___generate_publish_box_extra_content__misc_pub_section_class',
1529
+				'misc-pub-section'
1530
+			),
1531
+		);
1532
+		ob_start();
1533
+		do_action(
1534
+			'AHEE__Events_Admin_Page___generate_publish_box_extra_content__event_editor_overview_add',
1535
+			$this->_cpt_model_obj
1536
+		);
1537
+		$publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1538
+		// load template
1539
+		EEH_Template::display_template(
1540
+			EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1541
+			$publish_box_extra_args
1542
+		);
1543
+	}
1544
+
1545
+
1546
+	/**
1547
+	 * @return EE_Event
1548
+	 */
1549
+	public function get_event_object()
1550
+	{
1551
+		return $this->_cpt_model_obj;
1552
+	}
1553
+
1554
+
1555
+
1556
+
1557
+	/** METABOXES * */
1558
+	/**
1559
+	 * _register_event_editor_meta_boxes
1560
+	 * add all metaboxes related to the event_editor
1561
+	 *
1562
+	 * @return void
1563
+	 * @throws EE_Error
1564
+	 * @throws InvalidArgumentException
1565
+	 * @throws InvalidDataTypeException
1566
+	 * @throws InvalidInterfaceException
1567
+	 * @throws ReflectionException
1568
+	 */
1569
+	protected function _register_event_editor_meta_boxes()
1570
+	{
1571
+		$this->verify_cpt_object();
1572
+		if (! EE_Registry::instance()->CFG->admin->useAdvancedEditor()) {
1573
+			add_meta_box(
1574
+				'espresso_event_editor_tickets',
1575
+				esc_html__('Event Datetime & Ticket', 'event_espresso'),
1576
+				[$this, 'ticket_metabox'],
1577
+				$this->page_slug,
1578
+				'normal',
1579
+				'high'
1580
+			);
1581
+		}
1582
+		add_meta_box(
1583
+			'espresso_event_editor_event_options',
1584
+			esc_html__('Event Registration Options', 'event_espresso'),
1585
+			array($this, 'registration_options_meta_box'),
1586
+			$this->page_slug,
1587
+			'side'
1588
+		);
1589
+		// NOTE: if you're looking for other metaboxes in here,
1590
+		// where a metabox has a related management page in the admin
1591
+		// you will find it setup in the related management page's "_Hooks" file.
1592
+		// i.e. messages metabox is found in "espresso_events_Messages_Hooks.class.php".
1593
+	}
1594
+
1595
+
1596
+	/**
1597
+	 * @throws DomainException
1598
+	 * @throws EE_Error
1599
+	 * @throws InvalidArgumentException
1600
+	 * @throws InvalidDataTypeException
1601
+	 * @throws InvalidInterfaceException
1602
+	 * @throws ReflectionException
1603
+	 */
1604
+	public function ticket_metabox()
1605
+	{
1606
+		$existing_datetime_ids = $existing_ticket_ids = array();
1607
+		// defaults for template args
1608
+		$template_args = array(
1609
+			'existing_datetime_ids'    => '',
1610
+			'event_datetime_help_link' => '',
1611
+			'ticket_options_help_link' => '',
1612
+			'time'                     => null,
1613
+			'ticket_rows'              => '',
1614
+			'existing_ticket_ids'      => '',
1615
+			'total_ticket_rows'        => 1,
1616
+			'ticket_js_structure'      => '',
1617
+			'trash_icon'               => 'ee-lock-icon',
1618
+			'disabled'                 => '',
1619
+		);
1620
+		$event_id = is_object($this->_cpt_model_obj) ? $this->_cpt_model_obj->ID() : null;
1621
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
1622
+		/**
1623
+		 * 1. Start with retrieving Datetimes
1624
+		 * 2. Fore each datetime get related tickets
1625
+		 * 3. For each ticket get related prices
1626
+		 */
1627
+		$times = EE_Registry::instance()->load_model('Datetime')->get_all_event_dates($event_id);
1628
+		/** @type EE_Datetime $first_datetime */
1629
+		$first_datetime = reset($times);
1630
+		// do we get related tickets?
1631
+		if ($first_datetime instanceof EE_Datetime
1632
+			&& $first_datetime->ID() !== 0
1633
+		) {
1634
+			$existing_datetime_ids[] = $first_datetime->get('DTT_ID');
1635
+			$template_args['time'] = $first_datetime;
1636
+			$related_tickets = $first_datetime->tickets(
1637
+				array(
1638
+					array('OR' => array('TKT_deleted' => 1, 'TKT_deleted*' => 0)),
1639
+					'default_where_conditions' => 'none',
1640
+				)
1641
+			);
1642
+			if (! empty($related_tickets)) {
1643
+				$template_args['total_ticket_rows'] = count($related_tickets);
1644
+				$row = 0;
1645
+				foreach ($related_tickets as $ticket) {
1646
+					$existing_ticket_ids[] = $ticket->get('TKT_ID');
1647
+					$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket, false, $row);
1648
+					$row++;
1649
+				}
1650
+			} else {
1651
+				$template_args['total_ticket_rows'] = 1;
1652
+				/** @type EE_Ticket $ticket */
1653
+				$ticket = EE_Registry::instance()->load_model('Ticket')->create_default_object();
1654
+				$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket);
1655
+			}
1656
+		} else {
1657
+			$template_args['time'] = $times[0];
1658
+			/** @type EE_Ticket $ticket */
1659
+			$ticket = EE_Registry::instance()->load_model('Ticket')->get_all_default_tickets();
1660
+			$template_args['ticket_rows'] .= $this->_get_ticket_row($ticket[1]);
1661
+			// NOTE: we're just sending the first default row
1662
+			// (decaf can't manage default tickets so this should be sufficient);
1663
+		}
1664
+		$template_args['event_datetime_help_link'] = $this->_get_help_tab_link(
1665
+			'event_editor_event_datetimes_help_tab'
1666
+		);
1667
+		$template_args['ticket_options_help_link'] = $this->_get_help_tab_link('ticket_options_info');
1668
+		$template_args['existing_datetime_ids'] = implode(',', $existing_datetime_ids);
1669
+		$template_args['existing_ticket_ids'] = implode(',', $existing_ticket_ids);
1670
+		$template_args['ticket_js_structure'] = $this->_get_ticket_row(
1671
+			EE_Registry::instance()->load_model('Ticket')->create_default_object(),
1672
+			true
1673
+		);
1674
+		$template = apply_filters(
1675
+			'FHEE__Events_Admin_Page__ticket_metabox__template',
1676
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1677
+		);
1678
+		EEH_Template::display_template($template, $template_args);
1679
+	}
1680
+
1681
+
1682
+	/**
1683
+	 * Setup an individual ticket form for the decaf event editor page
1684
+	 *
1685
+	 * @access private
1686
+	 * @param EE_Ticket $ticket   the ticket object
1687
+	 * @param boolean   $skeleton whether we're generating a skeleton for js manipulation
1688
+	 * @param int       $row
1689
+	 * @return string generated html for the ticket row.
1690
+	 * @throws DomainException
1691
+	 * @throws EE_Error
1692
+	 * @throws InvalidArgumentException
1693
+	 * @throws InvalidDataTypeException
1694
+	 * @throws InvalidInterfaceException
1695
+	 * @throws ReflectionException
1696
+	 */
1697
+	private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1698
+	{
1699
+		$template_args = array(
1700
+			'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1701
+			'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1702
+				: '',
1703
+			'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
1704
+			'TKT_ID'              => $ticket->get('TKT_ID'),
1705
+			'TKT_name'            => $ticket->get('TKT_name'),
1706
+			'TKT_start_date'      => $skeleton ? '' : $ticket->get_date('TKT_start_date', 'Y-m-d h:i a'),
1707
+			'TKT_end_date'        => $skeleton ? '' : $ticket->get_date('TKT_end_date', 'Y-m-d h:i a'),
1708
+			'TKT_is_default'      => $ticket->get('TKT_is_default'),
1709
+			'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1710
+			'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1711
+			'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1712
+			'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1713
+									 && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1714
+				? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1715
+			'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1716
+				: ' disabled=disabled',
1717
+		);
1718
+		$price = $ticket->ID() !== 0
1719
+			? $ticket->get_first_related('Price', array('default_where_conditions' => 'none'))
1720
+			: EE_Registry::instance()->load_model('Price')->create_default_object();
1721
+		$price_args = array(
1722
+			'price_currency_symbol' => EE_Registry::instance()->CFG->currency->sign,
1723
+			'PRC_amount'            => $price->get('PRC_amount'),
1724
+			'PRT_ID'                => $price->get('PRT_ID'),
1725
+			'PRC_ID'                => $price->get('PRC_ID'),
1726
+			'PRC_is_default'        => $price->get('PRC_is_default'),
1727
+		);
1728
+		// make sure we have default start and end dates if skeleton
1729
+		// handle rows that should NOT be empty
1730
+		if (empty($template_args['TKT_start_date'])) {
1731
+			// if empty then the start date will be now.
1732
+			$template_args['TKT_start_date'] = date('Y-m-d h:i a', current_time('timestamp'));
1733
+		}
1734
+		if (empty($template_args['TKT_end_date'])) {
1735
+			// get the earliest datetime (if present);
1736
+			$earliest_dtt = $this->_cpt_model_obj->ID() > 0
1737
+				? $this->_cpt_model_obj->get_first_related(
1738
+					'Datetime',
1739
+					array('order_by' => array('DTT_EVT_start' => 'ASC'))
1740
+				)
1741
+				: null;
1742
+			if (! empty($earliest_dtt)) {
1743
+				$template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1744
+			} else {
1745
+				$template_args['TKT_end_date'] = date(
1746
+					'Y-m-d h:i a',
1747
+					mktime(0, 0, 0, date('m'), date('d') + 7, date('Y'))
1748
+				);
1749
+			}
1750
+		}
1751
+		$template_args = array_merge($template_args, $price_args);
1752
+		$template = apply_filters(
1753
+			'FHEE__Events_Admin_Page__get_ticket_row__template',
1754
+			EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1755
+			$ticket
1756
+		);
1757
+		return EEH_Template::display_template($template, $template_args, true);
1758
+	}
1759
+
1760
+
1761
+	/**
1762
+	 * @throws DomainException
1763
+	 * @throws EE_Error
1764
+	 */
1765
+	public function registration_options_meta_box()
1766
+	{
1767
+		$yes_no_values = array(
1768
+			array('id' => true, 'text' => esc_html__('Yes', 'event_espresso')),
1769
+			array('id' => false, 'text' => esc_html__('No', 'event_espresso')),
1770
+		);
1771
+		$default_reg_status_values = EEM_Registration::reg_status_array(
1772
+			array(
1773
+				EEM_Registration::status_id_cancelled,
1774
+				EEM_Registration::status_id_declined,
1775
+				EEM_Registration::status_id_incomplete,
1776
+			),
1777
+			true
1778
+		);
1779
+		// $template_args['is_active_select'] = EEH_Form_Fields::select_input('is_active', $yes_no_values, $this->_cpt_model_obj->is_active());
1780
+		$template_args['_event'] = $this->_cpt_model_obj;
1781
+		$template_args['active_status'] = $this->_cpt_model_obj->pretty_active_status(false);
1782
+		$template_args['additional_limit'] = $this->_cpt_model_obj->additional_limit();
1783
+		$template_args['default_registration_status'] = EEH_Form_Fields::select_input(
1784
+			'default_reg_status',
1785
+			$default_reg_status_values,
1786
+			$this->_cpt_model_obj->default_registration_status()
1787
+		);
1788
+		$template_args['display_description'] = EEH_Form_Fields::select_input(
1789
+			'display_desc',
1790
+			$yes_no_values,
1791
+			$this->_cpt_model_obj->display_description()
1792
+		);
1793
+		$template_args['display_ticket_selector'] = EEH_Form_Fields::select_input(
1794
+			'display_ticket_selector',
1795
+			$yes_no_values,
1796
+			$this->_cpt_model_obj->display_ticket_selector(),
1797
+			'',
1798
+			'',
1799
+			false
1800
+		);
1801
+		$template_args['additional_registration_options'] = apply_filters(
1802
+			'FHEE__Events_Admin_Page__registration_options_meta_box__additional_registration_options',
1803
+			'',
1804
+			$template_args,
1805
+			$yes_no_values,
1806
+			$default_reg_status_values
1807
+		);
1808
+		EEH_Template::display_template(
1809
+			EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1810
+			$template_args
1811
+		);
1812
+	}
1813
+
1814
+
1815
+	/**
1816
+	 * _get_events()
1817
+	 * This method simply returns all the events (for the given _view and paging)
1818
+	 *
1819
+	 * @access public
1820
+	 * @param int  $per_page     count of items per page (20 default);
1821
+	 * @param int  $current_page what is the current page being viewed.
1822
+	 * @param bool $count        if TRUE then we just return a count of ALL events matching the given _view.
1823
+	 *                           If FALSE then we return an array of event objects
1824
+	 *                           that match the given _view and paging parameters.
1825
+	 * @return array an array of event objects.
1826
+	 * @throws EE_Error
1827
+	 * @throws InvalidArgumentException
1828
+	 * @throws InvalidDataTypeException
1829
+	 * @throws InvalidInterfaceException
1830
+	 * @throws ReflectionException
1831
+	 * @throws Exception
1832
+	 * @throws Exception
1833
+	 * @throws Exception
1834
+	 */
1835
+	public function get_events($per_page = 10, $current_page = 1, $count = false)
1836
+	{
1837
+		$EEME = $this->_event_model();
1838
+		$offset = ($current_page - 1) * $per_page;
1839
+		$limit = $count ? null : $offset . ',' . $per_page;
1840
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1841
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
1842
+		if (isset($this->_req_data['month_range'])) {
1843
+			$pieces = explode(' ', $this->_req_data['month_range'], 3);
1844
+			// simulate the FIRST day of the month, that fixes issues for months like February
1845
+			// where PHP doesn't know what to assume for date.
1846
+			// @see https://events.codebasehq.com/projects/event-espresso/tickets/10437
1847
+			$month_r = ! empty($pieces[0]) ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0])) : '';
1848
+			$year_r = ! empty($pieces[1]) ? $pieces[1] : '';
1849
+		}
1850
+		$where = array();
1851
+		$status = isset($this->_req_data['status']) ? $this->_req_data['status'] : null;
1852
+		// determine what post_status our condition will have for the query.
1853
+		switch ($status) {
1854
+			case 'month':
1855
+			case 'today':
1856
+			case null:
1857
+			case 'all':
1858
+				break;
1859
+			case 'draft':
1860
+				$where['status'] = array('IN', array('draft', 'auto-draft'));
1861
+				break;
1862
+			default:
1863
+				$where['status'] = $status;
1864
+		}
1865
+		// categories?
1866
+		$category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1867
+			? $this->_req_data['EVT_CAT'] : null;
1868
+		if (! empty($category)) {
1869
+			$where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1870
+			$where['Term_Taxonomy.term_id'] = $category;
1871
+		}
1872
+		// date where conditions
1873
+		$start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1874
+		if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] !== '') {
1875
+			$DateTime = new DateTime(
1876
+				$year_r . '-' . $month_r . '-01 00:00:00',
1877
+				new DateTimeZone('UTC')
1878
+			);
1879
+			$start = $DateTime->getTimestamp();
1880
+			// set the datetime to be the end of the month
1881
+			$DateTime->setDate(
1882
+				$year_r,
1883
+				$month_r,
1884
+				$DateTime->format('t')
1885
+			)->setTime(23, 59, 59);
1886
+			$end = $DateTime->getTimestamp();
1887
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1888
+		} elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'today') {
1889
+			$DateTime = new DateTime('now', new DateTimeZone(EEM_Event::instance()->get_timezone()));
1890
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1891
+			$end = $DateTime->setTime(23, 59, 59)->format(implode(' ', $start_formats));
1892
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1893
+		} elseif (isset($this->_req_data['status']) && $this->_req_data['status'] === 'month') {
1894
+			$now = date('Y-m-01');
1895
+			$DateTime = new DateTime($now, new DateTimeZone(EEM_Event::instance()->get_timezone()));
1896
+			$start = $DateTime->setTime(0, 0, 0)->format(implode(' ', $start_formats));
1897
+			$end = $DateTime->setDate(date('Y'), date('m'), $DateTime->format('t'))
1898
+							->setTime(23, 59, 59)
1899
+							->format(implode(' ', $start_formats));
1900
+			$where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1901
+		}
1902
+		if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1903
+			$where['EVT_wp_user'] = get_current_user_id();
1904
+		} elseif (! isset($where['status'])
1905
+			&& ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')
1906
+		) {
1907
+			$where['OR'] = array(
1908
+				'status*restrict_private' => array('!=', 'private'),
1909
+				'AND'                     => array(
1910
+					'status*inclusive' => array('=', 'private'),
1911
+					'EVT_wp_user'      => get_current_user_id(),
1912
+				),
1913
+			);
1914
+		}
1915
+
1916
+		if (isset($this->_req_data['EVT_wp_user'])
1917
+			&& (int) $this->_req_data['EVT_wp_user'] !== (int) get_current_user_id()
1918
+			&& EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')
1919
+		) {
1920
+			$where['EVT_wp_user'] = $this->_req_data['EVT_wp_user'];
1921
+		}
1922
+		// search query handling
1923
+		if (isset($this->_req_data['s'])) {
1924
+			$search_string = '%' . $this->_req_data['s'] . '%';
1925
+			$where['OR'] = array(
1926
+				'EVT_name'       => array('LIKE', $search_string),
1927
+				'EVT_desc'       => array('LIKE', $search_string),
1928
+				'EVT_short_desc' => array('LIKE', $search_string),
1929
+			);
1930
+		}
1931
+		// filter events by venue.
1932
+		if (isset($this->_req_data['venue']) && ! empty($this->_req_data['venue'])) {
1933
+			$where['Venue.VNU_ID'] = absint($this->_req_data['venue']);
1934
+		}
1935
+		$where = apply_filters('FHEE__Events_Admin_Page__get_events__where', $where, $this->_req_data);
1936
+		$query_params = apply_filters(
1937
+			'FHEE__Events_Admin_Page__get_events__query_params',
1938
+			array(
1939
+				$where,
1940
+				'limit'    => $limit,
1941
+				'order_by' => $orderby,
1942
+				'order'    => $order,
1943
+				'group_by' => 'EVT_ID',
1944
+			),
1945
+			$this->_req_data
1946
+		);
1947
+
1948
+		// let's first check if we have special requests coming in.
1949
+		if (isset($this->_req_data['active_status'])) {
1950
+			switch ($this->_req_data['active_status']) {
1951
+				case 'upcoming':
1952
+					return $EEME->get_upcoming_events($query_params, $count);
1953
+					break;
1954
+				case 'expired':
1955
+					return $EEME->get_expired_events($query_params, $count);
1956
+					break;
1957
+				case 'active':
1958
+					return $EEME->get_active_events($query_params, $count);
1959
+					break;
1960
+				case 'inactive':
1961
+					return $EEME->get_inactive_events($query_params, $count);
1962
+					break;
1963
+			}
1964
+		}
1965
+
1966
+		$events = $count ? $EEME->count(array($where), 'EVT_ID', true) : $EEME->get_all($query_params);
1967
+		return $events;
1968
+	}
1969
+
1970
+
1971
+	/**
1972
+	 * handling for WordPress CPT actions (trash, restore, delete)
1973
+	 *
1974
+	 * @param string $post_id
1975
+	 * @throws EE_Error
1976
+	 * @throws InvalidArgumentException
1977
+	 * @throws InvalidDataTypeException
1978
+	 * @throws InvalidInterfaceException
1979
+	 * @throws ReflectionException
1980
+	 */
1981
+	public function trash_cpt_item($post_id)
1982
+	{
1983
+		$this->_req_data['EVT_ID'] = $post_id;
1984
+		$this->_trash_or_restore_event('trash', false);
1985
+	}
1986
+
1987
+
1988
+	/**
1989
+	 * @param string $post_id
1990
+	 * @throws EE_Error
1991
+	 * @throws InvalidArgumentException
1992
+	 * @throws InvalidDataTypeException
1993
+	 * @throws InvalidInterfaceException
1994
+	 * @throws ReflectionException
1995
+	 */
1996
+	public function restore_cpt_item($post_id)
1997
+	{
1998
+		$this->_req_data['EVT_ID'] = $post_id;
1999
+		$this->_trash_or_restore_event('draft', false);
2000
+	}
2001
+
2002
+
2003
+	/**
2004
+	 * @param string $post_id
2005
+	 * @throws EE_Error
2006
+	 * @throws InvalidArgumentException
2007
+	 * @throws InvalidDataTypeException
2008
+	 * @throws InvalidInterfaceException
2009
+	 * @throws ReflectionException
2010
+	 */
2011
+	public function delete_cpt_item($post_id)
2012
+	{
2013
+		$this->_req_data['EVT_ID'] = $post_id;
2014
+		$this->_delete_event(false);
2015
+	}
2016
+
2017
+
2018
+	/**
2019
+	 * _trash_or_restore_event
2020
+	 *
2021
+	 * @access protected
2022
+	 * @param string $event_status
2023
+	 * @param bool   $redirect_after
2024
+	 * @throws EE_Error
2025
+	 * @throws InvalidArgumentException
2026
+	 * @throws InvalidDataTypeException
2027
+	 * @throws InvalidInterfaceException
2028
+	 * @throws ReflectionException
2029
+	 */
2030
+	protected function _trash_or_restore_event($event_status = 'trash', $redirect_after = true)
2031
+	{
2032
+		// determine the event id and set to array.
2033
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : false;
2034
+		// loop thru events
2035
+		if ($EVT_ID) {
2036
+			// clean status
2037
+			$event_status = sanitize_key($event_status);
2038
+			// grab status
2039
+			if (! empty($event_status)) {
2040
+				$success = $this->_change_event_status($EVT_ID, $event_status);
2041
+			} else {
2042
+				$success = false;
2043
+				$msg = esc_html__(
2044
+					'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2045
+					'event_espresso'
2046
+				);
2047
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2048
+			}
2049
+		} else {
2050
+			$success = false;
2051
+			$msg = esc_html__(
2052
+				'An error occurred. The event could not be moved to the trash because a valid event ID was not not supplied.',
2053
+				'event_espresso'
2054
+			);
2055
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2056
+		}
2057
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2058
+		if ($redirect_after) {
2059
+			$this->_redirect_after_action($success, 'Event', $action, array('action' => 'default'));
2060
+		}
2061
+	}
2062
+
2063
+
2064
+	/**
2065
+	 * _trash_or_restore_events
2066
+	 *
2067
+	 * @access protected
2068
+	 * @param string $event_status
2069
+	 * @return void
2070
+	 * @throws EE_Error
2071
+	 * @throws InvalidArgumentException
2072
+	 * @throws InvalidDataTypeException
2073
+	 * @throws InvalidInterfaceException
2074
+	 * @throws ReflectionException
2075
+	 */
2076
+	protected function _trash_or_restore_events($event_status = 'trash')
2077
+	{
2078
+		// clean status
2079
+		$event_status = sanitize_key($event_status);
2080
+		// grab status
2081
+		if (! empty($event_status)) {
2082
+			$success = true;
2083
+			// determine the event id and set to array.
2084
+			$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2085
+			// loop thru events
2086
+			foreach ($EVT_IDs as $EVT_ID) {
2087
+				if ($EVT_ID = absint($EVT_ID)) {
2088
+					$results = $this->_change_event_status($EVT_ID, $event_status);
2089
+					$success = $results !== false ? $success : false;
2090
+				} else {
2091
+					$msg = sprintf(
2092
+						esc_html__(
2093
+							'An error occurred. Event #%d could not be moved to the trash because a valid event ID was not not supplied.',
2094
+							'event_espresso'
2095
+						),
2096
+						$EVT_ID
2097
+					);
2098
+					EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2099
+					$success = false;
2100
+				}
2101
+			}
2102
+		} else {
2103
+			$success = false;
2104
+			$msg = esc_html__(
2105
+				'An error occurred. The event could not be moved to the trash because a valid event status was not not supplied.',
2106
+				'event_espresso'
2107
+			);
2108
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2109
+		}
2110
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2111
+		$success = $success ? 2 : false;
2112
+		$action = $event_status === 'trash' ? 'moved to the trash' : 'restored from the trash';
2113
+		$this->_redirect_after_action($success, 'Events', $action, array('action' => 'default'));
2114
+	}
2115
+
2116
+
2117
+	/**
2118
+	 * _trash_or_restore_events
2119
+	 *
2120
+	 * @access  private
2121
+	 * @param int    $EVT_ID
2122
+	 * @param string $event_status
2123
+	 * @return bool
2124
+	 * @throws EE_Error
2125
+	 * @throws InvalidArgumentException
2126
+	 * @throws InvalidDataTypeException
2127
+	 * @throws InvalidInterfaceException
2128
+	 * @throws ReflectionException
2129
+	 */
2130
+	private function _change_event_status($EVT_ID = 0, $event_status = '')
2131
+	{
2132
+		// grab event id
2133
+		if (! $EVT_ID) {
2134
+			$msg = esc_html__(
2135
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2136
+				'event_espresso'
2137
+			);
2138
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2139
+			return false;
2140
+		}
2141
+		$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2142
+		// clean status
2143
+		$event_status = sanitize_key($event_status);
2144
+		// grab status
2145
+		if (empty($event_status)) {
2146
+			$msg = esc_html__(
2147
+				'An error occurred. No Event Status or an invalid Event Status was received.',
2148
+				'event_espresso'
2149
+			);
2150
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2151
+			return false;
2152
+		}
2153
+		// was event trashed or restored ?
2154
+		switch ($event_status) {
2155
+			case 'draft':
2156
+				$action = 'restored from the trash';
2157
+				$hook = 'AHEE_event_restored_from_trash';
2158
+				break;
2159
+			case 'trash':
2160
+				$action = 'moved to the trash';
2161
+				$hook = 'AHEE_event_moved_to_trash';
2162
+				break;
2163
+			default:
2164
+				$action = 'updated';
2165
+				$hook = false;
2166
+		}
2167
+		// use class to change status
2168
+		$this->_cpt_model_obj->set_status($event_status);
2169
+		$success = $this->_cpt_model_obj->save();
2170
+		if ($success === false) {
2171
+			$msg = sprintf(esc_html__('An error occurred. The event could not be %s.', 'event_espresso'), $action);
2172
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2173
+			return false;
2174
+		}
2175
+		if ($hook) {
2176
+			do_action($hook);
2177
+		}
2178
+		return true;
2179
+	}
2180
+
2181
+
2182
+	/**
2183
+	 * _delete_event
2184
+	 *
2185
+	 * @access protected
2186
+	 * @param bool $redirect_after
2187
+	 * @throws EE_Error
2188
+	 * @throws InvalidArgumentException
2189
+	 * @throws InvalidDataTypeException
2190
+	 * @throws InvalidInterfaceException
2191
+	 * @throws ReflectionException
2192
+	 */
2193
+	protected function _delete_event($redirect_after = true)
2194
+	{
2195
+		// determine the event id and set to array.
2196
+		$EVT_ID = isset($this->_req_data['EVT_ID']) ? absint($this->_req_data['EVT_ID']) : null;
2197
+		$EVT_ID = isset($this->_req_data['post']) ? absint($this->_req_data['post']) : $EVT_ID;
2198
+		// loop thru events
2199
+		if ($EVT_ID) {
2200
+			$success = $this->_permanently_delete_event($EVT_ID);
2201
+			// get list of events with no prices
2202
+			$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2203
+			// remove this event from the list of events with no prices
2204
+			if (isset($espresso_no_ticket_prices[ $EVT_ID ])) {
2205
+				unset($espresso_no_ticket_prices[ $EVT_ID ]);
2206
+			}
2207
+			update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2208
+		} else {
2209
+			$success = false;
2210
+			$msg = esc_html__(
2211
+				'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2212
+				'event_espresso'
2213
+			);
2214
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2215
+		}
2216
+		if ($redirect_after) {
2217
+			$this->_redirect_after_action(
2218
+				$success,
2219
+				'Event',
2220
+				'deleted',
2221
+				array('action' => 'default', 'status' => 'trash')
2222
+			);
2223
+		}
2224
+	}
2225
+
2226
+
2227
+	/**
2228
+	 * _delete_events
2229
+	 *
2230
+	 * @access protected
2231
+	 * @return void
2232
+	 * @throws EE_Error
2233
+	 * @throws InvalidArgumentException
2234
+	 * @throws InvalidDataTypeException
2235
+	 * @throws InvalidInterfaceException
2236
+	 * @throws ReflectionException
2237
+	 */
2238
+	protected function _delete_events()
2239
+	{
2240
+		$success = true;
2241
+		// get list of events with no prices
2242
+		$espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2243
+		// determine the event id and set to array.
2244
+		$EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
2245
+		// loop thru events
2246
+		foreach ($EVT_IDs as $EVT_ID) {
2247
+			$EVT_ID = absint($EVT_ID);
2248
+			if ($EVT_ID) {
2249
+				$results = $this->_permanently_delete_event($EVT_ID);
2250
+				$success = $results !== false ? $success : false;
2251
+				// remove this event from the list of events with no prices
2252
+				unset($espresso_no_ticket_prices[ $EVT_ID ]);
2253
+			} else {
2254
+				$success = false;
2255
+				$msg = esc_html__(
2256
+					'An error occurred. An event could not be deleted because a valid event ID was not not supplied.',
2257
+					'event_espresso'
2258
+				);
2259
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2260
+			}
2261
+		}
2262
+		update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2263
+		// in order to force a pluralized result message we need to send back a success status greater than 1
2264
+		$success = $success ? 2 : false;
2265
+		$this->_redirect_after_action($success, 'Events', 'deleted', array('action' => 'default'));
2266
+	}
2267
+
2268
+
2269
+	/**
2270
+	 * _permanently_delete_event
2271
+	 *
2272
+	 * @access  private
2273
+	 * @param int $EVT_ID
2274
+	 * @return bool
2275
+	 * @throws EE_Error
2276
+	 * @throws InvalidArgumentException
2277
+	 * @throws InvalidDataTypeException
2278
+	 * @throws InvalidInterfaceException
2279
+	 * @throws ReflectionException
2280
+	 */
2281
+	private function _permanently_delete_event($EVT_ID = 0)
2282
+	{
2283
+		// grab event id
2284
+		if (! $EVT_ID) {
2285
+			$msg = esc_html__(
2286
+				'An error occurred. No Event ID or an invalid Event ID was received.',
2287
+				'event_espresso'
2288
+			);
2289
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2290
+			return false;
2291
+		}
2292
+		if (! $this->_cpt_model_obj instanceof EE_Event
2293
+			|| $this->_cpt_model_obj->ID() !== $EVT_ID
2294
+		) {
2295
+			$this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2296
+		}
2297
+		if (! $this->_cpt_model_obj instanceof EE_Event) {
2298
+			return false;
2299
+		}
2300
+		// need to delete related tickets and prices first.
2301
+		$datetimes = $this->_cpt_model_obj->get_many_related('Datetime');
2302
+		foreach ($datetimes as $datetime) {
2303
+			$this->_cpt_model_obj->_remove_relation_to($datetime, 'Datetime');
2304
+			$tickets = $datetime->get_many_related('Ticket');
2305
+			foreach ($tickets as $ticket) {
2306
+				$ticket->_remove_relation_to($datetime, 'Datetime');
2307
+				$ticket->delete_related_permanently('Price');
2308
+				$ticket->delete_permanently();
2309
+			}
2310
+			$datetime->delete();
2311
+		}
2312
+		// what about related venues or terms?
2313
+		$venues = $this->_cpt_model_obj->get_many_related('Venue');
2314
+		foreach ($venues as $venue) {
2315
+			$this->_cpt_model_obj->_remove_relation_to($venue, 'Venue');
2316
+		}
2317
+		// any attached question groups?
2318
+		$question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2319
+		if (! empty($question_groups)) {
2320
+			foreach ($question_groups as $question_group) {
2321
+				$this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2322
+			}
2323
+		}
2324
+		// Message Template Groups
2325
+		$this->_cpt_model_obj->_remove_relations('Message_Template_Group');
2326
+		/** @type EE_Term_Taxonomy[] $term_taxonomies */
2327
+		$term_taxonomies = $this->_cpt_model_obj->term_taxonomies();
2328
+		foreach ($term_taxonomies as $term_taxonomy) {
2329
+			$this->_cpt_model_obj->remove_relation_to_term_taxonomy($term_taxonomy);
2330
+		}
2331
+		$success = $this->_cpt_model_obj->delete_permanently();
2332
+		// did it all go as planned ?
2333
+		if ($success) {
2334
+			$msg = sprintf(esc_html__('Event ID # %d has been deleted.', 'event_espresso'), $EVT_ID);
2335
+			EE_Error::add_success($msg);
2336
+		} else {
2337
+			$msg = sprintf(
2338
+				esc_html__('An error occurred. Event ID # %d could not be deleted.', 'event_espresso'),
2339
+				$EVT_ID
2340
+			);
2341
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2342
+			return false;
2343
+		}
2344
+		do_action('AHEE__Events_Admin_Page___permanently_delete_event__after_event_deleted', $EVT_ID);
2345
+		return true;
2346
+	}
2347
+
2348
+
2349
+	/**
2350
+	 * get total number of events
2351
+	 *
2352
+	 * @access public
2353
+	 * @return int
2354
+	 * @throws EE_Error
2355
+	 * @throws InvalidArgumentException
2356
+	 * @throws InvalidDataTypeException
2357
+	 * @throws InvalidInterfaceException
2358
+	 */
2359
+	public function total_events()
2360
+	{
2361
+		$count = EEM_Event::instance()->count(array('caps' => 'read_admin'), 'EVT_ID', true);
2362
+		return $count;
2363
+	}
2364
+
2365
+
2366
+	/**
2367
+	 * get total number of draft events
2368
+	 *
2369
+	 * @access public
2370
+	 * @return int
2371
+	 * @throws EE_Error
2372
+	 * @throws InvalidArgumentException
2373
+	 * @throws InvalidDataTypeException
2374
+	 * @throws InvalidInterfaceException
2375
+	 */
2376
+	public function total_events_draft()
2377
+	{
2378
+		$where = array(
2379
+			'status' => array('IN', array('draft', 'auto-draft')),
2380
+		);
2381
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2382
+		return $count;
2383
+	}
2384
+
2385
+
2386
+	/**
2387
+	 * get total number of trashed events
2388
+	 *
2389
+	 * @access public
2390
+	 * @return int
2391
+	 * @throws EE_Error
2392
+	 * @throws InvalidArgumentException
2393
+	 * @throws InvalidDataTypeException
2394
+	 * @throws InvalidInterfaceException
2395
+	 */
2396
+	public function total_trashed_events()
2397
+	{
2398
+		$where = array(
2399
+			'status' => 'trash',
2400
+		);
2401
+		$count = EEM_Event::instance()->count(array($where, 'caps' => 'read_admin'), 'EVT_ID', true);
2402
+		return $count;
2403
+	}
2404
+
2405
+
2406
+	/**
2407
+	 *    _default_event_settings
2408
+	 *    This generates the Default Settings Tab
2409
+	 *
2410
+	 * @return void
2411
+	 * @throws DomainException
2412
+	 * @throws EE_Error
2413
+	 * @throws InvalidArgumentException
2414
+	 * @throws InvalidDataTypeException
2415
+	 * @throws InvalidInterfaceException
2416
+	 */
2417
+	protected function _default_event_settings()
2418
+	{
2419
+		$this->_set_add_edit_form_tags('update_default_event_settings');
2420
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
2421
+		$this->_template_args['admin_page_content'] = $this->_default_event_settings_form()->get_html();
2422
+		$this->display_admin_page_with_sidebar();
2423
+	}
2424
+
2425
+
2426
+	/**
2427
+	 * Return the form for event settings.
2428
+	 *
2429
+	 * @return EE_Form_Section_Proper
2430
+	 * @throws EE_Error
2431
+	 */
2432
+	protected function _default_event_settings_form()
2433
+	{
2434
+		$registration_config = EE_Registry::instance()->CFG->registration;
2435
+		$registration_stati_for_selection = EEM_Registration::reg_status_array(
2436
+			// exclude
2437
+			array(
2438
+				EEM_Registration::status_id_cancelled,
2439
+				EEM_Registration::status_id_declined,
2440
+				EEM_Registration::status_id_incomplete,
2441
+				EEM_Registration::status_id_wait_list,
2442
+			),
2443
+			true
2444
+		);
2445
+		return new EE_Form_Section_Proper(
2446
+			array(
2447
+				'name'            => 'update_default_event_settings',
2448
+				'html_id'         => 'update_default_event_settings',
2449
+				'html_class'      => 'form-table',
2450
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
2451
+				'subsections'     => apply_filters(
2452
+					'FHEE__Events_Admin_Page___default_event_settings_form__form_subsections',
2453
+					array(
2454
+						'default_reg_status'  => new EE_Select_Input(
2455
+							$registration_stati_for_selection,
2456
+							array(
2457
+								'default'         => isset($registration_config->default_STS_ID)
2458
+													 && array_key_exists(
2459
+														 $registration_config->default_STS_ID,
2460
+														 $registration_stati_for_selection
2461
+													 )
2462
+									? sanitize_text_field($registration_config->default_STS_ID)
2463
+									: EEM_Registration::status_id_pending_payment,
2464
+								'html_label_text' => esc_html__('Default Registration Status', 'event_espresso')
2465
+													 . EEH_Template::get_help_tab_link(
2466
+														 'default_settings_status_help_tab'
2467
+													 ),
2468
+								'html_help_text'  => esc_html__(
2469
+									'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.',
2470
+									'event_espresso'
2471
+								),
2472
+							)
2473
+						),
2474
+						'default_max_tickets' => new EE_Integer_Input(
2475
+							array(
2476
+								'default'         => isset($registration_config->default_maximum_number_of_tickets)
2477
+									? $registration_config->default_maximum_number_of_tickets
2478
+									: EEM_Event::get_default_additional_limit(),
2479
+								'html_label_text' => esc_html__(
2480
+									'Default Maximum Tickets Allowed Per Order:',
2481
+									'event_espresso'
2482
+								)
2483
+													 . EEH_Template::get_help_tab_link(
2484
+														 'default_maximum_tickets_help_tab"'
2485
+													 ),
2486
+								'html_help_text'  => esc_html__(
2487
+									'This setting allows you to indicate what will be the default for the maximum number of tickets per order when creating new events.',
2488
+									'event_espresso'
2489
+								),
2490
+							)
2491
+						),
2492
+					)
2493
+				),
2494
+			)
2495
+		);
2496
+	}
2497
+
2498
+
2499
+	/**
2500
+	 * @return void
2501
+	 * @throws EE_Error
2502
+	 * @throws InvalidArgumentException
2503
+	 * @throws InvalidDataTypeException
2504
+	 * @throws InvalidInterfaceException
2505
+	 */
2506
+	protected function _update_default_event_settings()
2507
+	{
2508
+		$form = $this->_default_event_settings_form();
2509
+		if ($form->was_submitted()) {
2510
+			$form->receive_form_submission();
2511
+			if ($form->is_valid()) {
2512
+				$registration_config = EE_Registry::instance()->CFG->registration;
2513
+				$valid_data = $form->valid_data();
2514
+				if (isset($valid_data['default_reg_status'])) {
2515
+					$registration_config->default_STS_ID = $valid_data['default_reg_status'];
2516
+				}
2517
+				if (isset($valid_data['default_max_tickets'])) {
2518
+					$registration_config->default_maximum_number_of_tickets = $valid_data['default_max_tickets'];
2519
+				}
2520
+				do_action(
2521
+					'AHEE__Events_Admin_Page___update_default_event_settings',
2522
+					$valid_data,
2523
+					EE_Registry::instance()->CFG,
2524
+					$this
2525
+				);
2526
+				// update because data was valid!
2527
+				EE_Registry::instance()->CFG->update_espresso_config();
2528
+				EE_Error::overwrite_success();
2529
+				EE_Error::add_success(
2530
+					__('Default Event Settings were updated', 'event_espresso')
2531
+				);
2532
+			}
2533
+		}
2534
+		$this->_redirect_after_action(0, '', '', array('action' => 'default_event_settings'), true);
2535
+	}
2536
+
2537
+
2538
+	/*************        Templates        *************/
2539
+	protected function _template_settings()
2540
+	{
2541
+		$this->_admin_page_title = esc_html__('Template Settings (Preview)', 'event_espresso');
2542
+		$this->_template_args['preview_img'] = '<img src="'
2543
+											   . EVENTS_ASSETS_URL
2544
+											   . '/images/'
2545
+											   . 'caffeinated_template_features.jpg" alt="'
2546
+											   . esc_attr__('Template Settings Preview screenshot', 'event_espresso')
2547
+											   . '" />';
2548
+		$this->_template_args['preview_text'] = '<strong>'
2549
+												. esc_html__(
2550
+													'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.',
2551
+													'event_espresso'
2552
+												) . '</strong>';
2553
+		$this->display_admin_caf_preview_page('template_settings_tab');
2554
+	}
2555
+
2556
+
2557
+	/** Event Category Stuff **/
2558
+	/**
2559
+	 * set the _category property with the category object for the loaded page.
2560
+	 *
2561
+	 * @access private
2562
+	 * @return void
2563
+	 */
2564
+	private function _set_category_object()
2565
+	{
2566
+		if (isset($this->_category->id) && ! empty($this->_category->id)) {
2567
+			return;
2568
+		} //already have the category object so get out.
2569
+		// set default category object
2570
+		$this->_set_empty_category_object();
2571
+		// only set if we've got an id
2572
+		if (! isset($this->_req_data['EVT_CAT_ID'])) {
2573
+			return;
2574
+		}
2575
+		$category_id = absint($this->_req_data['EVT_CAT_ID']);
2576
+		$term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2577
+		if (! empty($term)) {
2578
+			$this->_category->category_name = $term->name;
2579
+			$this->_category->category_identifier = $term->slug;
2580
+			$this->_category->category_desc = $term->description;
2581
+			$this->_category->id = $term->term_id;
2582
+			$this->_category->parent = $term->parent;
2583
+		}
2584
+	}
2585
+
2586
+
2587
+	/**
2588
+	 * Clears out category properties.
2589
+	 */
2590
+	private function _set_empty_category_object()
2591
+	{
2592
+		$this->_category = new stdClass();
2593
+		$this->_category->category_name = $this->_category->category_identifier = $this->_category->category_desc = '';
2594
+		$this->_category->id = $this->_category->parent = 0;
2595
+	}
2596
+
2597
+
2598
+	/**
2599
+	 * @throws DomainException
2600
+	 * @throws EE_Error
2601
+	 * @throws InvalidArgumentException
2602
+	 * @throws InvalidDataTypeException
2603
+	 * @throws InvalidInterfaceException
2604
+	 */
2605
+	protected function _category_list_table()
2606
+	{
2607
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2608
+		$this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2609
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2610
+			'add_category',
2611
+			'add_category',
2612
+			array(),
2613
+			'add-new-h2'
2614
+		);
2615
+		$this->display_admin_list_table_page_with_sidebar();
2616
+	}
2617
+
2618
+
2619
+	/**
2620
+	 * Output category details view.
2621
+	 *
2622
+	 * @param string $view
2623
+	 * @throws DomainException
2624
+	 * @throws EE_Error
2625
+	 * @throws InvalidArgumentException
2626
+	 * @throws InvalidDataTypeException
2627
+	 * @throws InvalidInterfaceException
2628
+	 */
2629
+	protected function _category_details($view)
2630
+	{
2631
+		// load formatter helper
2632
+		// load field generator helper
2633
+		$route = $view === 'edit' ? 'update_category' : 'insert_category';
2634
+		$this->_set_add_edit_form_tags($route);
2635
+		$this->_set_category_object();
2636
+		$id = ! empty($this->_category->id) ? $this->_category->id : '';
2637
+		$delete_action = 'delete_category';
2638
+		// custom redirect
2639
+		$redirect = EE_Admin_Page::add_query_args_and_nonce(
2640
+			array('action' => 'category_list'),
2641
+			$this->_admin_base_url
2642
+		);
2643
+		$this->_set_publish_post_box_vars('EVT_CAT_ID', $id, $delete_action, $redirect);
2644
+		// take care of contents
2645
+		$this->_template_args['admin_page_content'] = $this->_category_details_content();
2646
+		$this->display_admin_page_with_sidebar();
2647
+	}
2648
+
2649
+
2650
+	/**
2651
+	 * Output category details content.
2652
+	 *
2653
+	 * @throws DomainException
2654
+	 */
2655
+	protected function _category_details_content()
2656
+	{
2657
+		$editor_args['category_desc'] = array(
2658
+			'type'          => 'wp_editor',
2659
+			'value'         => EEH_Formatter::admin_format_content($this->_category->category_desc),
2660
+			'class'         => 'my_editor_custom',
2661
+			'wpeditor_args' => array('media_buttons' => false),
2662
+		);
2663
+		$_wp_editor = $this->_generate_admin_form_fields($editor_args, 'array');
2664
+		$all_terms = get_terms(
2665
+			array(EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY),
2666
+			array('hide_empty' => 0, 'exclude' => array($this->_category->id))
2667
+		);
2668
+		// setup category select for term parents.
2669
+		$category_select_values[] = array(
2670
+			'text' => esc_html__('No Parent', 'event_espresso'),
2671
+			'id'   => 0,
2672
+		);
2673
+		foreach ($all_terms as $term) {
2674
+			$category_select_values[] = array(
2675
+				'text' => $term->name,
2676
+				'id'   => $term->term_id,
2677
+			);
2678
+		}
2679
+		$category_select = EEH_Form_Fields::select_input(
2680
+			'category_parent',
2681
+			$category_select_values,
2682
+			$this->_category->parent
2683
+		);
2684
+		$template_args = array(
2685
+			'category'                 => $this->_category,
2686
+			'category_select'          => $category_select,
2687
+			'unique_id_info_help_link' => $this->_get_help_tab_link('unique_id_info'),
2688
+			'category_desc_editor'     => $_wp_editor['category_desc']['field'],
2689
+			'disable'                  => '',
2690
+			'disabled_message'         => false,
2691
+		);
2692
+		$template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2693
+		return EEH_Template::display_template($template, $template_args, true);
2694
+	}
2695
+
2696
+
2697
+	/**
2698
+	 * Handles deleting categories.
2699
+	 */
2700
+	protected function _delete_categories()
2701
+	{
2702
+		$cat_ids = isset($this->_req_data['EVT_CAT_ID']) ? (array) $this->_req_data['EVT_CAT_ID']
2703
+			: (array) $this->_req_data['category_id'];
2704
+		foreach ($cat_ids as $cat_id) {
2705
+			$this->_delete_category($cat_id);
2706
+		}
2707
+		// doesn't matter what page we're coming from... we're going to the same place after delete.
2708
+		$query_args = array(
2709
+			'action' => 'category_list',
2710
+		);
2711
+		$this->_redirect_after_action(0, '', '', $query_args);
2712
+	}
2713
+
2714
+
2715
+	/**
2716
+	 * Handles deleting specific category.
2717
+	 *
2718
+	 * @param int $cat_id
2719
+	 */
2720
+	protected function _delete_category($cat_id)
2721
+	{
2722
+		$cat_id = absint($cat_id);
2723
+		wp_delete_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2724
+	}
2725
+
2726
+
2727
+	/**
2728
+	 * Handles triggering the update or insertion of a new category.
2729
+	 *
2730
+	 * @param bool $new_category true means we're triggering the insert of a new category.
2731
+	 * @throws EE_Error
2732
+	 * @throws InvalidArgumentException
2733
+	 * @throws InvalidDataTypeException
2734
+	 * @throws InvalidInterfaceException
2735
+	 */
2736
+	protected function _insert_or_update_category($new_category)
2737
+	{
2738
+		$cat_id = $new_category ? $this->_insert_category() : $this->_insert_category(true);
2739
+		$success = 0; // we already have a success message so lets not send another.
2740
+		if ($cat_id) {
2741
+			$query_args = array(
2742
+				'action'     => 'edit_category',
2743
+				'EVT_CAT_ID' => $cat_id,
2744
+			);
2745
+		} else {
2746
+			$query_args = array('action' => 'add_category');
2747
+		}
2748
+		$this->_redirect_after_action($success, '', '', $query_args, true);
2749
+	}
2750
+
2751
+
2752
+	/**
2753
+	 * Inserts or updates category
2754
+	 *
2755
+	 * @param bool $update (true indicates we're updating a category).
2756
+	 * @return bool|mixed|string
2757
+	 */
2758
+	private function _insert_category($update = false)
2759
+	{
2760
+		$cat_id = $update ? $this->_req_data['EVT_CAT_ID'] : '';
2761
+		$category_name = isset($this->_req_data['category_name']) ? $this->_req_data['category_name'] : '';
2762
+		$category_desc = isset($this->_req_data['category_desc']) ? $this->_req_data['category_desc'] : '';
2763
+		$category_parent = isset($this->_req_data['category_parent']) ? $this->_req_data['category_parent'] : 0;
2764
+		if (empty($category_name)) {
2765
+			$msg = esc_html__('You must add a name for the category.', 'event_espresso');
2766
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2767
+			return false;
2768
+		}
2769
+		$term_args = array(
2770
+			'name'        => $category_name,
2771
+			'description' => $category_desc,
2772
+			'parent'      => $category_parent,
2773
+		);
2774
+		// was the category_identifier input disabled?
2775
+		if (isset($this->_req_data['category_identifier'])) {
2776
+			$term_args['slug'] = $this->_req_data['category_identifier'];
2777
+		}
2778
+		$insert_ids = $update
2779
+			? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2780
+			: wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2781
+		if (! is_array($insert_ids)) {
2782
+			$msg = esc_html__(
2783
+				'An error occurred and the category has not been saved to the database.',
2784
+				'event_espresso'
2785
+			);
2786
+			EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2787
+		} else {
2788
+			$cat_id = $insert_ids['term_id'];
2789
+			$msg = sprintf(esc_html__('The category %s was successfully saved', 'event_espresso'), $category_name);
2790
+			EE_Error::add_success($msg);
2791
+		}
2792
+		return $cat_id;
2793
+	}
2794
+
2795
+
2796
+	/**
2797
+	 * Gets categories or count of categories matching the arguments in the request.
2798
+	 *
2799
+	 * @param int  $per_page
2800
+	 * @param int  $current_page
2801
+	 * @param bool $count
2802
+	 * @return EE_Base_Class[]|EE_Term_Taxonomy[]|int
2803
+	 * @throws EE_Error
2804
+	 * @throws InvalidArgumentException
2805
+	 * @throws InvalidDataTypeException
2806
+	 * @throws InvalidInterfaceException
2807
+	 */
2808
+	public function get_categories($per_page = 10, $current_page = 1, $count = false)
2809
+	{
2810
+		// testing term stuff
2811
+		$orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'Term.term_id';
2812
+		$order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
2813
+		$limit = ($current_page - 1) * $per_page;
2814
+		$where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2815
+		if (isset($this->_req_data['s'])) {
2816
+			$sstr = '%' . $this->_req_data['s'] . '%';
2817
+			$where['OR'] = array(
2818
+				'Term.name'   => array('LIKE', $sstr),
2819
+				'description' => array('LIKE', $sstr),
2820
+			);
2821
+		}
2822
+		$query_params = array(
2823
+			$where,
2824
+			'order_by'   => array($orderby => $order),
2825
+			'limit'      => $limit . ',' . $per_page,
2826
+			'force_join' => array('Term'),
2827
+		);
2828
+		$categories = $count
2829
+			? EEM_Term_Taxonomy::instance()->count($query_params, 'term_id')
2830
+			: EEM_Term_Taxonomy::instance()->get_all($query_params);
2831
+		return $categories;
2832
+	}
2833
+
2834
+	/* end category stuff */
2835
+	/**************/
2836
+
2837
+
2838
+	/**
2839
+	 * Callback for the `ee_save_timezone_setting` ajax action.
2840
+	 *
2841
+	 * @throws EE_Error
2842
+	 * @throws InvalidArgumentException
2843
+	 * @throws InvalidDataTypeException
2844
+	 * @throws InvalidInterfaceException
2845
+	 */
2846
+	public function save_timezonestring_setting()
2847
+	{
2848
+		$timezone_string = isset($this->_req_data['timezone_selected'])
2849
+			? $this->_req_data['timezone_selected']
2850
+			: '';
2851
+		if (empty($timezone_string) || ! EEH_DTT_Helper::validate_timezone($timezone_string, false)) {
2852
+			EE_Error::add_error(
2853
+				esc_html__('An invalid timezone string submitted.', 'event_espresso'),
2854
+				__FILE__,
2855
+				__FUNCTION__,
2856
+				__LINE__
2857
+			);
2858
+			$this->_template_args['error'] = true;
2859
+			$this->_return_json();
2860
+		}
2861
+
2862
+		update_option('timezone_string', $timezone_string);
2863
+		EE_Error::add_success(
2864
+			esc_html__('Your timezone string was updated.', 'event_espresso')
2865
+		);
2866
+		$this->_template_args['success'] = true;
2867
+		$this->_return_json(true, array('action' => 'create_new'));
2868
+	}
2869 2869
 }
Please login to merge, or discard this patch.
Spacing   +68 added lines, -68 removed lines patch added patch discarded remove patch
@@ -502,9 +502,9 @@  discard block
 block discarded – undo
502 502
         ];
503 503
         // only load EE_Event_Editor_Decaf_Tips if domain is not caffeinated
504 504
         $domain = $this->loader->getShared('EventEspresso\core\domain\Domain');
505
-        if (! $domain->isCaffeinated()) {
505
+        if ( ! $domain->isCaffeinated()) {
506 506
             $this->_page_config['create_new']['qtips'] = ['EE_Event_Editor_Decaf_Tips'];
507
-            $this->_page_config['edit']['qtips'] = ['EE_Event_Editor_Decaf_Tips' ];
507
+            $this->_page_config['edit']['qtips'] = ['EE_Event_Editor_Decaf_Tips'];
508 508
         }
509 509
     }
510 510
 
@@ -561,11 +561,11 @@  discard block
 block discarded – undo
561 561
     {
562 562
         wp_register_style(
563 563
             'events-admin-css',
564
-            EVENTS_ASSETS_URL . 'events-admin-page.css',
564
+            EVENTS_ASSETS_URL.'events-admin-page.css',
565 565
             array(),
566 566
             EVENT_ESPRESSO_VERSION
567 567
         );
568
-        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL . 'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
568
+        wp_register_style('ee-cat-admin', EVENTS_ASSETS_URL.'ee-cat-admin.css', array(), EVENT_ESPRESSO_VERSION);
569 569
         wp_enqueue_style('events-admin-css');
570 570
         wp_enqueue_style('ee-cat-admin');
571 571
         // todo note: we also need to load_scripts_styles per view (i.e. default/view_report/event_details
@@ -573,7 +573,7 @@  discard block
 block discarded – undo
573 573
         // scripts
574 574
         wp_register_script(
575 575
             'event_editor_js',
576
-            EVENTS_ASSETS_URL . 'event_editor.js',
576
+            EVENTS_ASSETS_URL.'event_editor.js',
577 577
             array('ee_admin_js', 'jquery-ui-slider', 'jquery-ui-timepicker-addon'),
578 578
             EVENT_ESPRESSO_VERSION,
579 579
             true
@@ -599,7 +599,7 @@  discard block
 block discarded – undo
599 599
         wp_enqueue_style('espresso-ui-theme');
600 600
         wp_register_style(
601 601
             'event-editor-css',
602
-            EVENTS_ASSETS_URL . 'event-editor.css',
602
+            EVENTS_ASSETS_URL.'event-editor.css',
603 603
             array('ee-admin-css'),
604 604
             EVENT_ESPRESSO_VERSION
605 605
         );
@@ -607,7 +607,7 @@  discard block
 block discarded – undo
607 607
         // scripts
608 608
         wp_register_script(
609 609
             'event-datetime-metabox',
610
-            EVENTS_ASSETS_URL . 'event-datetime-metabox.js',
610
+            EVENTS_ASSETS_URL.'event-datetime-metabox.js',
611 611
             array('event_editor_js', 'ee-datepicker'),
612 612
             EVENT_ESPRESSO_VERSION
613 613
         );
@@ -676,15 +676,15 @@  discard block
 block discarded – undo
676 676
     public function verify_event_edit($event = null, $req_type = '')
677 677
     {
678 678
         // don't need to do this when processing
679
-        if (! empty($req_type)) {
679
+        if ( ! empty($req_type)) {
680 680
             return;
681 681
         }
682 682
         // no event?
683
-        if (! $event instanceof EE_Event) {
683
+        if ( ! $event instanceof EE_Event) {
684 684
             $event = $this->_cpt_model_obj;
685 685
         }
686 686
         // STILL no event?
687
-        if (! $event instanceof EE_Event) {
687
+        if ( ! $event instanceof EE_Event) {
688 688
             return;
689 689
         }
690 690
         $orig_status = $event->status();
@@ -723,7 +723,7 @@  discard block
 block discarded – undo
723 723
             );
724 724
         }
725 725
         // now we need to determine if the event has any tickets on sale.  If not then we dont' show the error
726
-        if (! $event->tickets_on_sale()) {
726
+        if ( ! $event->tickets_on_sale()) {
727 727
             return;
728 728
         }
729 729
         // made it here so show warning
@@ -771,7 +771,7 @@  discard block
 block discarded – undo
771 771
     {
772 772
         $has_timezone_string = get_option('timezone_string');
773 773
         // only nag them about setting their timezone if it's their first event, and they haven't already done it
774
-        if (! $has_timezone_string && ! EEM_Event::instance()->exists(array())) {
774
+        if ( ! $has_timezone_string && ! EEM_Event::instance()->exists(array())) {
775 775
             EE_Error::add_attention(
776 776
                 sprintf(
777 777
                     __(
@@ -855,31 +855,31 @@  discard block
 block discarded – undo
855 855
         $items = apply_filters('FHEE__Events_Admin_Page___event_legend_items__items', $items);
856 856
         $statuses = array(
857 857
             'sold_out_status'  => array(
858
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::sold_out,
858
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::sold_out,
859 859
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::sold_out, false, 'sentence'),
860 860
             ),
861 861
             'active_status'    => array(
862
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::active,
862
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::active,
863 863
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::active, false, 'sentence'),
864 864
             ),
865 865
             'upcoming_status'  => array(
866
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::upcoming,
866
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::upcoming,
867 867
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::upcoming, false, 'sentence'),
868 868
             ),
869 869
             'postponed_status' => array(
870
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::postponed,
870
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::postponed,
871 871
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::postponed, false, 'sentence'),
872 872
             ),
873 873
             'cancelled_status' => array(
874
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::cancelled,
874
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::cancelled,
875 875
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::cancelled, false, 'sentence'),
876 876
             ),
877 877
             'expired_status'   => array(
878
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::expired,
878
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::expired,
879 879
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::expired, false, 'sentence'),
880 880
             ),
881 881
             'inactive_status'  => array(
882
-                'class' => 'ee-status-legend ee-status-legend-' . EE_Datetime::inactive,
882
+                'class' => 'ee-status-legend ee-status-legend-'.EE_Datetime::inactive,
883 883
                 'desc'  => EEH_Template::pretty_status(EE_Datetime::inactive, false, 'sentence'),
884 884
             ),
885 885
         );
@@ -898,7 +898,7 @@  discard block
 block discarded – undo
898 898
      */
899 899
     private function _event_model()
900 900
     {
901
-        if (! $this->_event_model instanceof EEM_Event) {
901
+        if ( ! $this->_event_model instanceof EEM_Event) {
902 902
             $this->_event_model = EE_Registry::instance()->load_model('Event');
903 903
         }
904 904
         return $this->_event_model;
@@ -918,7 +918,7 @@  discard block
 block discarded – undo
918 918
     public function extra_permalink_field_buttons($return, $id, $new_title, $new_slug)
919 919
     {
920 920
         // make sure this is only when editing
921
-        if (! empty($id)) {
921
+        if ( ! empty($id)) {
922 922
             $post = get_post($id);
923 923
             $return .= '<a class="button button-small" onclick="prompt(\'Shortcode:\', jQuery(\'#shortcode\').val()); return false;" href="#"  tabindex="-1">'
924 924
                        . esc_html__('Shortcode', 'event_espresso')
@@ -956,7 +956,7 @@  discard block
 block discarded – undo
956 956
                     'button'
957 957
                 );
958 958
         $this->_template_args['after_list_table']['legend'] = $this->_display_legend($this->_event_legend_items());
959
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
959
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
960 960
             'create_new',
961 961
             'add',
962 962
             array(),
@@ -1116,7 +1116,7 @@  discard block
 block discarded – undo
1116 1116
      */
1117 1117
     protected function _default_venue_update(EE_Event $evtobj, $data)
1118 1118
     {
1119
-        require_once(EE_MODELS . 'EEM_Venue.model.php');
1119
+        require_once(EE_MODELS.'EEM_Venue.model.php');
1120 1120
         $venue_model = EE_Registry::instance()->load_model('Venue');
1121 1121
         $rows_affected = null;
1122 1122
         $venue_id = ! empty($data['venue_id']) ? $data['venue_id'] : null;
@@ -1147,7 +1147,7 @@  discard block
 block discarded – undo
1147 1147
             'status'              => 'publish',
1148 1148
         );
1149 1149
         // if we've got the venue_id then we're just updating the existing venue so let's do that and then get out.
1150
-        if (! empty($venue_id)) {
1150
+        if ( ! empty($venue_id)) {
1151 1151
             $update_where = array($venue_model->primary_key_name() => $venue_id);
1152 1152
             $rows_affected = $venue_model->update($venue_array, array($update_where));
1153 1153
             // 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.
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
                 'DTT_order'     => $row,
1198 1198
             );
1199 1199
             // 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.
1200
-            if (! empty($dtt['DTT_ID'])) {
1200
+            if ( ! empty($dtt['DTT_ID'])) {
1201 1201
                 $DTM = EE_Registry::instance()
1202 1202
                                   ->load_model('Datetime', array($evtobj->get_timezone()))
1203 1203
                                   ->get_one_by_ID($dtt['DTT_ID']);
@@ -1207,7 +1207,7 @@  discard block
 block discarded – undo
1207 1207
                     $DTM->set($field, $value);
1208 1208
                 }
1209 1209
                 // 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.
1210
-                $saved_dtts[ $DTM->ID() ] = $DTM;
1210
+                $saved_dtts[$DTM->ID()] = $DTM;
1211 1211
             } else {
1212 1212
                 $DTM = EE_Registry::instance()->load_class(
1213 1213
                     'Datetime',
@@ -1240,14 +1240,14 @@  discard block
 block discarded – undo
1240 1240
         foreach ($data['edit_tickets'] as $row => $tkt) {
1241 1241
             $incoming_date_formats = array('Y-m-d', 'h:i a');
1242 1242
             $update_prices = false;
1243
-            $ticket_price = isset($data['edit_prices'][ $row ][1]['PRC_amount'])
1244
-                ? $data['edit_prices'][ $row ][1]['PRC_amount'] : 0;
1243
+            $ticket_price = isset($data['edit_prices'][$row][1]['PRC_amount'])
1244
+                ? $data['edit_prices'][$row][1]['PRC_amount'] : 0;
1245 1245
             // trim inputs to ensure any excess whitespace is removed.
1246 1246
             $tkt = array_map('trim', $tkt);
1247 1247
             if (empty($tkt['TKT_start_date'])) {
1248 1248
                 // let's use now in the set timezone.
1249 1249
                 $now = new DateTime('now', new DateTimeZone($evtobj->get_timezone()));
1250
-                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0] . ' ' . $incoming_date_formats[1]);
1250
+                $tkt['TKT_start_date'] = $now->format($incoming_date_formats[0].' '.$incoming_date_formats[1]);
1251 1251
             }
1252 1252
             if (empty($tkt['TKT_end_date'])) {
1253 1253
                 // use the start date of the first datetime
@@ -1282,7 +1282,7 @@  discard block
 block discarded – undo
1282 1282
             // if we have a TKT_ID then we need to get that existing TKT_obj and update it
1283 1283
             // 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.
1284 1284
             // 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.
1285
-            if (! empty($tkt['TKT_ID'])) {
1285
+            if ( ! empty($tkt['TKT_ID'])) {
1286 1286
                 $TKT = EE_Registry::instance()
1287 1287
                                   ->load_model('Ticket', array($evtobj->get_timezone()))
1288 1288
                                   ->get_one_by_ID($tkt['TKT_ID']);
@@ -1322,7 +1322,7 @@  discard block
 block discarded – undo
1322 1322
                         $TKT->set('TKT_deleted', 1);
1323 1323
                         $TKT->save();
1324 1324
                         // make sure this ticket is still recorded in our saved_tkts so we don't run it through the regular trash routine.
1325
-                        $saved_tickets[ $TKT->ID() ] = $TKT;
1325
+                        $saved_tickets[$TKT->ID()] = $TKT;
1326 1326
                         // 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.
1327 1327
                         $TKT = clone $TKT;
1328 1328
                         $TKT->set('TKT_ID', 0);
@@ -1367,9 +1367,9 @@  discard block
 block discarded – undo
1367 1367
             }
1368 1368
             // initially let's add the ticket to the dtt
1369 1369
             $saved_dtt->_add_relation_to($TKT, 'Ticket');
1370
-            $saved_tickets[ $TKT->ID() ] = $TKT;
1370
+            $saved_tickets[$TKT->ID()] = $TKT;
1371 1371
             // add prices to ticket
1372
-            $this->_add_prices_to_ticket($data['edit_prices'][ $row ], $TKT, $update_prices);
1372
+            $this->_add_prices_to_ticket($data['edit_prices'][$row], $TKT, $update_prices);
1373 1373
         }
1374 1374
         // 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.
1375 1375
         $old_tickets = isset($old_tickets[0]) && $old_tickets[0] === '' ? array() : $old_tickets;
@@ -1537,7 +1537,7 @@  discard block
 block discarded – undo
1537 1537
         $publish_box_extra_args['event_editor_overview_add'] = ob_get_clean();
1538 1538
         // load template
1539 1539
         EEH_Template::display_template(
1540
-            EVENTS_TEMPLATE_PATH . 'event_publish_box_extras.template.php',
1540
+            EVENTS_TEMPLATE_PATH.'event_publish_box_extras.template.php',
1541 1541
             $publish_box_extra_args
1542 1542
         );
1543 1543
     }
@@ -1569,7 +1569,7 @@  discard block
 block discarded – undo
1569 1569
     protected function _register_event_editor_meta_boxes()
1570 1570
     {
1571 1571
         $this->verify_cpt_object();
1572
-        if (! EE_Registry::instance()->CFG->admin->useAdvancedEditor()) {
1572
+        if ( ! EE_Registry::instance()->CFG->admin->useAdvancedEditor()) {
1573 1573
             add_meta_box(
1574 1574
                 'espresso_event_editor_tickets',
1575 1575
                 esc_html__('Event Datetime & Ticket', 'event_espresso'),
@@ -1639,7 +1639,7 @@  discard block
 block discarded – undo
1639 1639
                     'default_where_conditions' => 'none',
1640 1640
                 )
1641 1641
             );
1642
-            if (! empty($related_tickets)) {
1642
+            if ( ! empty($related_tickets)) {
1643 1643
                 $template_args['total_ticket_rows'] = count($related_tickets);
1644 1644
                 $row = 0;
1645 1645
                 foreach ($related_tickets as $ticket) {
@@ -1673,7 +1673,7 @@  discard block
 block discarded – undo
1673 1673
         );
1674 1674
         $template = apply_filters(
1675 1675
             'FHEE__Events_Admin_Page__ticket_metabox__template',
1676
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_main.template.php'
1676
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_main.template.php'
1677 1677
         );
1678 1678
         EEH_Template::display_template($template, $template_args);
1679 1679
     }
@@ -1697,7 +1697,7 @@  discard block
 block discarded – undo
1697 1697
     private function _get_ticket_row($ticket, $skeleton = false, $row = 0)
1698 1698
     {
1699 1699
         $template_args = array(
1700
-            'tkt_status_class'    => ' tkt-status-' . $ticket->ticket_status(),
1700
+            'tkt_status_class'    => ' tkt-status-'.$ticket->ticket_status(),
1701 1701
             'tkt_archive_class'   => $ticket->ticket_status() === EE_Ticket::archived && ! $skeleton ? ' tkt-archived'
1702 1702
                 : '',
1703 1703
             'ticketrow'           => $skeleton ? 'TICKETNUM' : $row,
@@ -1709,10 +1709,10 @@  discard block
 block discarded – undo
1709 1709
             'TKT_qty'             => $ticket->get_pretty('TKT_qty', 'input'),
1710 1710
             'edit_ticketrow_name' => $skeleton ? 'TICKETNAMEATTR' : 'edit_tickets',
1711 1711
             'TKT_sold'            => $skeleton ? 0 : $ticket->get('TKT_sold'),
1712
-            'trash_icon'          => ($skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')))
1713
-                                     && (! empty($ticket) && $ticket->get('TKT_sold') === 0)
1712
+            'trash_icon'          => ($skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')))
1713
+                                     && ( ! empty($ticket) && $ticket->get('TKT_sold') === 0)
1714 1714
                 ? 'trash-icon dashicons dashicons-post-trash clickable' : 'ee-lock-icon',
1715
-            'disabled'            => $skeleton || (! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1715
+            'disabled'            => $skeleton || ( ! empty($ticket) && ! $ticket->get('TKT_deleted')) ? ''
1716 1716
                 : ' disabled=disabled',
1717 1717
         );
1718 1718
         $price = $ticket->ID() !== 0
@@ -1739,7 +1739,7 @@  discard block
 block discarded – undo
1739 1739
                     array('order_by' => array('DTT_EVT_start' => 'ASC'))
1740 1740
                 )
1741 1741
                 : null;
1742
-            if (! empty($earliest_dtt)) {
1742
+            if ( ! empty($earliest_dtt)) {
1743 1743
                 $template_args['TKT_end_date'] = $earliest_dtt->get_datetime('DTT_EVT_start', 'Y-m-d', 'h:i a');
1744 1744
             } else {
1745 1745
                 $template_args['TKT_end_date'] = date(
@@ -1751,7 +1751,7 @@  discard block
 block discarded – undo
1751 1751
         $template_args = array_merge($template_args, $price_args);
1752 1752
         $template = apply_filters(
1753 1753
             'FHEE__Events_Admin_Page__get_ticket_row__template',
1754
-            EVENTS_TEMPLATE_PATH . 'event_tickets_metabox_ticket_row.template.php',
1754
+            EVENTS_TEMPLATE_PATH.'event_tickets_metabox_ticket_row.template.php',
1755 1755
             $ticket
1756 1756
         );
1757 1757
         return EEH_Template::display_template($template, $template_args, true);
@@ -1806,7 +1806,7 @@  discard block
 block discarded – undo
1806 1806
             $default_reg_status_values
1807 1807
         );
1808 1808
         EEH_Template::display_template(
1809
-            EVENTS_TEMPLATE_PATH . 'event_registration_options.template.php',
1809
+            EVENTS_TEMPLATE_PATH.'event_registration_options.template.php',
1810 1810
             $template_args
1811 1811
         );
1812 1812
     }
@@ -1836,7 +1836,7 @@  discard block
 block discarded – undo
1836 1836
     {
1837 1837
         $EEME = $this->_event_model();
1838 1838
         $offset = ($current_page - 1) * $per_page;
1839
-        $limit = $count ? null : $offset . ',' . $per_page;
1839
+        $limit = $count ? null : $offset.','.$per_page;
1840 1840
         $orderby = isset($this->_req_data['orderby']) ? $this->_req_data['orderby'] : 'EVT_ID';
1841 1841
         $order = isset($this->_req_data['order']) ? $this->_req_data['order'] : 'DESC';
1842 1842
         if (isset($this->_req_data['month_range'])) {
@@ -1865,7 +1865,7 @@  discard block
 block discarded – undo
1865 1865
         // categories?
1866 1866
         $category = isset($this->_req_data['EVT_CAT']) && $this->_req_data['EVT_CAT'] > 0
1867 1867
             ? $this->_req_data['EVT_CAT'] : null;
1868
-        if (! empty($category)) {
1868
+        if ( ! empty($category)) {
1869 1869
             $where['Term_Taxonomy.taxonomy'] = EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY;
1870 1870
             $where['Term_Taxonomy.term_id'] = $category;
1871 1871
         }
@@ -1873,7 +1873,7 @@  discard block
 block discarded – undo
1873 1873
         $start_formats = EEM_Datetime::instance()->get_formats_for('DTT_EVT_start');
1874 1874
         if (isset($this->_req_data['month_range']) && $this->_req_data['month_range'] !== '') {
1875 1875
             $DateTime = new DateTime(
1876
-                $year_r . '-' . $month_r . '-01 00:00:00',
1876
+                $year_r.'-'.$month_r.'-01 00:00:00',
1877 1877
                 new DateTimeZone('UTC')
1878 1878
             );
1879 1879
             $start = $DateTime->getTimestamp();
@@ -1899,9 +1899,9 @@  discard block
 block discarded – undo
1899 1899
                             ->format(implode(' ', $start_formats));
1900 1900
             $where['Datetime.DTT_EVT_start'] = array('BETWEEN', array($start, $end));
1901 1901
         }
1902
-        if (! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1902
+        if ( ! EE_Registry::instance()->CAP->current_user_can('ee_read_others_events', 'get_events')) {
1903 1903
             $where['EVT_wp_user'] = get_current_user_id();
1904
-        } elseif (! isset($where['status'])
1904
+        } elseif ( ! isset($where['status'])
1905 1905
             && ! EE_Registry::instance()->CAP->current_user_can('ee_read_private_events', 'get_events')
1906 1906
         ) {
1907 1907
             $where['OR'] = array(
@@ -1921,7 +1921,7 @@  discard block
 block discarded – undo
1921 1921
         }
1922 1922
         // search query handling
1923 1923
         if (isset($this->_req_data['s'])) {
1924
-            $search_string = '%' . $this->_req_data['s'] . '%';
1924
+            $search_string = '%'.$this->_req_data['s'].'%';
1925 1925
             $where['OR'] = array(
1926 1926
                 'EVT_name'       => array('LIKE', $search_string),
1927 1927
                 'EVT_desc'       => array('LIKE', $search_string),
@@ -2036,7 +2036,7 @@  discard block
 block discarded – undo
2036 2036
             // clean status
2037 2037
             $event_status = sanitize_key($event_status);
2038 2038
             // grab status
2039
-            if (! empty($event_status)) {
2039
+            if ( ! empty($event_status)) {
2040 2040
                 $success = $this->_change_event_status($EVT_ID, $event_status);
2041 2041
             } else {
2042 2042
                 $success = false;
@@ -2078,7 +2078,7 @@  discard block
 block discarded – undo
2078 2078
         // clean status
2079 2079
         $event_status = sanitize_key($event_status);
2080 2080
         // grab status
2081
-        if (! empty($event_status)) {
2081
+        if ( ! empty($event_status)) {
2082 2082
             $success = true;
2083 2083
             // determine the event id and set to array.
2084 2084
             $EVT_IDs = isset($this->_req_data['EVT_IDs']) ? (array) $this->_req_data['EVT_IDs'] : array();
@@ -2130,7 +2130,7 @@  discard block
 block discarded – undo
2130 2130
     private function _change_event_status($EVT_ID = 0, $event_status = '')
2131 2131
     {
2132 2132
         // grab event id
2133
-        if (! $EVT_ID) {
2133
+        if ( ! $EVT_ID) {
2134 2134
             $msg = esc_html__(
2135 2135
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2136 2136
                 'event_espresso'
@@ -2201,8 +2201,8 @@  discard block
 block discarded – undo
2201 2201
             // get list of events with no prices
2202 2202
             $espresso_no_ticket_prices = get_option('ee_no_ticket_prices', array());
2203 2203
             // remove this event from the list of events with no prices
2204
-            if (isset($espresso_no_ticket_prices[ $EVT_ID ])) {
2205
-                unset($espresso_no_ticket_prices[ $EVT_ID ]);
2204
+            if (isset($espresso_no_ticket_prices[$EVT_ID])) {
2205
+                unset($espresso_no_ticket_prices[$EVT_ID]);
2206 2206
             }
2207 2207
             update_option('ee_no_ticket_prices', $espresso_no_ticket_prices);
2208 2208
         } else {
@@ -2249,7 +2249,7 @@  discard block
 block discarded – undo
2249 2249
                 $results = $this->_permanently_delete_event($EVT_ID);
2250 2250
                 $success = $results !== false ? $success : false;
2251 2251
                 // remove this event from the list of events with no prices
2252
-                unset($espresso_no_ticket_prices[ $EVT_ID ]);
2252
+                unset($espresso_no_ticket_prices[$EVT_ID]);
2253 2253
             } else {
2254 2254
                 $success = false;
2255 2255
                 $msg = esc_html__(
@@ -2281,7 +2281,7 @@  discard block
 block discarded – undo
2281 2281
     private function _permanently_delete_event($EVT_ID = 0)
2282 2282
     {
2283 2283
         // grab event id
2284
-        if (! $EVT_ID) {
2284
+        if ( ! $EVT_ID) {
2285 2285
             $msg = esc_html__(
2286 2286
                 'An error occurred. No Event ID or an invalid Event ID was received.',
2287 2287
                 'event_espresso'
@@ -2289,12 +2289,12 @@  discard block
 block discarded – undo
2289 2289
             EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
2290 2290
             return false;
2291 2291
         }
2292
-        if (! $this->_cpt_model_obj instanceof EE_Event
2292
+        if ( ! $this->_cpt_model_obj instanceof EE_Event
2293 2293
             || $this->_cpt_model_obj->ID() !== $EVT_ID
2294 2294
         ) {
2295 2295
             $this->_cpt_model_obj = EEM_Event::instance()->get_one_by_ID($EVT_ID);
2296 2296
         }
2297
-        if (! $this->_cpt_model_obj instanceof EE_Event) {
2297
+        if ( ! $this->_cpt_model_obj instanceof EE_Event) {
2298 2298
             return false;
2299 2299
         }
2300 2300
         // need to delete related tickets and prices first.
@@ -2316,7 +2316,7 @@  discard block
 block discarded – undo
2316 2316
         }
2317 2317
         // any attached question groups?
2318 2318
         $question_groups = $this->_cpt_model_obj->get_many_related('Question_Group');
2319
-        if (! empty($question_groups)) {
2319
+        if ( ! empty($question_groups)) {
2320 2320
             foreach ($question_groups as $question_group) {
2321 2321
                 $this->_cpt_model_obj->_remove_relation_to($question_group, 'Question_Group');
2322 2322
             }
@@ -2549,7 +2549,7 @@  discard block
 block discarded – undo
2549 2549
                                                 . esc_html__(
2550 2550
                                                     '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.',
2551 2551
                                                     'event_espresso'
2552
-                                                ) . '</strong>';
2552
+                                                ).'</strong>';
2553 2553
         $this->display_admin_caf_preview_page('template_settings_tab');
2554 2554
     }
2555 2555
 
@@ -2569,12 +2569,12 @@  discard block
 block discarded – undo
2569 2569
         // set default category object
2570 2570
         $this->_set_empty_category_object();
2571 2571
         // only set if we've got an id
2572
-        if (! isset($this->_req_data['EVT_CAT_ID'])) {
2572
+        if ( ! isset($this->_req_data['EVT_CAT_ID'])) {
2573 2573
             return;
2574 2574
         }
2575 2575
         $category_id = absint($this->_req_data['EVT_CAT_ID']);
2576 2576
         $term = get_term($category_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2577
-        if (! empty($term)) {
2577
+        if ( ! empty($term)) {
2578 2578
             $this->_category->category_name = $term->name;
2579 2579
             $this->_category->category_identifier = $term->slug;
2580 2580
             $this->_category->category_desc = $term->description;
@@ -2606,7 +2606,7 @@  discard block
 block discarded – undo
2606 2606
     {
2607 2607
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
2608 2608
         $this->_search_btn_label = esc_html__('Categories', 'event_espresso');
2609
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
2609
+        $this->_admin_page_title .= ' '.$this->get_action_link_or_button(
2610 2610
             'add_category',
2611 2611
             'add_category',
2612 2612
             array(),
@@ -2689,7 +2689,7 @@  discard block
 block discarded – undo
2689 2689
             'disable'                  => '',
2690 2690
             'disabled_message'         => false,
2691 2691
         );
2692
-        $template = EVENTS_TEMPLATE_PATH . 'event_category_details.template.php';
2692
+        $template = EVENTS_TEMPLATE_PATH.'event_category_details.template.php';
2693 2693
         return EEH_Template::display_template($template, $template_args, true);
2694 2694
     }
2695 2695
 
@@ -2778,7 +2778,7 @@  discard block
 block discarded – undo
2778 2778
         $insert_ids = $update
2779 2779
             ? wp_update_term($cat_id, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args)
2780 2780
             : wp_insert_term($category_name, EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY, $term_args);
2781
-        if (! is_array($insert_ids)) {
2781
+        if ( ! is_array($insert_ids)) {
2782 2782
             $msg = esc_html__(
2783 2783
                 'An error occurred and the category has not been saved to the database.',
2784 2784
                 'event_espresso'
@@ -2813,7 +2813,7 @@  discard block
 block discarded – undo
2813 2813
         $limit = ($current_page - 1) * $per_page;
2814 2814
         $where = array('taxonomy' => EEM_CPT_Base::EVENT_CATEGORY_TAXONOMY);
2815 2815
         if (isset($this->_req_data['s'])) {
2816
-            $sstr = '%' . $this->_req_data['s'] . '%';
2816
+            $sstr = '%'.$this->_req_data['s'].'%';
2817 2817
             $where['OR'] = array(
2818 2818
                 'Term.name'   => array('LIKE', $sstr),
2819 2819
                 'description' => array('LIKE', $sstr),
@@ -2822,7 +2822,7 @@  discard block
 block discarded – undo
2822 2822
         $query_params = array(
2823 2823
             $where,
2824 2824
             'order_by'   => array($orderby => $order),
2825
-            'limit'      => $limit . ',' . $per_page,
2825
+            'limit'      => $limit.','.$per_page,
2826 2826
             'force_join' => array('Term'),
2827 2827
         );
2828 2828
         $categories = $count
Please login to merge, or discard this patch.