Completed
Branch BUG-10911-php-7.2 (ef442d)
by
unknown
104:08 queued 92:42
created
core/services/notifications/PersistentAdminNoticeManager.php 2 patches
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -86,7 +86,7 @@  discard block
 block discarded – undo
86 86
      */
87 87
     private function setReturnUrl($return_url)
88 88
     {
89
-        if (! is_string($return_url)) {
89
+        if ( ! is_string($return_url)) {
90 90
             throw new InvalidDataTypeException('$return_url', $return_url, 'string');
91 91
         }
92 92
         $this->return_url = $return_url;
@@ -103,7 +103,7 @@  discard block
 block discarded – undo
103 103
      */
104 104
     protected function getPersistentAdminNoticeCollection()
105 105
     {
106
-        if (! $this->notice_collection instanceof Collection) {
106
+        if ( ! $this->notice_collection instanceof Collection) {
107 107
             $this->notice_collection = new Collection(
108 108
                 'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
109 109
             );
@@ -127,7 +127,7 @@  discard block
 block discarded – undo
127 127
     {
128 128
         $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
129 129
         // \EEH_Debug_Tools::printr($persistent_admin_notices, '$persistent_admin_notices', __FILE__, __LINE__);
130
-        if (! empty($persistent_admin_notices)) {
130
+        if ( ! empty($persistent_admin_notices)) {
131 131
             foreach ($persistent_admin_notices as $name => $details) {
132 132
                 if (is_array($details)) {
133 133
                     if (
@@ -166,7 +166,7 @@  discard block
 block discarded – undo
166 166
                         $this->notice_collection->add(
167 167
                             new PersistentAdminNotice(
168 168
                                 $name,
169
-                                (string)$details,
169
+                                (string) $details,
170 170
                                 false,
171 171
                                 '',
172 172
                                 '',
@@ -244,14 +244,14 @@  discard block
 block discarded – undo
244 244
     {
245 245
         wp_register_script(
246 246
             'espresso_core',
247
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
247
+            EE_GLOBAL_ASSETS_URL.'scripts/espresso_core.js',
248 248
             array('jquery'),
249 249
             EVENT_ESPRESSO_VERSION,
250 250
             true
251 251
         );
252 252
         wp_register_script(
253 253
             'ee_error_js',
254
-            EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
254
+            EE_GLOBAL_ASSETS_URL.'scripts/EE_Error.js',
255 255
             array('espresso_core'),
256 256
             EVENT_ESPRESSO_VERSION,
257 257
             true
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
         // used in template
284 284
         $persistent_admin_notice_name    = $persistent_admin_notice->getName();
285 285
         $persistent_admin_notice_message = $persistent_admin_notice->getMessage();
286
-        require EE_TEMPLATES . DS . 'notifications' . DS . 'persistent_admin_notice.template.php';
286
+        require EE_TEMPLATES.DS.'notifications'.DS.'persistent_admin_notice.template.php';
287 287
     }
288 288
 
289 289
 
@@ -304,7 +304,7 @@  discard block
 block discarded – undo
304 304
     {
305 305
         $pan_name                = $this->request->get('ee_nag_notice', $pan_name);
306 306
         $this->notice_collection = $this->getPersistentAdminNoticeCollection();
307
-        if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
307
+        if ( ! empty($pan_name) && $this->notice_collection->has($pan_name)) {
308 308
             /** @var PersistentAdminNotice $persistent_admin_notice */
309 309
             $persistent_admin_notice = $this->notice_collection->get($pan_name);
310 310
             $persistent_admin_notice->setDismissed(true);
Please login to merge, or discard this patch.
Indentation   +360 added lines, -360 removed lines patch added patch discarded remove patch
@@ -30,366 +30,366 @@
 block discarded – undo
30 30
 class PersistentAdminNoticeManager
31 31
 {
32 32
 
33
-    const WP_OPTION_KEY = 'ee_pers_admin_notices';
34
-
35
-    /**
36
-     * @var Collection|PersistentAdminNotice[] $notice_collection
37
-     */
38
-    private $notice_collection;
39
-
40
-    /**
41
-     * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the
42
-     * persistent admin notice was displayed, and ultimately dismissed from.
43
-     *
44
-     * @type string $return_url
45
-     */
46
-    private $return_url;
47
-
48
-    /**
49
-     * @type CapabilitiesChecker $capabilities_checker
50
-     */
51
-    private $capabilities_checker;
52
-
53
-    /**
54
-     * @type EE_Request $request
55
-     */
56
-    private $request;
57
-
58
-
59
-
60
-    /**
61
-     * CapChecker constructor
62
-     *
63
-     * @param string              $return_url  where to  redirect to after dismissing notices
64
-     * @param CapabilitiesChecker $capabilities_checker
65
-     * @param EE_Request          $request
66
-     * @throws InvalidDataTypeException
67
-     */
68
-    public function __construct($return_url = '', CapabilitiesChecker $capabilities_checker, EE_Request $request)
69
-    {
70
-        $this->setReturnUrl($return_url);
71
-        $this->capabilities_checker = $capabilities_checker;
72
-        $this->request              = $request;
73
-        // setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10,
74
-        // and we want to retrieve and generate any nag notices at the last possible moment
75
-        add_action('admin_notices', array($this, 'displayNotices'), 9);
76
-        add_action('network_admin_notices', array($this, 'displayNotices'), 9);
77
-        add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice'));
78
-        add_action('shutdown', array($this, 'registerAndSaveNotices'), 998);
79
-    }
80
-
81
-
82
-
83
-    /**
84
-     * @param string $return_url
85
-     * @throws InvalidDataTypeException
86
-     */
87
-    private function setReturnUrl($return_url)
88
-    {
89
-        if (! is_string($return_url)) {
90
-            throw new InvalidDataTypeException('$return_url', $return_url, 'string');
91
-        }
92
-        $this->return_url = $return_url;
93
-    }
94
-
95
-
96
-
97
-    /**
98
-     * @return Collection
99
-     * @throws InvalidEntityException
100
-     * @throws InvalidInterfaceException
101
-     * @throws InvalidDataTypeException
102
-     * @throws DomainException
103
-     */
104
-    protected function getPersistentAdminNoticeCollection()
105
-    {
106
-        if (! $this->notice_collection instanceof Collection) {
107
-            $this->notice_collection = new Collection(
108
-                'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
109
-            );
110
-            $this->retrieveStoredNotices();
111
-            $this->registerNotices();
112
-        }
113
-        return $this->notice_collection;
114
-    }
115
-
116
-
117
-
118
-    /**
119
-     * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db
120
-     *
121
-     * @return void
122
-     * @throws InvalidEntityException
123
-     * @throws DomainException
124
-     * @throws InvalidDataTypeException
125
-     */
126
-    protected function retrieveStoredNotices()
127
-    {
128
-        $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
129
-        // \EEH_Debug_Tools::printr($persistent_admin_notices, '$persistent_admin_notices', __FILE__, __LINE__);
130
-        if (! empty($persistent_admin_notices)) {
131
-            foreach ($persistent_admin_notices as $name => $details) {
132
-                if (is_array($details)) {
133
-                    if (
134
-                        ! isset(
135
-                            $details['message'],
136
-                            $details['capability'],
137
-                            $details['cap_context'],
138
-                            $details['dismissed']
139
-                        )
140
-                    ) {
141
-                        throw new DomainException(
142
-                            sprintf(
143
-                                esc_html__(
144
-                                    'The "%1$s" PersistentAdminNotice could not be retrieved from the database.',
145
-                                    'event_espresso'
146
-                                ),
147
-                                $name
148
-                            )
149
-                        );
150
-                    }
151
-                    // new format for nag notices
152
-                    $this->notice_collection->add(
153
-                        new PersistentAdminNotice(
154
-                            $name,
155
-                            $details['message'],
156
-                            false,
157
-                            $details['capability'],
158
-                            $details['cap_context'],
159
-                            $details['dismissed']
160
-                        ),
161
-                        $name
162
-                    );
163
-                } else {
164
-                    try {
165
-                        // old nag notices, that we want to convert to the new format
166
-                        $this->notice_collection->add(
167
-                            new PersistentAdminNotice(
168
-                                $name,
169
-                                (string)$details,
170
-                                false,
171
-                                '',
172
-                                '',
173
-                                empty($details)
174
-                            ),
175
-                            $name
176
-                        );
177
-                    } catch (Exception $e) {
178
-                        EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
179
-                    }
180
-                }
181
-                // each notice will self register when the action hook in registerNotices is triggered
182
-            }
183
-        }
184
-    }
185
-
186
-
187
-
188
-    /**
189
-     * exposes the Persistent Admin Notice Collection via an action
190
-     * so that PersistentAdminNotice objects can be added and/or removed
191
-     * without compromising the actual collection like a filter would
192
-     */
193
-    protected function registerNotices()
194
-    {
195
-        do_action(
196
-            'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices',
197
-            $this->notice_collection
198
-        );
199
-    }
200
-
201
-
202
-
203
-    /**
204
-     * @throws DomainException
205
-     * @throws InvalidClassException
206
-     * @throws InvalidDataTypeException
207
-     * @throws InvalidInterfaceException
208
-     * @throws InvalidEntityException
209
-     */
210
-    public function displayNotices()
211
-    {
212
-        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
213
-        if ($this->notice_collection->hasObjects()) {
214
-            $enqueue_assets = false;
215
-            // and display notices
216
-            foreach ($this->notice_collection as $persistent_admin_notice) {
217
-                /** @var PersistentAdminNotice $persistent_admin_notice */
218
-                // don't display notices that have already been dismissed
219
-                if ($persistent_admin_notice->getDismissed()) {
220
-                    continue;
221
-                }
222
-                try {
223
-                    $this->capabilities_checker->processCapCheck(
224
-                        $persistent_admin_notice->getCapCheck()
225
-                    );
226
-                } catch (InsufficientPermissionsException $e) {
227
-                    // user does not have required cap, so skip to next notice
228
-                    // and just eat the exception - nom nom nom nom
229
-                    continue;
230
-                }
231
-                if ($persistent_admin_notice->getMessage() === '') {
232
-                    continue;
233
-                }
234
-                $this->displayPersistentAdminNotice($persistent_admin_notice);
235
-                $enqueue_assets = true;
236
-            }
237
-            if ($enqueue_assets) {
238
-                $this->enqueueAssets();
239
-            }
240
-        }
241
-    }
242
-
243
-
244
-
245
-    /**
246
-     * does what it's named
247
-     *
248
-     * @return void
249
-     */
250
-    public function enqueueAssets()
251
-    {
252
-        wp_register_script(
253
-            'espresso_core',
254
-            EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
255
-            array('jquery'),
256
-            EVENT_ESPRESSO_VERSION,
257
-            true
258
-        );
259
-        wp_register_script(
260
-            'ee_error_js',
261
-            EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
262
-            array('espresso_core'),
263
-            EVENT_ESPRESSO_VERSION,
264
-            true
265
-        );
266
-        wp_localize_script(
267
-            'ee_error_js',
268
-            'ee_dismiss',
269
-            array(
270
-                'return_url'    => urlencode($this->return_url),
271
-                'ajax_url'      => WP_AJAX_URL,
272
-                'unknown_error' => esc_html__(
273
-                    'An unknown error has occurred on the server while attempting to dismiss this notice.',
274
-                    'event_espresso'
275
-                ),
276
-            )
277
-        );
278
-        wp_enqueue_script('ee_error_js');
279
-    }
280
-
281
-
282
-
283
-    /**
284
-     * displayPersistentAdminNoticeHtml
285
-     *
286
-     * @param  PersistentAdminNotice $persistent_admin_notice
287
-     */
288
-    protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice)
289
-    {
290
-        // used in template
291
-        $persistent_admin_notice_name    = $persistent_admin_notice->getName();
292
-        $persistent_admin_notice_message = $persistent_admin_notice->getMessage();
293
-        require EE_TEMPLATES . DS . 'notifications' . DS . 'persistent_admin_notice.template.php';
294
-    }
295
-
296
-
297
-
298
-    /**
299
-     * dismissNotice
300
-     *
301
-     * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
302
-     * @param bool   $purge    if true, then delete it from the db
303
-     * @param bool   $return   forget all of this AJAX or redirect nonsense, and just return
304
-     * @return void
305
-     * @throws InvalidEntityException
306
-     * @throws InvalidInterfaceException
307
-     * @throws InvalidDataTypeException
308
-     * @throws DomainException
309
-     */
310
-    public function dismissNotice($pan_name = '', $purge = false, $return = false)
311
-    {
312
-        $pan_name                = $this->request->get('ee_nag_notice', $pan_name);
313
-        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
314
-        if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
315
-            /** @var PersistentAdminNotice $persistent_admin_notice */
316
-            $persistent_admin_notice = $this->notice_collection->get($pan_name);
317
-            $persistent_admin_notice->setDismissed(true);
318
-            $persistent_admin_notice->setPurge($purge);
319
-            $this->saveNotices();
320
-        }
321
-        if ($return) {
322
-            return;
323
-        }
324
-        if ($this->request->ajax) {
325
-            // grab any notices and concatenate into string
326
-            echo wp_json_encode(
327
-                array(
328
-                    'errors' => implode('<br />', EE_Error::get_notices(false)),
329
-                )
330
-            );
331
-            exit();
332
-        }
333
-        // save errors to a transient to be displayed on next request (after redirect)
334
-        EE_Error::get_notices(false, true);
335
-        wp_safe_redirect(
336
-            urldecode(
337
-                $this->request->get('return_url', '')
338
-            )
339
-        );
340
-    }
341
-
342
-
343
-
344
-    /**
345
-     * saveNotices
346
-     *
347
-     * @throws DomainException
348
-     * @throws InvalidDataTypeException
349
-     * @throws InvalidInterfaceException
350
-     * @throws InvalidEntityException
351
-     */
352
-    public function saveNotices()
353
-    {
354
-        $this->notice_collection = $this->getPersistentAdminNoticeCollection();
355
-        if ($this->notice_collection->hasObjects()) {
356
-            $persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
357
-            //maybe initialize persistent_admin_notices
358
-            if (empty($persistent_admin_notices)) {
359
-                add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no');
360
-            }
361
-            foreach ($this->notice_collection as $persistent_admin_notice) {
362
-                // are we deleting this notice ?
363
-                if ($persistent_admin_notice->getPurge()) {
364
-                    unset($persistent_admin_notices[$persistent_admin_notice->getName()]);
365
-                } else {
366
-                    /** @var PersistentAdminNotice $persistent_admin_notice */
367
-                    $persistent_admin_notices[$persistent_admin_notice->getName()] = array(
368
-                        'message'     => $persistent_admin_notice->getMessage(),
369
-                        'capability'  => $persistent_admin_notice->getCapability(),
370
-                        'cap_context' => $persistent_admin_notice->getCapContext(),
371
-                        'dismissed'   => $persistent_admin_notice->getDismissed(),
372
-                    );
373
-                }
374
-            }
375
-            update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices);
376
-        }
377
-    }
378
-
379
-
380
-
381
-    /**
382
-     * @throws DomainException
383
-     * @throws InvalidDataTypeException
384
-     * @throws InvalidEntityException
385
-     * @throws InvalidInterfaceException
386
-     */
387
-    public function registerAndSaveNotices()
388
-    {
389
-        $this->getPersistentAdminNoticeCollection();
390
-        $this->registerNotices();
391
-        $this->saveNotices();
392
-    }
33
+	const WP_OPTION_KEY = 'ee_pers_admin_notices';
34
+
35
+	/**
36
+	 * @var Collection|PersistentAdminNotice[] $notice_collection
37
+	 */
38
+	private $notice_collection;
39
+
40
+	/**
41
+	 * if AJAX is not enabled, then the return URL will be used for redirecting back to the admin page where the
42
+	 * persistent admin notice was displayed, and ultimately dismissed from.
43
+	 *
44
+	 * @type string $return_url
45
+	 */
46
+	private $return_url;
47
+
48
+	/**
49
+	 * @type CapabilitiesChecker $capabilities_checker
50
+	 */
51
+	private $capabilities_checker;
52
+
53
+	/**
54
+	 * @type EE_Request $request
55
+	 */
56
+	private $request;
57
+
58
+
59
+
60
+	/**
61
+	 * CapChecker constructor
62
+	 *
63
+	 * @param string              $return_url  where to  redirect to after dismissing notices
64
+	 * @param CapabilitiesChecker $capabilities_checker
65
+	 * @param EE_Request          $request
66
+	 * @throws InvalidDataTypeException
67
+	 */
68
+	public function __construct($return_url = '', CapabilitiesChecker $capabilities_checker, EE_Request $request)
69
+	{
70
+		$this->setReturnUrl($return_url);
71
+		$this->capabilities_checker = $capabilities_checker;
72
+		$this->request              = $request;
73
+		// setup up notices at priority 9 because `EE_Admin::display_admin_notices()` runs at priority 10,
74
+		// and we want to retrieve and generate any nag notices at the last possible moment
75
+		add_action('admin_notices', array($this, 'displayNotices'), 9);
76
+		add_action('network_admin_notices', array($this, 'displayNotices'), 9);
77
+		add_action('wp_ajax_dismiss_ee_nag_notice', array($this, 'dismissNotice'));
78
+		add_action('shutdown', array($this, 'registerAndSaveNotices'), 998);
79
+	}
80
+
81
+
82
+
83
+	/**
84
+	 * @param string $return_url
85
+	 * @throws InvalidDataTypeException
86
+	 */
87
+	private function setReturnUrl($return_url)
88
+	{
89
+		if (! is_string($return_url)) {
90
+			throw new InvalidDataTypeException('$return_url', $return_url, 'string');
91
+		}
92
+		$this->return_url = $return_url;
93
+	}
94
+
95
+
96
+
97
+	/**
98
+	 * @return Collection
99
+	 * @throws InvalidEntityException
100
+	 * @throws InvalidInterfaceException
101
+	 * @throws InvalidDataTypeException
102
+	 * @throws DomainException
103
+	 */
104
+	protected function getPersistentAdminNoticeCollection()
105
+	{
106
+		if (! $this->notice_collection instanceof Collection) {
107
+			$this->notice_collection = new Collection(
108
+				'EventEspresso\core\domain\entities\notifications\PersistentAdminNotice'
109
+			);
110
+			$this->retrieveStoredNotices();
111
+			$this->registerNotices();
112
+		}
113
+		return $this->notice_collection;
114
+	}
115
+
116
+
117
+
118
+	/**
119
+	 * generates PersistentAdminNotice objects for all non-dismissed notices saved to the db
120
+	 *
121
+	 * @return void
122
+	 * @throws InvalidEntityException
123
+	 * @throws DomainException
124
+	 * @throws InvalidDataTypeException
125
+	 */
126
+	protected function retrieveStoredNotices()
127
+	{
128
+		$persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
129
+		// \EEH_Debug_Tools::printr($persistent_admin_notices, '$persistent_admin_notices', __FILE__, __LINE__);
130
+		if (! empty($persistent_admin_notices)) {
131
+			foreach ($persistent_admin_notices as $name => $details) {
132
+				if (is_array($details)) {
133
+					if (
134
+						! isset(
135
+							$details['message'],
136
+							$details['capability'],
137
+							$details['cap_context'],
138
+							$details['dismissed']
139
+						)
140
+					) {
141
+						throw new DomainException(
142
+							sprintf(
143
+								esc_html__(
144
+									'The "%1$s" PersistentAdminNotice could not be retrieved from the database.',
145
+									'event_espresso'
146
+								),
147
+								$name
148
+							)
149
+						);
150
+					}
151
+					// new format for nag notices
152
+					$this->notice_collection->add(
153
+						new PersistentAdminNotice(
154
+							$name,
155
+							$details['message'],
156
+							false,
157
+							$details['capability'],
158
+							$details['cap_context'],
159
+							$details['dismissed']
160
+						),
161
+						$name
162
+					);
163
+				} else {
164
+					try {
165
+						// old nag notices, that we want to convert to the new format
166
+						$this->notice_collection->add(
167
+							new PersistentAdminNotice(
168
+								$name,
169
+								(string)$details,
170
+								false,
171
+								'',
172
+								'',
173
+								empty($details)
174
+							),
175
+							$name
176
+						);
177
+					} catch (Exception $e) {
178
+						EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
179
+					}
180
+				}
181
+				// each notice will self register when the action hook in registerNotices is triggered
182
+			}
183
+		}
184
+	}
185
+
186
+
187
+
188
+	/**
189
+	 * exposes the Persistent Admin Notice Collection via an action
190
+	 * so that PersistentAdminNotice objects can be added and/or removed
191
+	 * without compromising the actual collection like a filter would
192
+	 */
193
+	protected function registerNotices()
194
+	{
195
+		do_action(
196
+			'AHEE__EventEspresso_core_services_notifications_PersistentAdminNoticeManager__registerNotices',
197
+			$this->notice_collection
198
+		);
199
+	}
200
+
201
+
202
+
203
+	/**
204
+	 * @throws DomainException
205
+	 * @throws InvalidClassException
206
+	 * @throws InvalidDataTypeException
207
+	 * @throws InvalidInterfaceException
208
+	 * @throws InvalidEntityException
209
+	 */
210
+	public function displayNotices()
211
+	{
212
+		$this->notice_collection = $this->getPersistentAdminNoticeCollection();
213
+		if ($this->notice_collection->hasObjects()) {
214
+			$enqueue_assets = false;
215
+			// and display notices
216
+			foreach ($this->notice_collection as $persistent_admin_notice) {
217
+				/** @var PersistentAdminNotice $persistent_admin_notice */
218
+				// don't display notices that have already been dismissed
219
+				if ($persistent_admin_notice->getDismissed()) {
220
+					continue;
221
+				}
222
+				try {
223
+					$this->capabilities_checker->processCapCheck(
224
+						$persistent_admin_notice->getCapCheck()
225
+					);
226
+				} catch (InsufficientPermissionsException $e) {
227
+					// user does not have required cap, so skip to next notice
228
+					// and just eat the exception - nom nom nom nom
229
+					continue;
230
+				}
231
+				if ($persistent_admin_notice->getMessage() === '') {
232
+					continue;
233
+				}
234
+				$this->displayPersistentAdminNotice($persistent_admin_notice);
235
+				$enqueue_assets = true;
236
+			}
237
+			if ($enqueue_assets) {
238
+				$this->enqueueAssets();
239
+			}
240
+		}
241
+	}
242
+
243
+
244
+
245
+	/**
246
+	 * does what it's named
247
+	 *
248
+	 * @return void
249
+	 */
250
+	public function enqueueAssets()
251
+	{
252
+		wp_register_script(
253
+			'espresso_core',
254
+			EE_GLOBAL_ASSETS_URL . 'scripts/espresso_core.js',
255
+			array('jquery'),
256
+			EVENT_ESPRESSO_VERSION,
257
+			true
258
+		);
259
+		wp_register_script(
260
+			'ee_error_js',
261
+			EE_GLOBAL_ASSETS_URL . 'scripts/EE_Error.js',
262
+			array('espresso_core'),
263
+			EVENT_ESPRESSO_VERSION,
264
+			true
265
+		);
266
+		wp_localize_script(
267
+			'ee_error_js',
268
+			'ee_dismiss',
269
+			array(
270
+				'return_url'    => urlencode($this->return_url),
271
+				'ajax_url'      => WP_AJAX_URL,
272
+				'unknown_error' => esc_html__(
273
+					'An unknown error has occurred on the server while attempting to dismiss this notice.',
274
+					'event_espresso'
275
+				),
276
+			)
277
+		);
278
+		wp_enqueue_script('ee_error_js');
279
+	}
280
+
281
+
282
+
283
+	/**
284
+	 * displayPersistentAdminNoticeHtml
285
+	 *
286
+	 * @param  PersistentAdminNotice $persistent_admin_notice
287
+	 */
288
+	protected function displayPersistentAdminNotice(PersistentAdminNotice $persistent_admin_notice)
289
+	{
290
+		// used in template
291
+		$persistent_admin_notice_name    = $persistent_admin_notice->getName();
292
+		$persistent_admin_notice_message = $persistent_admin_notice->getMessage();
293
+		require EE_TEMPLATES . DS . 'notifications' . DS . 'persistent_admin_notice.template.php';
294
+	}
295
+
296
+
297
+
298
+	/**
299
+	 * dismissNotice
300
+	 *
301
+	 * @param string $pan_name the name, or key of the Persistent Admin Notice to be dismissed
302
+	 * @param bool   $purge    if true, then delete it from the db
303
+	 * @param bool   $return   forget all of this AJAX or redirect nonsense, and just return
304
+	 * @return void
305
+	 * @throws InvalidEntityException
306
+	 * @throws InvalidInterfaceException
307
+	 * @throws InvalidDataTypeException
308
+	 * @throws DomainException
309
+	 */
310
+	public function dismissNotice($pan_name = '', $purge = false, $return = false)
311
+	{
312
+		$pan_name                = $this->request->get('ee_nag_notice', $pan_name);
313
+		$this->notice_collection = $this->getPersistentAdminNoticeCollection();
314
+		if (! empty($pan_name) && $this->notice_collection->has($pan_name)) {
315
+			/** @var PersistentAdminNotice $persistent_admin_notice */
316
+			$persistent_admin_notice = $this->notice_collection->get($pan_name);
317
+			$persistent_admin_notice->setDismissed(true);
318
+			$persistent_admin_notice->setPurge($purge);
319
+			$this->saveNotices();
320
+		}
321
+		if ($return) {
322
+			return;
323
+		}
324
+		if ($this->request->ajax) {
325
+			// grab any notices and concatenate into string
326
+			echo wp_json_encode(
327
+				array(
328
+					'errors' => implode('<br />', EE_Error::get_notices(false)),
329
+				)
330
+			);
331
+			exit();
332
+		}
333
+		// save errors to a transient to be displayed on next request (after redirect)
334
+		EE_Error::get_notices(false, true);
335
+		wp_safe_redirect(
336
+			urldecode(
337
+				$this->request->get('return_url', '')
338
+			)
339
+		);
340
+	}
341
+
342
+
343
+
344
+	/**
345
+	 * saveNotices
346
+	 *
347
+	 * @throws DomainException
348
+	 * @throws InvalidDataTypeException
349
+	 * @throws InvalidInterfaceException
350
+	 * @throws InvalidEntityException
351
+	 */
352
+	public function saveNotices()
353
+	{
354
+		$this->notice_collection = $this->getPersistentAdminNoticeCollection();
355
+		if ($this->notice_collection->hasObjects()) {
356
+			$persistent_admin_notices = get_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array());
357
+			//maybe initialize persistent_admin_notices
358
+			if (empty($persistent_admin_notices)) {
359
+				add_option(PersistentAdminNoticeManager::WP_OPTION_KEY, array(), '', 'no');
360
+			}
361
+			foreach ($this->notice_collection as $persistent_admin_notice) {
362
+				// are we deleting this notice ?
363
+				if ($persistent_admin_notice->getPurge()) {
364
+					unset($persistent_admin_notices[$persistent_admin_notice->getName()]);
365
+				} else {
366
+					/** @var PersistentAdminNotice $persistent_admin_notice */
367
+					$persistent_admin_notices[$persistent_admin_notice->getName()] = array(
368
+						'message'     => $persistent_admin_notice->getMessage(),
369
+						'capability'  => $persistent_admin_notice->getCapability(),
370
+						'cap_context' => $persistent_admin_notice->getCapContext(),
371
+						'dismissed'   => $persistent_admin_notice->getDismissed(),
372
+					);
373
+				}
374
+			}
375
+			update_option(PersistentAdminNoticeManager::WP_OPTION_KEY, $persistent_admin_notices);
376
+		}
377
+	}
378
+
379
+
380
+
381
+	/**
382
+	 * @throws DomainException
383
+	 * @throws InvalidDataTypeException
384
+	 * @throws InvalidEntityException
385
+	 * @throws InvalidInterfaceException
386
+	 */
387
+	public function registerAndSaveNotices()
388
+	{
389
+		$this->getPersistentAdminNoticeCollection();
390
+		$this->registerNotices();
391
+		$this->saveNotices();
392
+	}
393 393
 
394 394
 
395 395
 }
Please login to merge, or discard this patch.
core/admin/EE_Admin_Page_Loader.core.php 4 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -1,6 +1,5 @@
 block discarded – undo
1 1
 <?php
2 2
 use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
3
-use EventEspresso\core\exceptions\InvalidDataTypeException;
4 3
 
5 4
 if (!defined('EVENT_ESPRESSO_VERSION') )
6 5
 	exit('NO direct script access allowed');
Please login to merge, or discard this patch.
Braces   +2 added lines, -1 removed lines patch added patch discarded remove patch
@@ -2,8 +2,9 @@
 block discarded – undo
2 2
 use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
3 3
 use EventEspresso\core\exceptions\InvalidDataTypeException;
4 4
 
5
-if (!defined('EVENT_ESPRESSO_VERSION') )
5
+if (!defined('EVENT_ESPRESSO_VERSION') ) {
6 6
 	exit('NO direct script access allowed');
7
+}
7 8
 
8 9
 
9 10
 
Please login to merge, or discard this patch.
Indentation   +742 added lines, -742 removed lines patch added patch discarded remove patch
@@ -28,748 +28,748 @@
 block discarded – undo
28 28
 class EE_Admin_Page_Loader
29 29
 {
30 30
 
31
-    /**
32
-     * _installed_pages
33
-     * objects for page_init objects detected and loaded
34
-     *
35
-     * @access private
36
-     * @var \EE_Admin_Page_Init[]
37
-     */
38
-    private $_installed_pages = array();
39
-
40
-
41
-
42
-    /**
43
-     * this is used to hold the registry of menu slugs for all the installed admin pages
44
-     *
45
-     * @var array
46
-     */
47
-    private $_menu_slugs = array();
48
-
49
-
50
-    /**
51
-     * _caffeinated_extends
52
-     * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
53
-     * pieces needed to do so).  This property is defined in the _set_caffeinated method.
54
-     *
55
-     * @var array
56
-     */
57
-    private $_caffeinated_extends = array();
58
-
59
-
60
-
61
-    /**
62
-     * _current_caf_extend_slug
63
-     * This property is used for holding the page slug that is required for referencing the correct
64
-     * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
65
-     *
66
-     * @var array
67
-     */
68
-    private $_current_caf_extend_slug;
69
-
70
-
71
-
72
-    /**
73
-     * _caf_autoloader
74
-     * This property is used for holding an array of folder names of any NEW EE_Admin_Pages found in the
75
-     * caffeinated/new directory.  This array is then used to setup a corresponding dynamic autoloader for these pages
76
-     * classes.
77
-     *
78
-     * @var array
79
-     */
80
-    //	private $_caf_autoloader = array();
81
-    /**
82
-     * _prepped_menu_maps
83
-     * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
84
-     *
85
-     * @since  4.4.0
86
-     * @var EE_Admin_Page_Menu_Map[]
87
-     */
88
-    private $_prepped_menu_maps = array();
89
-
90
-
91
-
92
-    /**
93
-     * _admin_menu_groups
94
-     * array that holds the group headings and details for
95
-     *
96
-     * @access private
97
-     * @var array
98
-     */
99
-    private $_admin_menu_groups = array();
100
-
101
-
102
-
103
-    /**
104
-     * This property will hold the hook file for setting up the filter that does all the connections between admin
105
-     * pages.
106
-     *
107
-     * @var string
108
-     */
109
-    public $hook_file;
110
-
111
-
112
-
113
-    /**
114
-     * constructor
115
-     *
116
-     * @access public
117
-     * @return \EE_Admin_Page_Loader
118
-     */
119
-    public function __construct()
120
-    {
121
-        //load menu_map classes
122
-        EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
123
-        //define the default "groups" for the admin_pages
124
-        $this->_set_menu_groups();
125
-        //let's set default autoloaders.  Note that this just sets autoloaders for root admin files.
126
-        //		spl_autoload_register( array( $this, 'init_autoloaders') );
127
-        //let's do a scan and see what installed pages we have
128
-        $this->_get_installed_pages();
129
-        //set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
130
-        add_action('admin_menu', array($this, 'set_menus'));
131
-        add_action('network_admin_menu', array($this, 'set_network_menus'));
132
-    }
133
-
134
-
135
-
136
-    /**
137
-     * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
138
-     * files in the caffeinated folder.
139
-     *
140
-     * @access private
141
-     * @return void
142
-     */
143
-    private function _define_caffeinated_constants()
144
-    {
145
-        if (! defined('EE_CORE_CAF_ADMIN')) {
146
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
147
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
148
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
149
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
150
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
151
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
152
-        }
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     * _set_menu_groups
159
-     * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
160
-     *
161
-     * @access private
162
-     * @return void
163
-     */
164
-    private function _set_menu_groups()
165
-    {
166
-
167
-        //set array of EE_Admin_Page_Menu_Group objects
168
-        $groups = array(
169
-            'main'       => new EE_Admin_Page_Menu_Group(
170
-                array(
171
-                    'menu_label'   => __('Main', 'event_espresso'),
172
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
173
-                    'menu_slug'    => 'main',
174
-                    'capability'   => 'ee_read_ee',
175
-                    'menu_order'   => 0,
176
-                    'parent_slug'  => 'espresso_events',
177
-                )
178
-            ),
179
-            'management' => new EE_Admin_Page_Menu_Group(
180
-                array(
181
-                    'menu_label'   => __('Management', 'event_espresso'),
182
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
183
-                    'menu_slug'    => 'management',
184
-                    'capability'   => 'ee_read_ee',
185
-                    'menu_order'   => 10,
186
-                    'parent_slug'  => 'espresso_events',
187
-                )
188
-            ),
189
-            'settings'   => new EE_Admin_Page_Menu_Group(
190
-                array(
191
-                    'menu_label'   => __('Settings', 'event_espresso'),
192
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
193
-                    'menu_slug'    => 'settings',
194
-                    'capability'   => 'ee_read_ee',
195
-                    'menu_order'   => 30,
196
-                    'parent_slug'  => 'espresso_events',
197
-                )
198
-            ),
199
-            'templates'  => new EE_Admin_Page_Menu_Group(
200
-                array(
201
-                    'menu_label'   => __('Templates', 'event_espresso'),
202
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
203
-                    'menu_slug'    => 'templates',
204
-                    'capability'   => 'ee_read_ee',
205
-                    'menu_order'   => 40,
206
-                    'parent_slug'  => 'espresso_events',
207
-                )
208
-            ),
209
-            'extras'     => new EE_Admin_Page_Menu_Group(
210
-                array(
211
-                    'menu_label'              => __('Extras', 'event_espresso'),
212
-                    'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
213
-                    'menu_slug'               => 'extras',
214
-                    'capability'              => 'ee_read_ee',
215
-                    'menu_order'              => 50,
216
-                    'parent_slug'             => 'espresso_events',
217
-                    'maintenance_mode_parent' => 'espresso_maintenance_settings',
218
-                )
219
-            ),
220
-            'tools'      => new EE_Admin_Page_Menu_Group(
221
-                array(
222
-                    'menu_label'   => __("Tools", "event_espresso"),
223
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
224
-                    'menu_slug'    => 'tools',
225
-                    'capability'   => 'ee_read_ee',
226
-                    'menu_order'   => 60,
227
-                    'parent_slug'  => 'espresso_events',
228
-                )
229
-            ),
230
-            'addons'     => new EE_Admin_Page_Menu_Group(
231
-                array(
232
-                    'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
233
-                    'menu_label'   => __('Add-ons', 'event_espresso'),
234
-                    'menu_slug'    => 'addons',
235
-                    'capability'   => 'ee_read_ee',
236
-                    'menu_order'   => 20,
237
-                    'parent_slug'  => 'espresso_events',
238
-                )
239
-            ),
240
-        );
241
-        $this->_admin_menu_groups = apply_filters(
242
-            'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
243
-            $groups
244
-        );
245
-    }
246
-
247
-
248
-
249
-    /**
250
-     * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
251
-     * slug.  The other utility with this function is it validates that all the groups are instances of
252
-     * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
253
-     *
254
-     * @since  4.4.0
255
-     * @throws \EE_Error
256
-     * @return EE_Admin_Page_Menu_Group[]
257
-     */
258
-    private function _rearrange_menu_groups()
259
-    {
260
-        $groups = array();
261
-        //first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
262
-        usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
263
-        foreach ($this->_admin_menu_groups as $group) {
264
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
265
-                throw new EE_Error(
266
-                    sprintf(
267
-                        __(
268
-                            'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
269
-                            'event_espresso'
270
-                        ),
271
-                        print_r($group, true)
272
-                    )
273
-                );
274
-            }
275
-            $groups[$group->menu_slug] = $group;
276
-        }
277
-        return $groups;
278
-    }
279
-
280
-
281
-
282
-    /**
283
-     * _get_installed_pages
284
-     * This just gets the list of installed EE_Admin_pages.
285
-     *
286
-     * @access private
287
-     * @throws EE_Error
288
-     * @return void
289
-     */
290
-    private function _get_installed_pages()
291
-    {
292
-        $installed_refs = array();
293
-        $exclude        = array('assets', 'templates');
294
-        // grab everything in the  admin core directory
295
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
296
-        if ($admin_screens) {
297
-            foreach ($admin_screens as $admin_screen) {
298
-                // files and anything in the exclude array need not apply
299
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
300
-                    // these folders represent the different EE admin pages
301
-                    $installed_refs[basename($admin_screen)] = $admin_screen;
302
-                }
303
-            }
304
-        }
305
-        if (empty($installed_refs)) {
306
-            $error_msg[] = __(
307
-                'There are no EE_Admin pages detected, it looks like EE did not install properly',
308
-                'event_espresso'
309
-            );
310
-            $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
311
-                    __(
312
-                        'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
313
-                        'event_espresso'
314
-                    ),
315
-                    EE_ADMIN_PAGES
316
-                );
317
-            throw new EE_Error(implode('||', $error_msg));
318
-        }
319
-        //this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
320
-        $installed_refs = $this->_set_caffeinated($installed_refs);
321
-        //allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
322
-        $installed_refs             = apply_filters(
323
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
324
-            $installed_refs
325
-        );
326
-        $this->_caffeinated_extends = apply_filters(
327
-            'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
328
-            $this->_caffeinated_extends
329
-        );
330
-        //loop through admin pages and setup the $_installed_pages array.
331
-        $hooks_ref = array();
332
-        foreach ($installed_refs as $page => $path) {
333
-            // set autoloaders for our admin page classes based on included path information
334
-            EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
335
-            // build list of installed pages
336
-            $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
337
-            // verify returned object
338
-            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
339
-                if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
340
-                    continue;
341
-                }
342
-                //skip if in full maintenance mode and maintenance_mode_parent is set
343
-                $maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
344
-                if (empty($maintenance_mode_parent)
345
-                    && EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
346
-                ) {
347
-                    unset($installed_refs[$page]);
348
-                    continue;
349
-                }
350
-                $menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
351
-                $this->_menu_slugs[$menu_slug] = $page;
352
-                //flag for register hooks on extended pages b/c extended pages use the default INIT.
353
-                $extend = false;
354
-                //now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
355
-                if (isset($this->_caffeinated_extends[$page])) {
356
-                    $this->_current_caf_extend_slug = $page;
357
-                    $admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
358
-                    $caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
359
-                    $caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
360
-                    add_filter(
361
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
362
-                        function($path_to_file) use ($caf_path) {
363
-                            return $caf_path;
364
-                        }
365
-                    );
366
-                    add_filter(
367
-                        "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
368
-                        function ($admin_page) use ($caf_admin_page)
369
-                        {
370
-                            return $caf_admin_page;
371
-                        }
372
-                    );
373
-                    $extend = true;
374
-                }
375
-                //let's do the registered hooks
376
-                $extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
377
-                $hooks_ref      = array_merge($hooks_ref, $extended_hooks);
378
-            }
379
-        }
380
-        //the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
381
-        //first make sure we've got unique values
382
-        $hooks_ref = array_unique($hooks_ref);
383
-        //now let's loop and require!
384
-        foreach ($hooks_ref as $path) {
385
-            require_once($path);
386
-        }
387
-        //make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
388
-        global $ee_menu_slugs;
389
-        $ee_menu_slugs = $this->_menu_slugs;
390
-        //we need to loop again to run any early code
391
-        foreach ($installed_refs as $page => $path) {
392
-            if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
393
-                $this->_installed_pages[$page]->do_initial_loads();
394
-            }
395
-        }
396
-        do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
397
-    }
398
-
399
-
400
-
401
-    /**
402
-     * get_admin_page_object
403
-     *
404
-     * @param string $page_slug
405
-     * @return EE_Admin_Page
406
-     */
407
-    public function get_admin_page_object($page_slug = '')
408
-    {
409
-        if (isset($this->_installed_pages[$page_slug])) {
410
-            return $this->_installed_pages[$page_slug]->loaded_page_object();
411
-        }
412
-        return null;
413
-    }
414
-
415
-
416
-
417
-    /**
418
-     * _get_classname_for_admin_page
419
-     * generates an "Admin Page" class based on the directory  name
420
-     *
421
-     * @param $dir_name
422
-     * @return string
423
-     */
424
-    private function _get_classname_for_admin_page($dir_name = '')
425
-    {
426
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
427
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
428
-    }
429
-
430
-
431
-
432
-    /**
433
-     * _get_classname_for_admin_init_page
434
-     * generates an "Admin Page Init" class based on the directory  name
435
-     *
436
-     * @param $dir_name
437
-     * @return string
438
-     */
439
-    private function _get_classname_for_admin_init_page($dir_name = '')
440
-    {
441
-        $class_name = str_replace('_', ' ', strtolower($dir_name));
442
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
443
-    }
444
-
445
-
446
-
447
-    /**
448
-     * _load_admin_page
449
-     * Loads and instantiates page_init object for a single EE_admin page.
450
-     *
451
-     * @param  string $page page_reference
452
-     * @param string  $path
453
-     * @throws EE_Error
454
-     * @return object|bool  return page object if valid, bool false if not.
455
-     */
456
-    private function _load_admin_page($page = '', $path = '')
457
-    {
458
-        $class_name = $this->_get_classname_for_admin_init_page($page);
459
-        EE_Registry::instance()->load_file($path, $class_name, 'core');
460
-        if (! class_exists($class_name)) {
461
-            $inner_error_msg = '<br />' . sprintf(
462
-                    esc_html__(
463
-                        'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
464
-                        'event_espresso'
465
-                    ),
466
-                    '<strong>' . $class_name . '</strong>'
467
-                );
468
-            $error_msg[]     = sprintf(
469
-                __('Something went wrong with loading the %s admin page.', 'event_espresso'),
470
-                $page
471
-            );
472
-            $error_msg[]     = $error_msg[0]
473
-                               . "\r\n"
474
-                               . sprintf(
475
-                                   esc_html__(
476
-                                       'There is no Init class in place for the %s admin page.',
477
-                                       'event_espresso'
478
-                                   ),
479
-                                   $page
480
-                               )
481
-                               . $inner_error_msg;
482
-            throw new EE_Error(implode('||', $error_msg));
483
-        }
484
-        $a = new ReflectionClass($class_name);
485
-        return $a->newInstance();
486
-    }
487
-
488
-
489
-
490
-    /**
491
-     * set_menus
492
-     * This method sets up the menus for EE Admin Pages
493
-     *
494
-     * @access private
495
-     * @return void
496
-     */
497
-    public function set_menus()
498
-    {
499
-        //prep the menu pages (sort, group.)
500
-        $this->_prep_pages();
501
-        foreach ($this->_prepped_menu_maps as $menu_map) {
502
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
503
-                $menu_map->add_menu_page(false);
504
-            }
505
-        }
506
-    }
507
-
508
-
509
-    /**
510
-     * set_network_menus
511
-     * This method sets up the menus for network EE Admin Pages.
512
-     * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
513
-     * are only added to the menu map if they are intended for the admin menu
514
-     *
515
-     * @return void
516
-     */
517
-    public function set_network_menus()
518
-    {
519
-        $this->_prep_pages();
520
-        foreach ($this->_prepped_menu_maps as $menu_map) {
521
-            if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
522
-                $menu_map->add_menu_page(true);
523
-            }
524
-        }
525
-    }
526
-
527
-
528
-
529
-    /**
530
-     * _prep_pages
531
-     * sets the _prepped_menu_maps property
532
-     *
533
-     * @access private
534
-     * @throws EE_Error
535
-     * @return void
536
-     */
537
-    private function _prep_pages()
538
-    {
539
-        $pages_array = array();
540
-        //rearrange _admin_menu_groups to be indexed by group slug.
541
-        $menu_groups = $this->_rearrange_menu_groups();
542
-        foreach ($this->_installed_pages as $page) {
543
-            if ($page instanceof EE_Admin_page_Init) {
544
-                $page_map = $page->get_menu_map();
545
-                //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
546
-                if (is_array($page_map) || empty($page_map)) {
547
-                      new PersistentAdminNotice(
548
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
549
-                        sprintf(
550
-                            __(
551
-                                'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
552
-                                'event_espresso'
553
-                            ),
554
-                            $page->label
555
-                        )
556
-                    );
557
-                    continue;
558
-                }
559
-                //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
560
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
561
-                    throw new EE_Error(
562
-                        sprintf(
563
-                            __(
564
-                                'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
565
-                                'event_espresso'
566
-                            ),
567
-                            $page->label,
568
-                            $page_map
569
-                        )
570
-                    );
571
-                }
572
-                //use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
573
-                if (empty($page_map->maintenance_mode_parent)
574
-                    && EE_Maintenance_Mode::instance()->level()
575
-                       == EE_Maintenance_Mode::level_2_complete_maintenance) {
576
-                    continue;
577
-                }
578
-                //assign to group (remember $page_map has the admin page stored in it).
579
-                $pages_array[$page_map->menu_group][] = $page_map;
580
-            }
581
-        }
582
-        if (empty($pages_array)) {
583
-            throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
584
-        }
585
-        //let's sort the groups, make sure it's a valid group, add header (if to show).
586
-        foreach ($pages_array as $group => $menu_maps) {
587
-            //valid_group?
588
-            if (! array_key_exists($group, $menu_groups)) {
589
-                continue;
590
-            }
591
-            //sort pages.
592
-            usort($menu_maps, array($this, '_sort_menu_maps'));
593
-            //prepend header
594
-            array_unshift($menu_maps, $menu_groups[$group]);
595
-            //reset $pages_array with prepped data
596
-            $pages_array[$group] = $menu_maps;
597
-        }
598
-        //now let's setup the _prepped_menu_maps property
599
-        foreach ($menu_groups as $group => $group_objs) {
600
-            if (isset($pages_array[$group])) {
601
-                $this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
602
-            }
603
-        }/**/
604
-    }
605
-
606
-
607
-    /**
608
-     * This method is the "workhorse" for detecting and setting up caffeinated functionality.
609
-     * In this method there are three checks being done:
610
-     * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
611
-     * array) etc.  (new page sets are found in caffeinated/new/{page})
612
-     * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
613
-     * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
614
-     * Extend_Events_Admin_Page extends Events_Admin_Page.
615
-     * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
616
-     * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
617
-     * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
618
-     * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
619
-     * admin_pages)
620
-     *
621
-     * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
622
-     *                              loaded.
623
-     * @return array
624
-     */
625
-    private function _set_caffeinated($installed_refs)
626
-    {
627
-
628
-        //first let's check if there IS a caffeinated folder. If there is not then lets get out.
629
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
630
-            return $installed_refs;
631
-        }
632
-        $this->_define_caffeinated_constants();
633
-        $exclude = array('tickets');
634
-        //okay let's setup an "New" pages first (we'll return installed refs later)
635
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
636
-        if ($new_admin_screens) {
637
-            foreach ($new_admin_screens as $admin_screen) {
638
-                // files and anything in the exclude array need not apply
639
-                if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
640
-                    // these folders represent the different NEW EE admin pages
641
-                    $installed_refs[basename($admin_screen)] = $admin_screen;
642
-                    // set autoloaders for our admin page classes based on included path information
643
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
644
-                    //					$this->_caf_autoloader[] = array(
645
-                    //						'dir' => 'new',
646
-                    //						'folder' => basename( $admin_screen )
647
-                    //					);
648
-                }
649
-            }
650
-        }
651
-        //let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
652
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
653
-        if ($extends) {
654
-            foreach ($extends as $extend) {
655
-                if (is_dir($extend)) {
656
-                    $extend_ref = basename($extend);
657
-                    //now let's make sure there is a file that matches the expected format
658
-                    $filename                                              = str_replace(
659
-                        ' ',
660
-                        '_',
661
-                        ucwords(
662
-                            str_replace(
663
-                                '_',
664
-                                ' ',
665
-                                $extend_ref
666
-                            )
667
-                        )
668
-                    );
669
-                    $filename                                              = 'Extend_' . $filename . '_Admin_Page';
670
-                    $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
671
-                        array('\\', '/'),
672
-                        DS,
673
-                        EE_CORE_CAF_ADMIN
674
-                        . 'extend'
675
-                        . DS
676
-                        . $extend_ref
677
-                        . DS
678
-                        . $filename
679
-                        . '.core.php'
680
-                    );
681
-                    $this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
682
-                    // set autoloaders for our admin page classes based on included path information
683
-                    EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
684
-                    //					$this->_caf_autoloader[] = array(
685
-                    //						'dir' => 'extend',
686
-                    //						'folder' => $extend_ref
687
-                    //					);
688
-                }
689
-            }
690
-        }
691
-        //let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
692
-        $ee_admin_hooks = array();
693
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
694
-        if ($hooks) {
695
-            foreach ($hooks as $hook) {
696
-                if (is_readable($hook)) {
697
-                    require_once $hook;
698
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
699
-                    $classname = str_replace('.class.php', '', $classname);
700
-                    if (class_exists($classname)) {
701
-                        $a                = new ReflectionClass($classname);
702
-                        $ee_admin_hooks[] = $a->newInstance();
703
-                    }
704
-                }
705
-            }
706
-        }/**/
707
-        $ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
708
-        return $installed_refs;
709
-    }
710
-
711
-
712
-
713
-
714
-
715
-    /**
716
-     * Initial autoloader registration
717
-     * This just sets up the autoloader for the root admin files
718
-     *
719
-     * @param  string $className incoming classname to check for autoload
720
-     * @return void
721
-     */
722
-    //	public function init_autoloaders( $className ) {
723
-    //		$dir_ref = array(
724
-    //			EE_ADMIN => array('core', 'class')
725
-    //		);
726
-    //		EEH_Autoloader::try_autoload($dir_ref, $className );
727
-    //	}
728
-    /**
729
-     * This method takes care of setting up the autoloader dynamically for any NEW EE_Admin pages found in the
730
-     * caffeinated folders.
731
-     *
732
-     * @access public
733
-     * @param  string $className in coming classname being called
734
-     * @return void
735
-     */
736
-    //	public function caffeinated_autoloaders( $className ) {
737
-    //		//let's setup an array of paths to check (for each subsystem)
738
-    //		$dir_ref = array();
739
-    //		foreach ( $this->_caf_autoloader as $pathinfo) {
740
-    //			$dir_ref[ EE_CORE_CAF_ADMIN . $pathinfo['dir'] . DS . $pathinfo['folder'] . DS] = array('core', 'class');
741
-    //		}
742
-    //
743
-    //		EEH_Autoloader::try_autoload($dir_ref, $className );
744
-    //	}
745
-    /**
746
-     * Utility method for sorting the _menu_maps (callback for usort php function)
747
-     *
748
-     * @since  4.4.0
749
-     * @param  EE_Admin_Page_Menu_Map $a menu_map object
750
-     * @param  EE_Admin_Page_Menu_Map $b being compared to
751
-     * @return int    sort order
752
-     */
753
-    private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
754
-    {
755
-        if ($a->menu_order == $b->menu_order) {
756
-            return 0;
757
-        }
758
-        return ($a->menu_order < $b->menu_order) ? -1 : 1;
759
-    }
760
-
761
-
762
-
763
-    /**
764
-     * _default_header_link
765
-     * This is just a dummy method to use with header submenu items
766
-     *
767
-     * @return bool false
768
-     */
769
-    public function _default_header_link()
770
-    {
771
-        return false;
772
-    }
31
+	/**
32
+	 * _installed_pages
33
+	 * objects for page_init objects detected and loaded
34
+	 *
35
+	 * @access private
36
+	 * @var \EE_Admin_Page_Init[]
37
+	 */
38
+	private $_installed_pages = array();
39
+
40
+
41
+
42
+	/**
43
+	 * this is used to hold the registry of menu slugs for all the installed admin pages
44
+	 *
45
+	 * @var array
46
+	 */
47
+	private $_menu_slugs = array();
48
+
49
+
50
+	/**
51
+	 * _caffeinated_extends
52
+	 * This array is the generated configuration array for which core EE_Admin pages are extended (and the bits and
53
+	 * pieces needed to do so).  This property is defined in the _set_caffeinated method.
54
+	 *
55
+	 * @var array
56
+	 */
57
+	private $_caffeinated_extends = array();
58
+
59
+
60
+
61
+	/**
62
+	 * _current_caf_extend_slug
63
+	 * This property is used for holding the page slug that is required for referencing the correct
64
+	 * _caffeinated_extends index when the corresponding core child EE_Admin_Page_init hooks are executed.
65
+	 *
66
+	 * @var array
67
+	 */
68
+	private $_current_caf_extend_slug;
69
+
70
+
71
+
72
+	/**
73
+	 * _caf_autoloader
74
+	 * This property is used for holding an array of folder names of any NEW EE_Admin_Pages found in the
75
+	 * caffeinated/new directory.  This array is then used to setup a corresponding dynamic autoloader for these pages
76
+	 * classes.
77
+	 *
78
+	 * @var array
79
+	 */
80
+	//	private $_caf_autoloader = array();
81
+	/**
82
+	 * _prepped_menu_maps
83
+	 * This is the prepared array of EE_Admin_Page_Menu_Maps for adding to the admin_menu.
84
+	 *
85
+	 * @since  4.4.0
86
+	 * @var EE_Admin_Page_Menu_Map[]
87
+	 */
88
+	private $_prepped_menu_maps = array();
89
+
90
+
91
+
92
+	/**
93
+	 * _admin_menu_groups
94
+	 * array that holds the group headings and details for
95
+	 *
96
+	 * @access private
97
+	 * @var array
98
+	 */
99
+	private $_admin_menu_groups = array();
100
+
101
+
102
+
103
+	/**
104
+	 * This property will hold the hook file for setting up the filter that does all the connections between admin
105
+	 * pages.
106
+	 *
107
+	 * @var string
108
+	 */
109
+	public $hook_file;
110
+
111
+
112
+
113
+	/**
114
+	 * constructor
115
+	 *
116
+	 * @access public
117
+	 * @return \EE_Admin_Page_Loader
118
+	 */
119
+	public function __construct()
120
+	{
121
+		//load menu_map classes
122
+		EE_Registry::instance()->load_file(EE_ADMIN, 'EE_Admin_Page_Menu_Map', 'core');
123
+		//define the default "groups" for the admin_pages
124
+		$this->_set_menu_groups();
125
+		//let's set default autoloaders.  Note that this just sets autoloaders for root admin files.
126
+		//		spl_autoload_register( array( $this, 'init_autoloaders') );
127
+		//let's do a scan and see what installed pages we have
128
+		$this->_get_installed_pages();
129
+		//set menus (has to be done on every load - we're not actually loading the page just setting the menus and where they point to).
130
+		add_action('admin_menu', array($this, 'set_menus'));
131
+		add_action('network_admin_menu', array($this, 'set_network_menus'));
132
+	}
133
+
134
+
135
+
136
+	/**
137
+	 * When caffeinated system is detected, this method is called to setup the caffeinated directory constants used by
138
+	 * files in the caffeinated folder.
139
+	 *
140
+	 * @access private
141
+	 * @return void
142
+	 */
143
+	private function _define_caffeinated_constants()
144
+	{
145
+		if (! defined('EE_CORE_CAF_ADMIN')) {
146
+			define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
147
+			define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
148
+			define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
149
+			define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
150
+			define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
151
+			define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
152
+		}
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 * _set_menu_groups
159
+	 * sets the filterable _admin_menu_groups property (list of various "groupings" within the EE admin menu array)
160
+	 *
161
+	 * @access private
162
+	 * @return void
163
+	 */
164
+	private function _set_menu_groups()
165
+	{
166
+
167
+		//set array of EE_Admin_Page_Menu_Group objects
168
+		$groups = array(
169
+			'main'       => new EE_Admin_Page_Menu_Group(
170
+				array(
171
+					'menu_label'   => __('Main', 'event_espresso'),
172
+					'show_on_menu' => EE_Admin_Page_Menu_Map::NONE,
173
+					'menu_slug'    => 'main',
174
+					'capability'   => 'ee_read_ee',
175
+					'menu_order'   => 0,
176
+					'parent_slug'  => 'espresso_events',
177
+				)
178
+			),
179
+			'management' => new EE_Admin_Page_Menu_Group(
180
+				array(
181
+					'menu_label'   => __('Management', 'event_espresso'),
182
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
183
+					'menu_slug'    => 'management',
184
+					'capability'   => 'ee_read_ee',
185
+					'menu_order'   => 10,
186
+					'parent_slug'  => 'espresso_events',
187
+				)
188
+			),
189
+			'settings'   => new EE_Admin_Page_Menu_Group(
190
+				array(
191
+					'menu_label'   => __('Settings', 'event_espresso'),
192
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
193
+					'menu_slug'    => 'settings',
194
+					'capability'   => 'ee_read_ee',
195
+					'menu_order'   => 30,
196
+					'parent_slug'  => 'espresso_events',
197
+				)
198
+			),
199
+			'templates'  => new EE_Admin_Page_Menu_Group(
200
+				array(
201
+					'menu_label'   => __('Templates', 'event_espresso'),
202
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
203
+					'menu_slug'    => 'templates',
204
+					'capability'   => 'ee_read_ee',
205
+					'menu_order'   => 40,
206
+					'parent_slug'  => 'espresso_events',
207
+				)
208
+			),
209
+			'extras'     => new EE_Admin_Page_Menu_Group(
210
+				array(
211
+					'menu_label'              => __('Extras', 'event_espresso'),
212
+					'show_on_menu'            => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
213
+					'menu_slug'               => 'extras',
214
+					'capability'              => 'ee_read_ee',
215
+					'menu_order'              => 50,
216
+					'parent_slug'             => 'espresso_events',
217
+					'maintenance_mode_parent' => 'espresso_maintenance_settings',
218
+				)
219
+			),
220
+			'tools'      => new EE_Admin_Page_Menu_Group(
221
+				array(
222
+					'menu_label'   => __("Tools", "event_espresso"),
223
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_ADMIN_ONLY,
224
+					'menu_slug'    => 'tools',
225
+					'capability'   => 'ee_read_ee',
226
+					'menu_order'   => 60,
227
+					'parent_slug'  => 'espresso_events',
228
+				)
229
+			),
230
+			'addons'     => new EE_Admin_Page_Menu_Group(
231
+				array(
232
+					'show_on_menu' => EE_Admin_Page_Menu_Map::BLOG_AND_NETWORK_ADMIN,
233
+					'menu_label'   => __('Add-ons', 'event_espresso'),
234
+					'menu_slug'    => 'addons',
235
+					'capability'   => 'ee_read_ee',
236
+					'menu_order'   => 20,
237
+					'parent_slug'  => 'espresso_events',
238
+				)
239
+			),
240
+		);
241
+		$this->_admin_menu_groups = apply_filters(
242
+			'FHEE__EE_Admin_Page_Loader___set_menu_groups__admin_menu_groups',
243
+			$groups
244
+		);
245
+	}
246
+
247
+
248
+
249
+	/**
250
+	 * This takes all the groups in the _admin_menu_groups array and returns the array indexed by group
251
+	 * slug.  The other utility with this function is it validates that all the groups are instances of
252
+	 * EE_Admin_Page_Menu_Group (cause some invalid things might have slipped in via addons).
253
+	 *
254
+	 * @since  4.4.0
255
+	 * @throws \EE_Error
256
+	 * @return EE_Admin_Page_Menu_Group[]
257
+	 */
258
+	private function _rearrange_menu_groups()
259
+	{
260
+		$groups = array();
261
+		//first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
262
+		usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
263
+		foreach ($this->_admin_menu_groups as $group) {
264
+			if (! $group instanceof EE_Admin_Page_Menu_Group) {
265
+				throw new EE_Error(
266
+					sprintf(
267
+						__(
268
+							'Unable to continue sorting the menu groups array because there is an invalid value for the menu groups.  All values in this array are required to be a EE_Admin_Page_Menu_Group object.  Instead there was: %s',
269
+							'event_espresso'
270
+						),
271
+						print_r($group, true)
272
+					)
273
+				);
274
+			}
275
+			$groups[$group->menu_slug] = $group;
276
+		}
277
+		return $groups;
278
+	}
279
+
280
+
281
+
282
+	/**
283
+	 * _get_installed_pages
284
+	 * This just gets the list of installed EE_Admin_pages.
285
+	 *
286
+	 * @access private
287
+	 * @throws EE_Error
288
+	 * @return void
289
+	 */
290
+	private function _get_installed_pages()
291
+	{
292
+		$installed_refs = array();
293
+		$exclude        = array('assets', 'templates');
294
+		// grab everything in the  admin core directory
295
+		$admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
296
+		if ($admin_screens) {
297
+			foreach ($admin_screens as $admin_screen) {
298
+				// files and anything in the exclude array need not apply
299
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
300
+					// these folders represent the different EE admin pages
301
+					$installed_refs[basename($admin_screen)] = $admin_screen;
302
+				}
303
+			}
304
+		}
305
+		if (empty($installed_refs)) {
306
+			$error_msg[] = __(
307
+				'There are no EE_Admin pages detected, it looks like EE did not install properly',
308
+				'event_espresso'
309
+			);
310
+			$error_msg[] = $error_msg[0] . "\r\n" . sprintf(
311
+					__(
312
+						'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
313
+						'event_espresso'
314
+					),
315
+					EE_ADMIN_PAGES
316
+				);
317
+			throw new EE_Error(implode('||', $error_msg));
318
+		}
319
+		//this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
320
+		$installed_refs = $this->_set_caffeinated($installed_refs);
321
+		//allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
322
+		$installed_refs             = apply_filters(
323
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
324
+			$installed_refs
325
+		);
326
+		$this->_caffeinated_extends = apply_filters(
327
+			'FHEE__EE_Admin_Page_Loader___get_installed_pages__caffeinated_extends',
328
+			$this->_caffeinated_extends
329
+		);
330
+		//loop through admin pages and setup the $_installed_pages array.
331
+		$hooks_ref = array();
332
+		foreach ($installed_refs as $page => $path) {
333
+			// set autoloaders for our admin page classes based on included path information
334
+			EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($path);
335
+			// build list of installed pages
336
+			$this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
337
+			// verify returned object
338
+			if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
339
+				if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
340
+					continue;
341
+				}
342
+				//skip if in full maintenance mode and maintenance_mode_parent is set
343
+				$maintenance_mode_parent = $this->_installed_pages[$page]->get_menu_map()->maintenance_mode_parent;
344
+				if (empty($maintenance_mode_parent)
345
+					&& EE_Maintenance_Mode::instance()->level() === EE_Maintenance_Mode::level_2_complete_maintenance
346
+				) {
347
+					unset($installed_refs[$page]);
348
+					continue;
349
+				}
350
+				$menu_slug = $this->_installed_pages[$page]->get_menu_map()->menu_slug;
351
+				$this->_menu_slugs[$menu_slug] = $page;
352
+				//flag for register hooks on extended pages b/c extended pages use the default INIT.
353
+				$extend = false;
354
+				//now that we've got the admin_init objects... lets see if there are any caffeinated pages extending the originals.  If there are then let's hook into the init admin filter and load our extend instead.
355
+				if (isset($this->_caffeinated_extends[$page])) {
356
+					$this->_current_caf_extend_slug = $page;
357
+					$admin_page_name = $this->_installed_pages[$page]->get_admin_page_name();
358
+					$caf_path = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['path'];
359
+					$caf_admin_page = $this->_caffeinated_extends[$this->_current_caf_extend_slug]['admin_page'];
360
+					add_filter(
361
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__path_to_file__{$menu_slug}_{$admin_page_name}",
362
+						function($path_to_file) use ($caf_path) {
363
+							return $caf_path;
364
+						}
365
+					);
366
+					add_filter(
367
+						"FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
368
+						function ($admin_page) use ($caf_admin_page)
369
+						{
370
+							return $caf_admin_page;
371
+						}
372
+					);
373
+					$extend = true;
374
+				}
375
+				//let's do the registered hooks
376
+				$extended_hooks = $this->_installed_pages[$page]->register_hooks($extend);
377
+				$hooks_ref      = array_merge($hooks_ref, $extended_hooks);
378
+			}
379
+		}
380
+		//the hooks_ref is all the pages where we have $extended _Hooks files that will extend a class in a different folder.  So we want to make sure we load the file for the parent.
381
+		//first make sure we've got unique values
382
+		$hooks_ref = array_unique($hooks_ref);
383
+		//now let's loop and require!
384
+		foreach ($hooks_ref as $path) {
385
+			require_once($path);
386
+		}
387
+		//make sure we have menu slugs global setup. Used in EE_Admin_Page->page_setup() to ensure we don't do a full class load for an admin page that isn't requested.
388
+		global $ee_menu_slugs;
389
+		$ee_menu_slugs = $this->_menu_slugs;
390
+		//we need to loop again to run any early code
391
+		foreach ($installed_refs as $page => $path) {
392
+			if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
393
+				$this->_installed_pages[$page]->do_initial_loads();
394
+			}
395
+		}
396
+		do_action('AHEE__EE_Admin_Page_Loader___get_installed_pages_loaded', $this->_installed_pages);
397
+	}
398
+
399
+
400
+
401
+	/**
402
+	 * get_admin_page_object
403
+	 *
404
+	 * @param string $page_slug
405
+	 * @return EE_Admin_Page
406
+	 */
407
+	public function get_admin_page_object($page_slug = '')
408
+	{
409
+		if (isset($this->_installed_pages[$page_slug])) {
410
+			return $this->_installed_pages[$page_slug]->loaded_page_object();
411
+		}
412
+		return null;
413
+	}
414
+
415
+
416
+
417
+	/**
418
+	 * _get_classname_for_admin_page
419
+	 * generates an "Admin Page" class based on the directory  name
420
+	 *
421
+	 * @param $dir_name
422
+	 * @return string
423
+	 */
424
+	private function _get_classname_for_admin_page($dir_name = '')
425
+	{
426
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
427
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
428
+	}
429
+
430
+
431
+
432
+	/**
433
+	 * _get_classname_for_admin_init_page
434
+	 * generates an "Admin Page Init" class based on the directory  name
435
+	 *
436
+	 * @param $dir_name
437
+	 * @return string
438
+	 */
439
+	private function _get_classname_for_admin_init_page($dir_name = '')
440
+	{
441
+		$class_name = str_replace('_', ' ', strtolower($dir_name));
442
+		return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
443
+	}
444
+
445
+
446
+
447
+	/**
448
+	 * _load_admin_page
449
+	 * Loads and instantiates page_init object for a single EE_admin page.
450
+	 *
451
+	 * @param  string $page page_reference
452
+	 * @param string  $path
453
+	 * @throws EE_Error
454
+	 * @return object|bool  return page object if valid, bool false if not.
455
+	 */
456
+	private function _load_admin_page($page = '', $path = '')
457
+	{
458
+		$class_name = $this->_get_classname_for_admin_init_page($page);
459
+		EE_Registry::instance()->load_file($path, $class_name, 'core');
460
+		if (! class_exists($class_name)) {
461
+			$inner_error_msg = '<br />' . sprintf(
462
+					esc_html__(
463
+						'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
464
+						'event_espresso'
465
+					),
466
+					'<strong>' . $class_name . '</strong>'
467
+				);
468
+			$error_msg[]     = sprintf(
469
+				__('Something went wrong with loading the %s admin page.', 'event_espresso'),
470
+				$page
471
+			);
472
+			$error_msg[]     = $error_msg[0]
473
+							   . "\r\n"
474
+							   . sprintf(
475
+								   esc_html__(
476
+									   'There is no Init class in place for the %s admin page.',
477
+									   'event_espresso'
478
+								   ),
479
+								   $page
480
+							   )
481
+							   . $inner_error_msg;
482
+			throw new EE_Error(implode('||', $error_msg));
483
+		}
484
+		$a = new ReflectionClass($class_name);
485
+		return $a->newInstance();
486
+	}
487
+
488
+
489
+
490
+	/**
491
+	 * set_menus
492
+	 * This method sets up the menus for EE Admin Pages
493
+	 *
494
+	 * @access private
495
+	 * @return void
496
+	 */
497
+	public function set_menus()
498
+	{
499
+		//prep the menu pages (sort, group.)
500
+		$this->_prep_pages();
501
+		foreach ($this->_prepped_menu_maps as $menu_map) {
502
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
503
+				$menu_map->add_menu_page(false);
504
+			}
505
+		}
506
+	}
507
+
508
+
509
+	/**
510
+	 * set_network_menus
511
+	 * This method sets up the menus for network EE Admin Pages.
512
+	 * Almost identical to EE_Admin_Page_Loader::set_menus() except pages
513
+	 * are only added to the menu map if they are intended for the admin menu
514
+	 *
515
+	 * @return void
516
+	 */
517
+	public function set_network_menus()
518
+	{
519
+		$this->_prep_pages();
520
+		foreach ($this->_prepped_menu_maps as $menu_map) {
521
+			if (EE_Registry::instance()->CAP->current_user_can($menu_map->capability, $menu_map->menu_slug)) {
522
+				$menu_map->add_menu_page(true);
523
+			}
524
+		}
525
+	}
526
+
527
+
528
+
529
+	/**
530
+	 * _prep_pages
531
+	 * sets the _prepped_menu_maps property
532
+	 *
533
+	 * @access private
534
+	 * @throws EE_Error
535
+	 * @return void
536
+	 */
537
+	private function _prep_pages()
538
+	{
539
+		$pages_array = array();
540
+		//rearrange _admin_menu_groups to be indexed by group slug.
541
+		$menu_groups = $this->_rearrange_menu_groups();
542
+		foreach ($this->_installed_pages as $page) {
543
+			if ($page instanceof EE_Admin_page_Init) {
544
+				$page_map = $page->get_menu_map();
545
+				//if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
546
+				if (is_array($page_map) || empty($page_map)) {
547
+					  new PersistentAdminNotice(
548
+						'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
549
+						sprintf(
550
+							__(
551
+								'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
552
+								'event_espresso'
553
+							),
554
+							$page->label
555
+						)
556
+					);
557
+					continue;
558
+				}
559
+				//if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
560
+				if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
561
+					throw new EE_Error(
562
+						sprintf(
563
+							__(
564
+								'The menu map for %s must be an EE_Admin_Page_Menu_Map object.  Instead it is %s.  Please double check that the menu map has been configured correctly.',
565
+								'event_espresso'
566
+							),
567
+							$page->label,
568
+							$page_map
569
+						)
570
+					);
571
+				}
572
+				//use the maintenance_mode_parent property and maintenance mode status to determine if this page even gets added to array.
573
+				if (empty($page_map->maintenance_mode_parent)
574
+					&& EE_Maintenance_Mode::instance()->level()
575
+					   == EE_Maintenance_Mode::level_2_complete_maintenance) {
576
+					continue;
577
+				}
578
+				//assign to group (remember $page_map has the admin page stored in it).
579
+				$pages_array[$page_map->menu_group][] = $page_map;
580
+			}
581
+		}
582
+		if (empty($pages_array)) {
583
+			throw new EE_Error(__('Something went wrong when prepping the admin pages', 'event_espresso'));
584
+		}
585
+		//let's sort the groups, make sure it's a valid group, add header (if to show).
586
+		foreach ($pages_array as $group => $menu_maps) {
587
+			//valid_group?
588
+			if (! array_key_exists($group, $menu_groups)) {
589
+				continue;
590
+			}
591
+			//sort pages.
592
+			usort($menu_maps, array($this, '_sort_menu_maps'));
593
+			//prepend header
594
+			array_unshift($menu_maps, $menu_groups[$group]);
595
+			//reset $pages_array with prepped data
596
+			$pages_array[$group] = $menu_maps;
597
+		}
598
+		//now let's setup the _prepped_menu_maps property
599
+		foreach ($menu_groups as $group => $group_objs) {
600
+			if (isset($pages_array[$group])) {
601
+				$this->_prepped_menu_maps = array_merge($this->_prepped_menu_maps, $pages_array[$group]);
602
+			}
603
+		}/**/
604
+	}
605
+
606
+
607
+	/**
608
+	 * This method is the "workhorse" for detecting and setting up caffeinated functionality.
609
+	 * In this method there are three checks being done:
610
+	 * 1. Do we have any NEW admin page sets.  If we do, lets add them into the menu setup (via the $installed_refs
611
+	 * array) etc.  (new page sets are found in caffeinated/new/{page})
612
+	 * 2. Do we have any EXTENDED page sets.  Basically an extended EE_Admin Page extends the core {child}_Admin_Page
613
+	 * class.  eg. would be caffeinated/extend/events/Extend_Events_Admin_Page.core.php and in there would be a class:
614
+	 * Extend_Events_Admin_Page extends Events_Admin_Page.
615
+	 * 3. Do we have any files just for setting up hooks into other core pages.  The files can be any name in
616
+	 * "caffeinated/hooks" EXCEPT they need a ".class.php" extension and the file name must correspond with the
617
+	 * classname inside.  These classes are instantiated really early so that any hooks in them are run before the
618
+	 * corresponding apply_filters/do_actions that are found in any future loaded EE_Admin pages (INCLUDING caffeinated
619
+	 * admin_pages)
620
+	 *
621
+	 * @param array $installed_refs the original installed_refs array that may contain our NEW EE_Admin_Pages to be
622
+	 *                              loaded.
623
+	 * @return array
624
+	 */
625
+	private function _set_caffeinated($installed_refs)
626
+	{
627
+
628
+		//first let's check if there IS a caffeinated folder. If there is not then lets get out.
629
+		if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
630
+			return $installed_refs;
631
+		}
632
+		$this->_define_caffeinated_constants();
633
+		$exclude = array('tickets');
634
+		//okay let's setup an "New" pages first (we'll return installed refs later)
635
+		$new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
636
+		if ($new_admin_screens) {
637
+			foreach ($new_admin_screens as $admin_screen) {
638
+				// files and anything in the exclude array need not apply
639
+				if (is_dir($admin_screen) && ! in_array(basename($admin_screen), $exclude)) {
640
+					// these folders represent the different NEW EE admin pages
641
+					$installed_refs[basename($admin_screen)] = $admin_screen;
642
+					// set autoloaders for our admin page classes based on included path information
643
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($admin_screen);
644
+					//					$this->_caf_autoloader[] = array(
645
+					//						'dir' => 'new',
646
+					//						'folder' => basename( $admin_screen )
647
+					//					);
648
+				}
649
+			}
650
+		}
651
+		//let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
652
+		$extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
653
+		if ($extends) {
654
+			foreach ($extends as $extend) {
655
+				if (is_dir($extend)) {
656
+					$extend_ref = basename($extend);
657
+					//now let's make sure there is a file that matches the expected format
658
+					$filename                                              = str_replace(
659
+						' ',
660
+						'_',
661
+						ucwords(
662
+							str_replace(
663
+								'_',
664
+								' ',
665
+								$extend_ref
666
+							)
667
+						)
668
+					);
669
+					$filename                                              = 'Extend_' . $filename . '_Admin_Page';
670
+					$this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
671
+						array('\\', '/'),
672
+						DS,
673
+						EE_CORE_CAF_ADMIN
674
+						. 'extend'
675
+						. DS
676
+						. $extend_ref
677
+						. DS
678
+						. $filename
679
+						. '.core.php'
680
+					);
681
+					$this->_caffeinated_extends[$extend_ref]['admin_page'] = $filename;
682
+					// set autoloaders for our admin page classes based on included path information
683
+					EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder($extend);
684
+					//					$this->_caf_autoloader[] = array(
685
+					//						'dir' => 'extend',
686
+					//						'folder' => $extend_ref
687
+					//					);
688
+				}
689
+			}
690
+		}
691
+		//let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
692
+		$ee_admin_hooks = array();
693
+		$hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
694
+		if ($hooks) {
695
+			foreach ($hooks as $hook) {
696
+				if (is_readable($hook)) {
697
+					require_once $hook;
698
+					$classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
699
+					$classname = str_replace('.class.php', '', $classname);
700
+					if (class_exists($classname)) {
701
+						$a                = new ReflectionClass($classname);
702
+						$ee_admin_hooks[] = $a->newInstance();
703
+					}
704
+				}
705
+			}
706
+		}/**/
707
+		$ee_admin_hooks = apply_filters('FHEE__EE_Admin_Page_Loader__set_caffeinated__ee_admin_hooks', $ee_admin_hooks);
708
+		return $installed_refs;
709
+	}
710
+
711
+
712
+
713
+
714
+
715
+	/**
716
+	 * Initial autoloader registration
717
+	 * This just sets up the autoloader for the root admin files
718
+	 *
719
+	 * @param  string $className incoming classname to check for autoload
720
+	 * @return void
721
+	 */
722
+	//	public function init_autoloaders( $className ) {
723
+	//		$dir_ref = array(
724
+	//			EE_ADMIN => array('core', 'class')
725
+	//		);
726
+	//		EEH_Autoloader::try_autoload($dir_ref, $className );
727
+	//	}
728
+	/**
729
+	 * This method takes care of setting up the autoloader dynamically for any NEW EE_Admin pages found in the
730
+	 * caffeinated folders.
731
+	 *
732
+	 * @access public
733
+	 * @param  string $className in coming classname being called
734
+	 * @return void
735
+	 */
736
+	//	public function caffeinated_autoloaders( $className ) {
737
+	//		//let's setup an array of paths to check (for each subsystem)
738
+	//		$dir_ref = array();
739
+	//		foreach ( $this->_caf_autoloader as $pathinfo) {
740
+	//			$dir_ref[ EE_CORE_CAF_ADMIN . $pathinfo['dir'] . DS . $pathinfo['folder'] . DS] = array('core', 'class');
741
+	//		}
742
+	//
743
+	//		EEH_Autoloader::try_autoload($dir_ref, $className );
744
+	//	}
745
+	/**
746
+	 * Utility method for sorting the _menu_maps (callback for usort php function)
747
+	 *
748
+	 * @since  4.4.0
749
+	 * @param  EE_Admin_Page_Menu_Map $a menu_map object
750
+	 * @param  EE_Admin_Page_Menu_Map $b being compared to
751
+	 * @return int    sort order
752
+	 */
753
+	private function _sort_menu_maps(EE_Admin_Page_Menu_Map $a, EE_Admin_Page_Menu_Map $b)
754
+	{
755
+		if ($a->menu_order == $b->menu_order) {
756
+			return 0;
757
+		}
758
+		return ($a->menu_order < $b->menu_order) ? -1 : 1;
759
+	}
760
+
761
+
762
+
763
+	/**
764
+	 * _default_header_link
765
+	 * This is just a dummy method to use with header submenu items
766
+	 *
767
+	 * @return bool false
768
+	 */
769
+	public function _default_header_link()
770
+	{
771
+		return false;
772
+	}
773 773
 
774 774
 
775 775
 }
Please login to merge, or discard this patch.
Spacing   +31 added lines, -31 removed lines patch added patch discarded remove patch
@@ -2,7 +2,7 @@  discard block
 block discarded – undo
2 2
 use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
3 3
 use EventEspresso\core\exceptions\InvalidDataTypeException;
4 4
 
5
-if (!defined('EVENT_ESPRESSO_VERSION') )
5
+if ( ! defined('EVENT_ESPRESSO_VERSION'))
6 6
 	exit('NO direct script access allowed');
7 7
 
8 8
 
@@ -142,13 +142,13 @@  discard block
 block discarded – undo
142 142
      */
143 143
     private function _define_caffeinated_constants()
144 144
     {
145
-        if (! defined('EE_CORE_CAF_ADMIN')) {
146
-            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH . 'caffeinated/admin/');
147
-            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL . 'caffeinated/admin/');
148
-            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN . 'new/');
149
-            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN . 'extend/');
150
-            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL . 'extend/');
151
-            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN . 'hooks/');
145
+        if ( ! defined('EE_CORE_CAF_ADMIN')) {
146
+            define('EE_CORE_CAF_ADMIN', EE_PLUGIN_DIR_PATH.'caffeinated/admin/');
147
+            define('EE_CORE_CAF_ADMIN_URL', EE_PLUGIN_DIR_URL.'caffeinated/admin/');
148
+            define('EE_CORE_CAF_ADMIN_NEW', EE_CORE_CAF_ADMIN.'new/');
149
+            define('EE_CORE_CAF_ADMIN_EXTEND', EE_CORE_CAF_ADMIN.'extend/');
150
+            define('EE_CORE_CAF_ADMIN_EXTEND_URL', EE_CORE_CAF_ADMIN_URL.'extend/');
151
+            define('EE_CORE_CAF_ADMIN_HOOKS', EE_CORE_CAF_ADMIN.'hooks/');
152 152
         }
153 153
     }
154 154
 
@@ -261,7 +261,7 @@  discard block
 block discarded – undo
261 261
         //first let's order the menu groups by their internal menu order (note usort type hinting to ensure the incoming array is EE_Admin_Page_Menu_Map objects )
262 262
         usort($this->_admin_menu_groups, array($this, '_sort_menu_maps'));
263 263
         foreach ($this->_admin_menu_groups as $group) {
264
-            if (! $group instanceof EE_Admin_Page_Menu_Group) {
264
+            if ( ! $group instanceof EE_Admin_Page_Menu_Group) {
265 265
                 throw new EE_Error(
266 266
                     sprintf(
267 267
                         __(
@@ -292,7 +292,7 @@  discard block
 block discarded – undo
292 292
         $installed_refs = array();
293 293
         $exclude        = array('assets', 'templates');
294 294
         // grab everything in the  admin core directory
295
-        $admin_screens = glob(EE_ADMIN_PAGES . '*', GLOB_ONLYDIR);
295
+        $admin_screens = glob(EE_ADMIN_PAGES.'*', GLOB_ONLYDIR);
296 296
         if ($admin_screens) {
297 297
             foreach ($admin_screens as $admin_screen) {
298 298
                 // files and anything in the exclude array need not apply
@@ -307,7 +307,7 @@  discard block
 block discarded – undo
307 307
                 'There are no EE_Admin pages detected, it looks like EE did not install properly',
308 308
                 'event_espresso'
309 309
             );
310
-            $error_msg[] = $error_msg[0] . "\r\n" . sprintf(
310
+            $error_msg[] = $error_msg[0]."\r\n".sprintf(
311 311
                     __(
312 312
                         'Check that the %s folder exists and is writable. Maybe try deactivating, then reactivating Event Espresso again.',
313 313
                         'event_espresso'
@@ -319,7 +319,7 @@  discard block
 block discarded – undo
319 319
         //this just checks the caffeinated folder and takes care of setting up any caffeinated stuff.
320 320
         $installed_refs = $this->_set_caffeinated($installed_refs);
321 321
         //allow plugins to add in their own pages (note at this point they will need to have an autoloader defined for their class) OR hook into EEH_Autoloader::load_admin_page() to add their path.;
322
-        $installed_refs             = apply_filters(
322
+        $installed_refs = apply_filters(
323 323
             'FHEE__EE_Admin_Page_Loader___get_installed_pages__installed_refs',
324 324
             $installed_refs
325 325
         );
@@ -336,7 +336,7 @@  discard block
 block discarded – undo
336 336
             $this->_installed_pages[$page] = $this->_load_admin_page($page, $path);
337 337
             // verify returned object
338 338
             if ($this->_installed_pages[$page] instanceof EE_Admin_Page_Init) {
339
-                if (! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
339
+                if ( ! $this->_installed_pages[$page]->get_menu_map() instanceof EE_Admin_Page_Menu_Map) {
340 340
                     continue;
341 341
                 }
342 342
                 //skip if in full maintenance mode and maintenance_mode_parent is set
@@ -365,7 +365,7 @@  discard block
 block discarded – undo
365 365
                     );
366 366
                     add_filter(
367 367
                         "FHEE__EE_Admin_Page_Init___initialize_admin_page__admin_page__{$menu_slug}_{$admin_page_name}",
368
-                        function ($admin_page) use ($caf_admin_page)
368
+                        function($admin_page) use ($caf_admin_page)
369 369
                         {
370 370
                             return $caf_admin_page;
371 371
                         }
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
     private function _get_classname_for_admin_page($dir_name = '')
425 425
     {
426 426
         $class_name = str_replace('_', ' ', strtolower($dir_name));
427
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page';
427
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page';
428 428
     }
429 429
 
430 430
 
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
     private function _get_classname_for_admin_init_page($dir_name = '')
440 440
     {
441 441
         $class_name = str_replace('_', ' ', strtolower($dir_name));
442
-        return str_replace(' ', '_', ucwords($class_name)) . '_Admin_Page_Init';
442
+        return str_replace(' ', '_', ucwords($class_name)).'_Admin_Page_Init';
443 443
     }
444 444
 
445 445
 
@@ -457,19 +457,19 @@  discard block
 block discarded – undo
457 457
     {
458 458
         $class_name = $this->_get_classname_for_admin_init_page($page);
459 459
         EE_Registry::instance()->load_file($path, $class_name, 'core');
460
-        if (! class_exists($class_name)) {
461
-            $inner_error_msg = '<br />' . sprintf(
460
+        if ( ! class_exists($class_name)) {
461
+            $inner_error_msg = '<br />'.sprintf(
462 462
                     esc_html__(
463 463
                         'Make sure you have %1$s defined. If this is a non-EE-core admin page then you also must have an autoloader in place for your class',
464 464
                         'event_espresso'
465 465
                     ),
466
-                    '<strong>' . $class_name . '</strong>'
466
+                    '<strong>'.$class_name.'</strong>'
467 467
                 );
468
-            $error_msg[]     = sprintf(
468
+            $error_msg[] = sprintf(
469 469
                 __('Something went wrong with loading the %s admin page.', 'event_espresso'),
470 470
                 $page
471 471
             );
472
-            $error_msg[]     = $error_msg[0]
472
+            $error_msg[] = $error_msg[0]
473 473
                                . "\r\n"
474 474
                                . sprintf(
475 475
                                    esc_html__(
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
                 //if we've got an array then the menu map is in the old format so let's throw a persistent notice that the admin system isn't setup correctly for this item.
546 546
                 if (is_array($page_map) || empty($page_map)) {
547 547
                       new PersistentAdminNotice(
548
-                        'menu_map_warning_' . str_replace(' ', '_', $page->label) . '_' . EVENT_ESPRESSO_VERSION,
548
+                        'menu_map_warning_'.str_replace(' ', '_', $page->label).'_'.EVENT_ESPRESSO_VERSION,
549 549
                         sprintf(
550 550
                             __(
551 551
                                 'The admin page for %s was not correctly setup because it is using an older method for integrating with Event Espresso Core.  This means that full functionality for this component is not available.  This error message usually appears with an Add-on that is out of date.  Make sure you update all your Event Espresso 4 add-ons to the latest version to ensure they have necessary compatibility updates in place.',
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
                     continue;
558 558
                 }
559 559
                 //if page map is NOT a EE_Admin_Page_Menu_Map object then throw error.
560
-                if (! $page_map instanceof EE_Admin_Page_Menu_Map) {
560
+                if ( ! $page_map instanceof EE_Admin_Page_Menu_Map) {
561 561
                     throw new EE_Error(
562 562
                         sprintf(
563 563
                             __(
@@ -585,7 +585,7 @@  discard block
 block discarded – undo
585 585
         //let's sort the groups, make sure it's a valid group, add header (if to show).
586 586
         foreach ($pages_array as $group => $menu_maps) {
587 587
             //valid_group?
588
-            if (! array_key_exists($group, $menu_groups)) {
588
+            if ( ! array_key_exists($group, $menu_groups)) {
589 589
                 continue;
590 590
             }
591 591
             //sort pages.
@@ -626,13 +626,13 @@  discard block
 block discarded – undo
626 626
     {
627 627
 
628 628
         //first let's check if there IS a caffeinated folder. If there is not then lets get out.
629
-        if (! is_dir(EE_PLUGIN_DIR_PATH . 'caffeinated' . DS . 'admin') || (defined('EE_DECAF') && EE_DECAF)) {
629
+        if ( ! is_dir(EE_PLUGIN_DIR_PATH.'caffeinated'.DS.'admin') || (defined('EE_DECAF') && EE_DECAF)) {
630 630
             return $installed_refs;
631 631
         }
632 632
         $this->_define_caffeinated_constants();
633 633
         $exclude = array('tickets');
634 634
         //okay let's setup an "New" pages first (we'll return installed refs later)
635
-        $new_admin_screens = glob(EE_CORE_CAF_ADMIN . 'new/*', GLOB_ONLYDIR);
635
+        $new_admin_screens = glob(EE_CORE_CAF_ADMIN.'new/*', GLOB_ONLYDIR);
636 636
         if ($new_admin_screens) {
637 637
             foreach ($new_admin_screens as $admin_screen) {
638 638
                 // files and anything in the exclude array need not apply
@@ -649,13 +649,13 @@  discard block
 block discarded – undo
649 649
             }
650 650
         }
651 651
         //let's see if there are any EXTENDS to setup in the $_caffeinated_extends array (that will be used later for hooking into the _initialize_admin_age in the related core_init admin page)
652
-        $extends = glob(EE_CORE_CAF_ADMIN . 'extend/*', GLOB_ONLYDIR);
652
+        $extends = glob(EE_CORE_CAF_ADMIN.'extend/*', GLOB_ONLYDIR);
653 653
         if ($extends) {
654 654
             foreach ($extends as $extend) {
655 655
                 if (is_dir($extend)) {
656 656
                     $extend_ref = basename($extend);
657 657
                     //now let's make sure there is a file that matches the expected format
658
-                    $filename                                              = str_replace(
658
+                    $filename = str_replace(
659 659
                         ' ',
660 660
                         '_',
661 661
                         ucwords(
@@ -666,7 +666,7 @@  discard block
 block discarded – undo
666 666
                             )
667 667
                         )
668 668
                     );
669
-                    $filename                                              = 'Extend_' . $filename . '_Admin_Page';
669
+                    $filename                                              = 'Extend_'.$filename.'_Admin_Page';
670 670
                     $this->_caffeinated_extends[$extend_ref]['path']       = str_replace(
671 671
                         array('\\', '/'),
672 672
                         DS,
@@ -690,12 +690,12 @@  discard block
 block discarded – undo
690 690
         }
691 691
         //let's see if there are any HOOK files and instantiate them if there are (so that hooks are loaded early!).
692 692
         $ee_admin_hooks = array();
693
-        $hooks          = glob(EE_CORE_CAF_ADMIN . 'hooks/*.class.php');
693
+        $hooks          = glob(EE_CORE_CAF_ADMIN.'hooks/*.class.php');
694 694
         if ($hooks) {
695 695
             foreach ($hooks as $hook) {
696 696
                 if (is_readable($hook)) {
697 697
                     require_once $hook;
698
-                    $classname = str_replace(EE_CORE_CAF_ADMIN . 'hooks/', '', $hook);
698
+                    $classname = str_replace(EE_CORE_CAF_ADMIN.'hooks/', '', $hook);
699 699
                     $classname = str_replace('.class.php', '', $classname);
700 700
                     if (class_exists($classname)) {
701 701
                         $a                = new ReflectionClass($classname);
Please login to merge, or discard this patch.
libraries/form_sections/inputs/EE_Form_Input_With_Options_Base.input.php 2 patches
Indentation   +319 added lines, -319 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('No direct script access allowed');
2
+	exit('No direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -16,324 +16,324 @@  discard block
 block discarded – undo
16 16
 class EE_Form_Input_With_Options_Base extends EE_Form_Input_Base
17 17
 {
18 18
 
19
-    /**
20
-     * array of available options to choose as an answer
21
-     *
22
-     * @var array
23
-     */
24
-    protected $_options = array();
25
-
26
-    /**
27
-     * whether to display the html_label_text above the checkbox/radio button options
28
-     *
29
-     * @var boolean
30
-     */
31
-    protected $_display_html_label_text = true;
32
-
33
-    /**
34
-     * whether to display an question option description as part of the input label
35
-     *
36
-     * @var boolean
37
-     */
38
-    protected $_use_desc_in_label = true;
39
-
40
-    /**
41
-     * strlen() result for the longest input value (what gets displayed in the label)
42
-     * this is used to apply a css class to the input label
43
-     *
44
-     * @var int
45
-     */
46
-    protected $_label_size = 0;
47
-
48
-    /**
49
-     * whether to enforce the label size value passed in the constructor
50
-     *
51
-     * @var boolean
52
-     */
53
-    protected $_enforce_label_size = false;
54
-
55
-    /**
56
-     * whether to allow multiple selections (ie, the value of this input should be an array)
57
-     * or not (ie, the value should be a simple int, string, etc)
58
-     *
59
-     * @var boolean
60
-     */
61
-    protected $_multiple_selections = false;
62
-
63
-
64
-
65
-    /**
66
-     * @param array     $answer_options
67
-     * @param array     $input_settings {
68
-     * @type int|string $label_size
69
-     * @type boolean    $display_html_label_text
70
-     *                                  }
71
-     *                                  And all the options accepted by EE_Form_Input_Base
72
-     */
73
-    public function __construct($answer_options = array(), $input_settings = array())
74
-    {
75
-        if (isset($input_settings['label_size'])) {
76
-            $this->_set_label_size($input_settings['label_size']);
77
-            if (isset($input_settings['enforce_label_size']) && $input_settings['enforce_label_size']) {
78
-                $this->_enforce_label_size = true;
79
-            }
80
-        }
81
-        if (isset($input_settings['display_html_label_text'])) {
82
-            $this->set_display_html_label_text($input_settings['display_html_label_text']);
83
-        }
84
-        $this->set_select_options($answer_options);
85
-        parent::__construct($input_settings);
86
-    }
87
-
88
-
89
-
90
-    /**
91
-     * Sets the allowed options for this input. Also has the side-effect of
92
-     * updating the normalization strategy to match the keys provided in the array
93
-     *
94
-     * @param array $answer_options
95
-     * @return void  just has the side-effect of setting the options for this input
96
-     */
97
-    public function set_select_options($answer_options = array())
98
-    {
99
-        $answer_options = is_array($answer_options) ? $answer_options : array($answer_options);
100
-        //get the first item in the select options and check it's type
101
-        $this->_options = reset($answer_options) instanceof EE_Question_Option
102
-            ? $this->_process_question_options($answer_options)
103
-            : $answer_options;
104
-        //d( $this->_options );
105
-        $select_option_keys = array_keys($this->_options);
106
-        // attempt to determine data type for values in order to set normalization type
107
-        //purposefully only
108
-        if (
109
-            count($this->_options) === 2
110
-            && (
111
-                (in_array(true, $select_option_keys, true) && in_array(false, $select_option_keys, true))
112
-                || (in_array(1, $select_option_keys, true) && in_array(0, $select_option_keys, true))
113
-            )
114
-        ) {
115
-            // values appear to be boolean, like TRUE, FALSE, 1, 0
116
-            $normalization = new EE_Boolean_Normalization();
117
-        } else {
118
-            //are ALL the options ints (even if we're using a multi-dimensional array)? If so use int validation
119
-            $all_ints = true;
120
-            array_walk_recursive(
121
-                $this->_options,
122
-                function($value,$key) use (&$all_ints){
123
-                    //is this a top-level key? ignore it
124
-                    if(! is_array($value)
125
-                        && ! is_int($key)
126
-                       && $key !== ''
127
-                       && $key !== null){
128
-                        $all_ints = false;
129
-                    }
130
-                }
131
-            );
132
-            if ($all_ints) {
133
-                $normalization = new EE_Int_Normalization();
134
-            } else {
135
-                $normalization = new EE_Text_Normalization();
136
-            }
137
-        }
138
-        // does input type have multiple options ?
139
-        if ($this->_multiple_selections) {
140
-            $this->_set_normalization_strategy(new EE_Many_Valued_Normalization($normalization));
141
-        } else {
142
-            $this->_set_normalization_strategy($normalization);
143
-        }
144
-    }
145
-
146
-
147
-
148
-    /**
149
-     * @return array
150
-     */
151
-    public function options()
152
-    {
153
-        return $this->_options;
154
-    }
155
-
156
-
157
-
158
-    /**
159
-     * Returns an array which is guaranteed to not be multidimensional
160
-     *
161
-     * @return array
162
-     */
163
-    public function flat_options()
164
-    {
165
-        return $this->_flatten_select_options($this->options());
166
-    }
167
-
168
-
169
-
170
-    /**
171
-     * Makes sure $arr is a flat array, not a multidimensional one
172
-     *
173
-     * @param array $arr
174
-     * @return array
175
-     */
176
-    protected function _flatten_select_options($arr)
177
-    {
178
-        $flat_array = array();
179
-        if (EEH_Array::is_multi_dimensional_array($arr)) {
180
-            foreach ($arr as $sub_array) {
181
-                foreach ((array)$sub_array as $key => $value) {
182
-                    $flat_array[$key] = $value;
183
-                    $this->_set_label_size($value);
184
-                }
185
-            }
186
-        } else {
187
-            foreach ($arr as $key => $value) {
188
-                $flat_array[$key] = $value;
189
-                $this->_set_label_size($value);
190
-            }
191
-        }
192
-        return $flat_array;
193
-    }
194
-
195
-
196
-
197
-    /**
198
-     * @param EE_Question_Option[] $question_options_array
199
-     * @return array
200
-     */
201
-    protected function _process_question_options($question_options_array = array())
202
-    {
203
-        $flat_array = array();
204
-        foreach ($question_options_array as $question_option) {
205
-            if ($question_option instanceof EE_Question_Option) {
206
-                $desc = '';
207
-                if ($this->_use_desc_in_label) {
208
-                    $desc = $question_option->desc();
209
-                    $desc = ! empty($desc) ? '<span class="ee-question-option-desc">' . $desc . '</span>' : '';
210
-                }
211
-                $value = $question_option->value();
212
-                // add value even if it's empty
213
-                $flat_array[$value] = $value;
214
-                // if both value and desc are not empty, then separate with a dash
215
-                if ( ! empty($value) && ! empty($desc)) {
216
-                    $flat_array[$value] .= ' - ' . $desc;
217
-                } else {
218
-                    // otherwise, just add desc, since either or both of the vars is empty, and no dash is necessary
219
-                    $flat_array[$value] .= $desc;
220
-                }
221
-            } elseif (is_array($question_option)) {
222
-                $flat_array += $this->_flatten_select_options($question_option);
223
-            }
224
-        }
225
-        return $flat_array;
226
-    }
227
-
228
-
229
-
230
-    /**
231
-     *    set_label_sizes
232
-     *
233
-     * @return void
234
-     */
235
-    public function set_label_sizes()
236
-    {
237
-        // did the input settings specifically say to NOT set the label size dynamically ?
238
-        if ( ! $this->_enforce_label_size) {
239
-            foreach ($this->_options as $option) {
240
-                // calculate the strlen of the label
241
-                $this->_set_label_size($option);
242
-            }
243
-        }
244
-    }
245
-
246
-
247
-
248
-    /**
249
-     *    _set_label_size_class
250
-     *
251
-     * @param int|string $value
252
-     * @return void
253
-     */
254
-    private function _set_label_size($value = '')
255
-    {
256
-        // don't change label size if it has already been set and is being enforced
257
-        if($this->_enforce_label_size && $this->_label_size >  0) {
258
-            return;
259
-        }
260
-        // determine length of option value
261
-        $val_size = is_int($value) ? $value : strlen($value);
262
-        // use new value if bigger than existing
263
-        $this->_label_size = $val_size > $this->_label_size ? $val_size : $this->_label_size;
264
-    }
265
-
266
-
267
-
268
-    /**
269
-     *    get_label_size_class
270
-     *
271
-     * @return string
272
-     */
273
-    public function get_label_size_class()
274
-    {
275
-        $size = ' medium-lbl';
276
-        // use maximum option value length to determine label size
277
-        if ($this->_label_size < 3) {
278
-            $size = ' nano-lbl';
279
-        } else if ($this->_label_size < 6) {
280
-            $size = ' micro-lbl';
281
-        } else if ($this->_label_size < 12) {
282
-            $size = ' tiny-lbl';
283
-        } else if ($this->_label_size < 25) {
284
-            $size = ' small-lbl';
285
-        } else if ($this->_label_size < 50) {
286
-            $size = ' medium-lbl';
287
-        } else if ($this->_label_size >= 100) {
288
-            $size = ' big-lbl';
289
-        }
290
-        return $size;
291
-    }
292
-
293
-
294
-
295
-    /**
296
-     * Returns the pretty value for the normalized value
297
-     *
298
-     * @return string
299
-     */
300
-    public function pretty_value()
301
-    {
302
-        $options = $this->flat_options();
303
-        $unnormalized_value_choices = $this->get_normalization_strategy()->unnormalize($this->_normalized_value);
304
-        if ( ! $this->_multiple_selections) {
305
-            $unnormalized_value_choices = array($unnormalized_value_choices);
306
-        }
307
-        $pretty_strings = array();
308
-        foreach ((array)$unnormalized_value_choices as $unnormalized_value_choice) {
309
-            if (isset($options[$unnormalized_value_choice])) {
310
-                $pretty_strings[] = $options[$unnormalized_value_choice];
311
-            } else {
312
-                $pretty_strings[] = $this->normalized_value();
313
-            }
314
-        }
315
-        return implode(', ', $pretty_strings);
316
-    }
317
-
318
-
319
-
320
-    /**
321
-     * @return boolean
322
-     */
323
-    public function display_html_label_text()
324
-    {
325
-        return $this->_display_html_label_text;
326
-    }
327
-
328
-
329
-
330
-    /**
331
-     * @param boolean $display_html_label_text
332
-     */
333
-    public function set_display_html_label_text($display_html_label_text)
334
-    {
335
-        $this->_display_html_label_text = filter_var($display_html_label_text, FILTER_VALIDATE_BOOLEAN);
336
-    }
19
+	/**
20
+	 * array of available options to choose as an answer
21
+	 *
22
+	 * @var array
23
+	 */
24
+	protected $_options = array();
25
+
26
+	/**
27
+	 * whether to display the html_label_text above the checkbox/radio button options
28
+	 *
29
+	 * @var boolean
30
+	 */
31
+	protected $_display_html_label_text = true;
32
+
33
+	/**
34
+	 * whether to display an question option description as part of the input label
35
+	 *
36
+	 * @var boolean
37
+	 */
38
+	protected $_use_desc_in_label = true;
39
+
40
+	/**
41
+	 * strlen() result for the longest input value (what gets displayed in the label)
42
+	 * this is used to apply a css class to the input label
43
+	 *
44
+	 * @var int
45
+	 */
46
+	protected $_label_size = 0;
47
+
48
+	/**
49
+	 * whether to enforce the label size value passed in the constructor
50
+	 *
51
+	 * @var boolean
52
+	 */
53
+	protected $_enforce_label_size = false;
54
+
55
+	/**
56
+	 * whether to allow multiple selections (ie, the value of this input should be an array)
57
+	 * or not (ie, the value should be a simple int, string, etc)
58
+	 *
59
+	 * @var boolean
60
+	 */
61
+	protected $_multiple_selections = false;
62
+
63
+
64
+
65
+	/**
66
+	 * @param array     $answer_options
67
+	 * @param array     $input_settings {
68
+	 * @type int|string $label_size
69
+	 * @type boolean    $display_html_label_text
70
+	 *                                  }
71
+	 *                                  And all the options accepted by EE_Form_Input_Base
72
+	 */
73
+	public function __construct($answer_options = array(), $input_settings = array())
74
+	{
75
+		if (isset($input_settings['label_size'])) {
76
+			$this->_set_label_size($input_settings['label_size']);
77
+			if (isset($input_settings['enforce_label_size']) && $input_settings['enforce_label_size']) {
78
+				$this->_enforce_label_size = true;
79
+			}
80
+		}
81
+		if (isset($input_settings['display_html_label_text'])) {
82
+			$this->set_display_html_label_text($input_settings['display_html_label_text']);
83
+		}
84
+		$this->set_select_options($answer_options);
85
+		parent::__construct($input_settings);
86
+	}
87
+
88
+
89
+
90
+	/**
91
+	 * Sets the allowed options for this input. Also has the side-effect of
92
+	 * updating the normalization strategy to match the keys provided in the array
93
+	 *
94
+	 * @param array $answer_options
95
+	 * @return void  just has the side-effect of setting the options for this input
96
+	 */
97
+	public function set_select_options($answer_options = array())
98
+	{
99
+		$answer_options = is_array($answer_options) ? $answer_options : array($answer_options);
100
+		//get the first item in the select options and check it's type
101
+		$this->_options = reset($answer_options) instanceof EE_Question_Option
102
+			? $this->_process_question_options($answer_options)
103
+			: $answer_options;
104
+		//d( $this->_options );
105
+		$select_option_keys = array_keys($this->_options);
106
+		// attempt to determine data type for values in order to set normalization type
107
+		//purposefully only
108
+		if (
109
+			count($this->_options) === 2
110
+			&& (
111
+				(in_array(true, $select_option_keys, true) && in_array(false, $select_option_keys, true))
112
+				|| (in_array(1, $select_option_keys, true) && in_array(0, $select_option_keys, true))
113
+			)
114
+		) {
115
+			// values appear to be boolean, like TRUE, FALSE, 1, 0
116
+			$normalization = new EE_Boolean_Normalization();
117
+		} else {
118
+			//are ALL the options ints (even if we're using a multi-dimensional array)? If so use int validation
119
+			$all_ints = true;
120
+			array_walk_recursive(
121
+				$this->_options,
122
+				function($value,$key) use (&$all_ints){
123
+					//is this a top-level key? ignore it
124
+					if(! is_array($value)
125
+						&& ! is_int($key)
126
+					   && $key !== ''
127
+					   && $key !== null){
128
+						$all_ints = false;
129
+					}
130
+				}
131
+			);
132
+			if ($all_ints) {
133
+				$normalization = new EE_Int_Normalization();
134
+			} else {
135
+				$normalization = new EE_Text_Normalization();
136
+			}
137
+		}
138
+		// does input type have multiple options ?
139
+		if ($this->_multiple_selections) {
140
+			$this->_set_normalization_strategy(new EE_Many_Valued_Normalization($normalization));
141
+		} else {
142
+			$this->_set_normalization_strategy($normalization);
143
+		}
144
+	}
145
+
146
+
147
+
148
+	/**
149
+	 * @return array
150
+	 */
151
+	public function options()
152
+	{
153
+		return $this->_options;
154
+	}
155
+
156
+
157
+
158
+	/**
159
+	 * Returns an array which is guaranteed to not be multidimensional
160
+	 *
161
+	 * @return array
162
+	 */
163
+	public function flat_options()
164
+	{
165
+		return $this->_flatten_select_options($this->options());
166
+	}
167
+
168
+
169
+
170
+	/**
171
+	 * Makes sure $arr is a flat array, not a multidimensional one
172
+	 *
173
+	 * @param array $arr
174
+	 * @return array
175
+	 */
176
+	protected function _flatten_select_options($arr)
177
+	{
178
+		$flat_array = array();
179
+		if (EEH_Array::is_multi_dimensional_array($arr)) {
180
+			foreach ($arr as $sub_array) {
181
+				foreach ((array)$sub_array as $key => $value) {
182
+					$flat_array[$key] = $value;
183
+					$this->_set_label_size($value);
184
+				}
185
+			}
186
+		} else {
187
+			foreach ($arr as $key => $value) {
188
+				$flat_array[$key] = $value;
189
+				$this->_set_label_size($value);
190
+			}
191
+		}
192
+		return $flat_array;
193
+	}
194
+
195
+
196
+
197
+	/**
198
+	 * @param EE_Question_Option[] $question_options_array
199
+	 * @return array
200
+	 */
201
+	protected function _process_question_options($question_options_array = array())
202
+	{
203
+		$flat_array = array();
204
+		foreach ($question_options_array as $question_option) {
205
+			if ($question_option instanceof EE_Question_Option) {
206
+				$desc = '';
207
+				if ($this->_use_desc_in_label) {
208
+					$desc = $question_option->desc();
209
+					$desc = ! empty($desc) ? '<span class="ee-question-option-desc">' . $desc . '</span>' : '';
210
+				}
211
+				$value = $question_option->value();
212
+				// add value even if it's empty
213
+				$flat_array[$value] = $value;
214
+				// if both value and desc are not empty, then separate with a dash
215
+				if ( ! empty($value) && ! empty($desc)) {
216
+					$flat_array[$value] .= ' - ' . $desc;
217
+				} else {
218
+					// otherwise, just add desc, since either or both of the vars is empty, and no dash is necessary
219
+					$flat_array[$value] .= $desc;
220
+				}
221
+			} elseif (is_array($question_option)) {
222
+				$flat_array += $this->_flatten_select_options($question_option);
223
+			}
224
+		}
225
+		return $flat_array;
226
+	}
227
+
228
+
229
+
230
+	/**
231
+	 *    set_label_sizes
232
+	 *
233
+	 * @return void
234
+	 */
235
+	public function set_label_sizes()
236
+	{
237
+		// did the input settings specifically say to NOT set the label size dynamically ?
238
+		if ( ! $this->_enforce_label_size) {
239
+			foreach ($this->_options as $option) {
240
+				// calculate the strlen of the label
241
+				$this->_set_label_size($option);
242
+			}
243
+		}
244
+	}
245
+
246
+
247
+
248
+	/**
249
+	 *    _set_label_size_class
250
+	 *
251
+	 * @param int|string $value
252
+	 * @return void
253
+	 */
254
+	private function _set_label_size($value = '')
255
+	{
256
+		// don't change label size if it has already been set and is being enforced
257
+		if($this->_enforce_label_size && $this->_label_size >  0) {
258
+			return;
259
+		}
260
+		// determine length of option value
261
+		$val_size = is_int($value) ? $value : strlen($value);
262
+		// use new value if bigger than existing
263
+		$this->_label_size = $val_size > $this->_label_size ? $val_size : $this->_label_size;
264
+	}
265
+
266
+
267
+
268
+	/**
269
+	 *    get_label_size_class
270
+	 *
271
+	 * @return string
272
+	 */
273
+	public function get_label_size_class()
274
+	{
275
+		$size = ' medium-lbl';
276
+		// use maximum option value length to determine label size
277
+		if ($this->_label_size < 3) {
278
+			$size = ' nano-lbl';
279
+		} else if ($this->_label_size < 6) {
280
+			$size = ' micro-lbl';
281
+		} else if ($this->_label_size < 12) {
282
+			$size = ' tiny-lbl';
283
+		} else if ($this->_label_size < 25) {
284
+			$size = ' small-lbl';
285
+		} else if ($this->_label_size < 50) {
286
+			$size = ' medium-lbl';
287
+		} else if ($this->_label_size >= 100) {
288
+			$size = ' big-lbl';
289
+		}
290
+		return $size;
291
+	}
292
+
293
+
294
+
295
+	/**
296
+	 * Returns the pretty value for the normalized value
297
+	 *
298
+	 * @return string
299
+	 */
300
+	public function pretty_value()
301
+	{
302
+		$options = $this->flat_options();
303
+		$unnormalized_value_choices = $this->get_normalization_strategy()->unnormalize($this->_normalized_value);
304
+		if ( ! $this->_multiple_selections) {
305
+			$unnormalized_value_choices = array($unnormalized_value_choices);
306
+		}
307
+		$pretty_strings = array();
308
+		foreach ((array)$unnormalized_value_choices as $unnormalized_value_choice) {
309
+			if (isset($options[$unnormalized_value_choice])) {
310
+				$pretty_strings[] = $options[$unnormalized_value_choice];
311
+			} else {
312
+				$pretty_strings[] = $this->normalized_value();
313
+			}
314
+		}
315
+		return implode(', ', $pretty_strings);
316
+	}
317
+
318
+
319
+
320
+	/**
321
+	 * @return boolean
322
+	 */
323
+	public function display_html_label_text()
324
+	{
325
+		return $this->_display_html_label_text;
326
+	}
327
+
328
+
329
+
330
+	/**
331
+	 * @param boolean $display_html_label_text
332
+	 */
333
+	public function set_display_html_label_text($display_html_label_text)
334
+	{
335
+		$this->_display_html_label_text = filter_var($display_html_label_text, FILTER_VALIDATE_BOOLEAN);
336
+	}
337 337
 
338 338
 
339 339
 
Please login to merge, or discard this patch.
Spacing   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -119,12 +119,12 @@  discard block
 block discarded – undo
119 119
             $all_ints = true;
120 120
             array_walk_recursive(
121 121
                 $this->_options,
122
-                function($value,$key) use (&$all_ints){
122
+                function($value, $key) use (&$all_ints){
123 123
                     //is this a top-level key? ignore it
124
-                    if(! is_array($value)
124
+                    if ( ! is_array($value)
125 125
                         && ! is_int($key)
126 126
                        && $key !== ''
127
-                       && $key !== null){
127
+                       && $key !== null) {
128 128
                         $all_ints = false;
129 129
                     }
130 130
                 }
@@ -178,7 +178,7 @@  discard block
 block discarded – undo
178 178
         $flat_array = array();
179 179
         if (EEH_Array::is_multi_dimensional_array($arr)) {
180 180
             foreach ($arr as $sub_array) {
181
-                foreach ((array)$sub_array as $key => $value) {
181
+                foreach ((array) $sub_array as $key => $value) {
182 182
                     $flat_array[$key] = $value;
183 183
                     $this->_set_label_size($value);
184 184
                 }
@@ -206,14 +206,14 @@  discard block
 block discarded – undo
206 206
                 $desc = '';
207 207
                 if ($this->_use_desc_in_label) {
208 208
                     $desc = $question_option->desc();
209
-                    $desc = ! empty($desc) ? '<span class="ee-question-option-desc">' . $desc . '</span>' : '';
209
+                    $desc = ! empty($desc) ? '<span class="ee-question-option-desc">'.$desc.'</span>' : '';
210 210
                 }
211 211
                 $value = $question_option->value();
212 212
                 // add value even if it's empty
213 213
                 $flat_array[$value] = $value;
214 214
                 // if both value and desc are not empty, then separate with a dash
215 215
                 if ( ! empty($value) && ! empty($desc)) {
216
-                    $flat_array[$value] .= ' - ' . $desc;
216
+                    $flat_array[$value] .= ' - '.$desc;
217 217
                 } else {
218 218
                     // otherwise, just add desc, since either or both of the vars is empty, and no dash is necessary
219 219
                     $flat_array[$value] .= $desc;
@@ -254,7 +254,7 @@  discard block
 block discarded – undo
254 254
     private function _set_label_size($value = '')
255 255
     {
256 256
         // don't change label size if it has already been set and is being enforced
257
-        if($this->_enforce_label_size && $this->_label_size >  0) {
257
+        if ($this->_enforce_label_size && $this->_label_size > 0) {
258 258
             return;
259 259
         }
260 260
         // determine length of option value
@@ -305,7 +305,7 @@  discard block
 block discarded – undo
305 305
             $unnormalized_value_choices = array($unnormalized_value_choices);
306 306
         }
307 307
         $pretty_strings = array();
308
-        foreach ((array)$unnormalized_value_choices as $unnormalized_value_choice) {
308
+        foreach ((array) $unnormalized_value_choices as $unnormalized_value_choice) {
309 309
             if (isset($options[$unnormalized_value_choice])) {
310 310
                 $pretty_strings[] = $options[$unnormalized_value_choice];
311 311
             } else {
Please login to merge, or discard this patch.
core/libraries/batch/JobHandlers/DatetimeOffsetFix.php 2 patches
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -158,19 +158,19 @@  discard block
 block discarded – undo
158 158
         $date_ranges = array();
159 159
         //since some affected models might have two tables, we have to get our tables and set up a query for each table.
160 160
         foreach ($model->get_tables() as $table) {
161
-            $query = 'UPDATE ' . $table->get_table_name();
161
+            $query = 'UPDATE '.$table->get_table_name();
162 162
             $fields_affected = array();
163 163
             $inner_query = array();
164 164
             foreach ($model->_get_fields_for_table($table->get_table_alias()) as $model_field) {
165 165
                 if ($model_field instanceof EE_Datetime_Field) {
166
-                    $inner_query[$model_field->get_table_column()] = $model_field->get_table_column() . ' = '
167
-                                     . $sql_date_function . '('
166
+                    $inner_query[$model_field->get_table_column()] = $model_field->get_table_column().' = '
167
+                                     . $sql_date_function.'('
168 168
                                      . $model_field->get_table_column()
169 169
                                      . ", INTERVAL {$offset} MINUTE)";
170 170
                     $fields_affected[] = $model_field;
171 171
                 }
172 172
             }
173
-            if (! $fields_affected) {
173
+            if ( ! $fields_affected) {
174 174
                 continue;
175 175
             }
176 176
             //do we do one query per column/field or one query for all fields on the model? It all depends on whether
@@ -187,7 +187,7 @@  discard block
 block discarded – undo
187 187
                     //record error.
188 188
                     $error_message = $wpdb->last_error;
189 189
                     //handle the edgecases where last_error might be empty.
190
-                    if (! $error_message) {
190
+                    if ( ! $error_message) {
191 191
                         $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
192 192
                     }
193 193
                     $this->recordChangeLog($model, $original_offset, $table, $fields_affected, $error_message);
@@ -220,7 +220,7 @@  discard block
 block discarded – undo
220 220
         foreach ($inner_query as $field_name => $field_query) {
221 221
             $query_to_run = $query;
222 222
             $where_conditions = array();
223
-            $query_to_run .= ' SET ' . $field_query;
223
+            $query_to_run .= ' SET '.$field_query;
224 224
             if ($start_date_range instanceof DbSafeDateTime) {
225 225
                 $start_date = $start_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
226 226
                 $where_conditions[] = "{$field_name} > '{$start_date}'";
@@ -230,14 +230,14 @@  discard block
 block discarded – undo
230 230
                 $where_conditions[] = "{$field_name} < '{$end_date}'";
231 231
             }
232 232
             if ($where_conditions) {
233
-                $query_to_run .= ' WHERE ' . implode(' AND ', $where_conditions);
233
+                $query_to_run .= ' WHERE '.implode(' AND ', $where_conditions);
234 234
             }
235 235
             $result = $wpdb->query($query_to_run);
236 236
             if ($result === false) {
237 237
                 //record error.
238 238
                 $error_message = $wpdb->last_error;
239 239
                 //handle the edgecases where last_error might be empty.
240
-                if (! $error_message) {
240
+                if ( ! $error_message) {
241 241
                     $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
242 242
                 }
243 243
                 $errors[$field_name] = $error_message;
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
     private function doQueryForAllFields($query, array $inner_query)
258 258
     {
259 259
         global $wpdb;
260
-        $query .= ' SET ' . implode(',', $inner_query);
260
+        $query .= ' SET '.implode(',', $inner_query);
261 261
         return $wpdb->query($query);
262 262
     }
263 263
 
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
         $fields = array();
284 284
         /** @var EE_Datetime_Field $model_field */
285 285
         foreach ($model_fields_affected as $model_field) {
286
-            if (! $model_field instanceof EE_Datetime_Field) {
286
+            if ( ! $model_field instanceof EE_Datetime_Field) {
287 287
                 continue;
288 288
             }
289 289
             $fields[] = $model_field->get_name();
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
     private function getModelsWithDatetimeFields()
336 336
     {
337 337
         $this->getModelsToProcess();
338
-        if (! empty($this->models_with_datetime_fields)) {
338
+        if ( ! empty($this->models_with_datetime_fields)) {
339 339
             return $this->models_with_datetime_fields;
340 340
         }
341 341
 
Please login to merge, or discard this patch.
Indentation   +458 added lines, -458 removed lines patch added patch discarded remove patch
@@ -26,462 +26,462 @@
 block discarded – undo
26 26
 class DatetimeOffsetFix extends JobHandler
27 27
 {
28 28
 
29
-    /**
30
-     * Key for the option used to track which models have been processed when doing the batches.
31
-     */
32
-    const MODELS_TO_PROCESS_OPTION_KEY = 'ee_models_processed_for_datetime_offset_fix';
33
-
34
-
35
-    const COUNT_OF_MODELS_PROCESSED = 'ee_count_of_ee_models_processed_for_datetime_offset_fixed';
36
-
37
-    /**
38
-     * Key for the option used to track what the current offset is that will be applied when this tool is executed.
39
-     */
40
-    const OFFSET_TO_APPLY_OPTION_KEY = 'ee_datetime_offset_fix_offset_to_apply';
41
-
42
-
43
-    const OPTION_KEY_OFFSET_RANGE_START_DATE = 'ee_datetime_offset_start_date_range';
44
-
45
-
46
-    const OPTION_KEY_OFFSET_RANGE_END_DATE = 'ee_datetime_offset_end_date_range';
47
-
48
-
49
-    /**
50
-     * String labelling the datetime offset fix type for change-log entries.
51
-     */
52
-    const DATETIME_OFFSET_FIX_CHANGELOG_TYPE = 'datetime_offset_fix';
53
-
54
-
55
-    /**
56
-     * String labelling a datetime offset fix error for change-log entries.
57
-     */
58
-    const DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE = 'datetime_offset_fix_error';
59
-
60
-    /**
61
-     * @var EEM_Base[]
62
-     */
63
-    protected $models_with_datetime_fields = array();
64
-
65
-
66
-    /**
67
-     * Performs any necessary setup for starting the job. This is also a good
68
-     * place to setup the $job_arguments which will be used for subsequent HTTP requests
69
-     * when continue_job will be called
70
-     *
71
-     * @param JobParameters $job_parameters
72
-     * @return JobStepResponse
73
-     * @throws EE_Error
74
-     * @throws InvalidArgumentException
75
-     * @throws InvalidDataTypeException
76
-     * @throws InvalidInterfaceException
77
-     */
78
-    public function create_job(JobParameters $job_parameters)
79
-    {
80
-        $models_with_datetime_fields = $this->getModelsWithDatetimeFields();
81
-        //we'll be doing each model as a batch.
82
-        $job_parameters->set_job_size(count($models_with_datetime_fields));
83
-        return new JobStepResponse(
84
-            $job_parameters,
85
-            esc_html__('Starting Datetime Offset Fix', 'event_espresso')
86
-        );
87
-    }
88
-
89
-    /**
90
-     * Performs another step of the job
91
-     *
92
-     * @param JobParameters $job_parameters
93
-     * @param int           $batch_size
94
-     * @return JobStepResponse
95
-     * @throws EE_Error
96
-     * @throws InvalidArgumentException
97
-     * @throws InvalidDataTypeException
98
-     * @throws InvalidInterfaceException
99
-     */
100
-    public function continue_job(JobParameters $job_parameters, $batch_size = 50)
101
-    {
102
-        $models_to_process = $this->getModelsWithDatetimeFields();
103
-        //let's pop off the a model and do the query to apply the offset.
104
-        $model_to_process = array_pop($models_to_process);
105
-        //update our record
106
-        $this->setModelsToProcess($models_to_process);
107
-        $this->processModel($model_to_process);
108
-        $this->updateCountOfModelsProcessed();
109
-        $job_parameters->set_units_processed($this->getCountOfModelsProcessed());
110
-        if (count($models_to_process) > 0) {
111
-            $job_parameters->set_status(JobParameters::status_continue);
112
-        } else {
113
-            $job_parameters->set_status(JobParameters::status_complete);
114
-        }
115
-        return new JobStepResponse(
116
-            $job_parameters,
117
-            sprintf(
118
-                esc_html__('Updated the offset for all datetime fields on the %s model.', 'event_espresso'),
119
-                $model_to_process
120
-            )
121
-        );
122
-    }
123
-
124
-    /**
125
-     * Performs any clean-up logic when we know the job is completed
126
-     *
127
-     * @param JobParameters $job_parameters
128
-     * @return JobStepResponse
129
-     * @throws BatchRequestException
130
-     */
131
-    public function cleanup_job(JobParameters $job_parameters)
132
-    {
133
-        //delete important saved options.
134
-        delete_option(self::MODELS_TO_PROCESS_OPTION_KEY);
135
-        delete_option(self::COUNT_OF_MODELS_PROCESSED);
136
-        delete_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE);
137
-        delete_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE);
138
-        return new JobStepResponse($job_parameters, esc_html__(
139
-            'Offset has been applied to all affected fields.',
140
-            'event_espresso'
141
-        ));
142
-    }
143
-
144
-
145
-    /**
146
-     * Contains the logic for processing a model and applying the datetime offset to affected fields on that model.
147
-     * @param string $model_class_name
148
-     * @throws EE_Error
149
-     */
150
-    protected function processModel($model_class_name)
151
-    {
152
-        global $wpdb;
153
-        /** @var EEM_Base $model */
154
-        $model = $model_class_name::instance();
155
-        $original_offset = self::getOffset();
156
-        $start_date_range = self::getStartDateRange();
157
-        $end_date_range = self::getEndDateRange();
158
-        $sql_date_function = $original_offset > 0 ? 'DATE_ADD' : 'DATE_SUB';
159
-        $offset = abs($original_offset) * 60;
160
-        $date_ranges = array();
161
-        //since some affected models might have two tables, we have to get our tables and set up a query for each table.
162
-        foreach ($model->get_tables() as $table) {
163
-            $query = 'UPDATE ' . $table->get_table_name();
164
-            $fields_affected = array();
165
-            $inner_query = array();
166
-            foreach ($model->_get_fields_for_table($table->get_table_alias()) as $model_field) {
167
-                if ($model_field instanceof EE_Datetime_Field) {
168
-                    $inner_query[$model_field->get_table_column()] = $model_field->get_table_column() . ' = '
169
-                                     . $sql_date_function . '('
170
-                                     . $model_field->get_table_column()
171
-                                     . ", INTERVAL {$offset} MINUTE)";
172
-                    $fields_affected[] = $model_field;
173
-                }
174
-            }
175
-            if (! $fields_affected) {
176
-                continue;
177
-            }
178
-            //do we do one query per column/field or one query for all fields on the model? It all depends on whether
179
-            //there is a date range applied or not.
180
-            if ($start_date_range instanceof DbSafeDateTime || $end_date_range instanceof DbSafeDateTime) {
181
-                $result = $this->doQueryForEachField($query, $inner_query, $start_date_range, $end_date_range);
182
-            } else {
183
-                $result = $this->doQueryForAllFields($query, $inner_query);
184
-            }
185
-
186
-            //record appropriate logs for the query
187
-            switch (true) {
188
-                case $result === false:
189
-                    //record error.
190
-                    $error_message = $wpdb->last_error;
191
-                    //handle the edgecases where last_error might be empty.
192
-                    if (! $error_message) {
193
-                        $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
194
-                    }
195
-                    $this->recordChangeLog($model, $original_offset, $table, $fields_affected, $error_message);
196
-                    break;
197
-                case is_array($result) && ! empty($result):
198
-                    foreach ($result as $field_name => $error_message) {
199
-                        $this->recordChangeLog($model, $original_offset, $table, array($field_name), $error_message);
200
-                    }
201
-                    break;
202
-                default:
203
-                    $this->recordChangeLog($model, $original_offset, $table, $fields_affected);
204
-            }
205
-        }
206
-    }
207
-
208
-
209
-    /**
210
-     * Does the query on each $inner_query individually.
211
-     *
212
-     * @param string              $query
213
-     * @param array               $inner_query
214
-     * @param DbSafeDateTime|null $start_date_range
215
-     * @param DbSafeDateTime|null $end_date_range
216
-     * @return array  An array of any errors encountered and the fields they were for.
217
-     */
218
-    private function doQueryForEachField($query, array $inner_query, $start_date_range, $end_date_range)
219
-    {
220
-        global $wpdb;
221
-        $errors = array();
222
-        foreach ($inner_query as $field_name => $field_query) {
223
-            $query_to_run = $query;
224
-            $where_conditions = array();
225
-            $query_to_run .= ' SET ' . $field_query;
226
-            if ($start_date_range instanceof DbSafeDateTime) {
227
-                $start_date = $start_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
228
-                $where_conditions[] = "{$field_name} > '{$start_date}'";
229
-            }
230
-            if ($end_date_range instanceof DbSafeDateTime) {
231
-                $end_date = $end_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
232
-                $where_conditions[] = "{$field_name} < '{$end_date}'";
233
-            }
234
-            if ($where_conditions) {
235
-                $query_to_run .= ' WHERE ' . implode(' AND ', $where_conditions);
236
-            }
237
-            $result = $wpdb->query($query_to_run);
238
-            if ($result === false) {
239
-                //record error.
240
-                $error_message = $wpdb->last_error;
241
-                //handle the edgecases where last_error might be empty.
242
-                if (! $error_message) {
243
-                    $error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
244
-                }
245
-                $errors[$field_name] = $error_message;
246
-            }
247
-        }
248
-        return $errors;
249
-    }
250
-
251
-
252
-    /**
253
-     * Performs the query for all fields within the inner_query
254
-     *
255
-     * @param string $query
256
-     * @param array  $inner_query
257
-     * @return false|int
258
-     */
259
-    private function doQueryForAllFields($query, array $inner_query)
260
-    {
261
-        global $wpdb;
262
-        $query .= ' SET ' . implode(',', $inner_query);
263
-        return $wpdb->query($query);
264
-    }
265
-
266
-
267
-    /**
268
-     * Records a changelog entry using the given information.
269
-     *
270
-     * @param EEM_Base              $model
271
-     * @param float                 $offset
272
-     * @param EE_Table_Base         $table
273
-     * @param EE_Model_Field_Base[] $model_fields_affected
274
-     * @param string                $error_message   If present then there was an error so let's record that instead.
275
-     * @throws EE_Error
276
-     */
277
-    private function recordChangeLog(
278
-        EEM_Base $model,
279
-        $offset,
280
-        EE_Table_Base $table,
281
-        $model_fields_affected,
282
-        $error_message = ''
283
-    ) {
284
-        //setup $fields list.
285
-        $fields = array();
286
-        /** @var EE_Datetime_Field $model_field */
287
-        foreach ($model_fields_affected as $model_field) {
288
-            if (! $model_field instanceof EE_Datetime_Field) {
289
-                continue;
290
-            }
291
-            $fields[] = $model_field->get_name();
292
-        }
293
-        //setup the message for the changelog entry.
294
-        $message = $error_message
295
-            ? sprintf(
296
-                esc_html__(
297
-                    'The %1$s table for the %2$s model did not have the offset of %3$f applied to its fields (%4$s), because of the following error:%5$s',
298
-                    'event_espresso'
299
-                ),
300
-                $table->get_table_name(),
301
-                $model->get_this_model_name(),
302
-                $offset,
303
-                implode(',', $fields),
304
-                $error_message
305
-            )
306
-            : sprintf(
307
-                esc_html__(
308
-                    'The %1$s table for the %2$s model has had the offset of %3$f applied to its following fields: %4$s',
309
-                    'event_espresso'
310
-                ),
311
-                $table->get_table_name(),
312
-                $model->get_this_model_name(),
313
-                $offset,
314
-                implode(',', $fields)
315
-            );
316
-        //write to the log
317
-        $changelog = EE_Change_Log::new_instance(array(
318
-            'LOG_type' => $error_message
319
-                ? self::DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE
320
-                : self::DATETIME_OFFSET_FIX_CHANGELOG_TYPE,
321
-            'LOG_message' => $message
322
-        ));
323
-        $changelog->save();
324
-    }
325
-
326
-
327
-    /**
328
-     * Returns an array of models that have datetime fields.
329
-     * This array is added to a short lived transient cache to keep having to build this list to a minimum.
330
-     *
331
-     * @return array an array of model class names.
332
-     * @throws EE_Error
333
-     * @throws InvalidDataTypeException
334
-     * @throws InvalidInterfaceException
335
-     * @throws InvalidArgumentException
336
-     */
337
-    private function getModelsWithDatetimeFields()
338
-    {
339
-        $this->getModelsToProcess();
340
-        if (! empty($this->models_with_datetime_fields)) {
341
-            return $this->models_with_datetime_fields;
342
-        }
343
-
344
-        $all_non_abstract_models = EE_Registry::instance()->non_abstract_db_models;
345
-        foreach ($all_non_abstract_models as $non_abstract_model) {
346
-            //get model instance
347
-            /** @var EEM_Base $non_abstract_model */
348
-            $non_abstract_model = $non_abstract_model::instance();
349
-            if ($non_abstract_model->get_a_field_of_type('EE_Datetime_Field') instanceof EE_Datetime_Field) {
350
-                $this->models_with_datetime_fields[] = get_class($non_abstract_model);
351
-            }
352
-        }
353
-        $this->setModelsToProcess($this->models_with_datetime_fields);
354
-        return $this->models_with_datetime_fields;
355
-    }
356
-
357
-
358
-    /**
359
-     * This simply records the models that have been processed with our tracking option.
360
-     * @param array $models_to_set  array of model class names.
361
-     */
362
-    private function setModelsToProcess($models_to_set)
363
-    {
364
-        update_option(self::MODELS_TO_PROCESS_OPTION_KEY, $models_to_set);
365
-    }
366
-
367
-
368
-    /**
369
-     * Used to keep track of how many models have been processed for the batch
370
-     * @param $count
371
-     */
372
-    private function updateCountOfModelsProcessed($count = 1)
373
-    {
374
-        $count = $this->getCountOfModelsProcessed() + (int) $count;
375
-        update_option(self::COUNT_OF_MODELS_PROCESSED, $count);
376
-    }
377
-
378
-
379
-    /**
380
-     * Retrieve the tracked number of models processed between requests.
381
-     * @return int
382
-     */
383
-    private function getCountOfModelsProcessed()
384
-    {
385
-        return (int) get_option(self::COUNT_OF_MODELS_PROCESSED, 0);
386
-    }
387
-
388
-
389
-    /**
390
-     * Returns the models that are left to process.
391
-     * @return array  an array of model class names.
392
-     */
393
-    private function getModelsToProcess()
394
-    {
395
-        if (empty($this->models_with_datetime_fields)) {
396
-            $this->models_with_datetime_fields = get_option(self::MODELS_TO_PROCESS_OPTION_KEY, array());
397
-        }
398
-        return $this->models_with_datetime_fields;
399
-    }
400
-
401
-
402
-    /**
403
-     * Used to record the offset that will be applied to dates and times for EE_Datetime_Field columns.
404
-     * @param float $offset
405
-     */
406
-    public static function updateOffset($offset)
407
-    {
408
-        update_option(self::OFFSET_TO_APPLY_OPTION_KEY, $offset);
409
-    }
410
-
411
-
412
-    /**
413
-     * Used to retrieve the saved offset that will be applied to dates and times for EE_Datetime_Field columns.
414
-     *
415
-     * @return float
416
-     */
417
-    public static function getOffset()
418
-    {
419
-        return (float) get_option(self::OFFSET_TO_APPLY_OPTION_KEY, 0);
420
-    }
421
-
422
-
423
-    /**
424
-     * Used to set the saved offset range start date.
425
-     * @param DbSafeDateTime|null $start_date
426
-     */
427
-    public static function updateStartDateRange(DbSafeDateTime $start_date = null)
428
-    {
429
-        $date_to_save = $start_date instanceof DbSafeDateTime
430
-            ? $start_date->format('U')
431
-            : '';
432
-        update_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, $date_to_save);
433
-    }
434
-
435
-
436
-    /**
437
-     * Used to get the saved offset range start date.
438
-     * @return DbSafeDateTime|null
439
-     */
440
-    public static function getStartDateRange()
441
-    {
442
-        $start_date = get_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, null);
443
-        try {
444
-            $datetime = DateTime::createFromFormat('U', $start_date, new DateTimeZone('UTC'));
445
-            $start_date = $datetime instanceof DateTime
446
-                ? DbSafeDateTime::createFromDateTime($datetime)
447
-                : null;
448
-
449
-        } catch (Exception $e) {
450
-            $start_date = null;
451
-        }
452
-        return $start_date;
453
-    }
454
-
455
-
456
-
457
-    /**
458
-     * Used to set the saved offset range end date.
459
-     * @param DbSafeDateTime|null $end_date
460
-     */
461
-    public static function updateEndDateRange(DbSafeDateTime $end_date = null)
462
-    {
463
-        $date_to_save = $end_date instanceof DbSafeDateTime
464
-            ? $end_date->format('U')
465
-            : '';
466
-        update_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, $date_to_save);
467
-    }
468
-
469
-
470
-    /**
471
-     * Used to get the saved offset range end date.
472
-     * @return DbSafeDateTime|null
473
-     */
474
-    public static function getEndDateRange()
475
-    {
476
-        $end_date = get_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, null);
477
-        try {
478
-            $datetime = DateTime::createFromFormat('U', $end_date, new DateTimeZone('UTC'));
479
-            $end_date = $datetime instanceof Datetime
480
-                ? DbSafeDateTime::createFromDateTime($datetime)
481
-                : null;
482
-        } catch (Exception $e) {
483
-            $end_date = null;
484
-        }
485
-        return $end_date;
486
-    }
29
+	/**
30
+	 * Key for the option used to track which models have been processed when doing the batches.
31
+	 */
32
+	const MODELS_TO_PROCESS_OPTION_KEY = 'ee_models_processed_for_datetime_offset_fix';
33
+
34
+
35
+	const COUNT_OF_MODELS_PROCESSED = 'ee_count_of_ee_models_processed_for_datetime_offset_fixed';
36
+
37
+	/**
38
+	 * Key for the option used to track what the current offset is that will be applied when this tool is executed.
39
+	 */
40
+	const OFFSET_TO_APPLY_OPTION_KEY = 'ee_datetime_offset_fix_offset_to_apply';
41
+
42
+
43
+	const OPTION_KEY_OFFSET_RANGE_START_DATE = 'ee_datetime_offset_start_date_range';
44
+
45
+
46
+	const OPTION_KEY_OFFSET_RANGE_END_DATE = 'ee_datetime_offset_end_date_range';
47
+
48
+
49
+	/**
50
+	 * String labelling the datetime offset fix type for change-log entries.
51
+	 */
52
+	const DATETIME_OFFSET_FIX_CHANGELOG_TYPE = 'datetime_offset_fix';
53
+
54
+
55
+	/**
56
+	 * String labelling a datetime offset fix error for change-log entries.
57
+	 */
58
+	const DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE = 'datetime_offset_fix_error';
59
+
60
+	/**
61
+	 * @var EEM_Base[]
62
+	 */
63
+	protected $models_with_datetime_fields = array();
64
+
65
+
66
+	/**
67
+	 * Performs any necessary setup for starting the job. This is also a good
68
+	 * place to setup the $job_arguments which will be used for subsequent HTTP requests
69
+	 * when continue_job will be called
70
+	 *
71
+	 * @param JobParameters $job_parameters
72
+	 * @return JobStepResponse
73
+	 * @throws EE_Error
74
+	 * @throws InvalidArgumentException
75
+	 * @throws InvalidDataTypeException
76
+	 * @throws InvalidInterfaceException
77
+	 */
78
+	public function create_job(JobParameters $job_parameters)
79
+	{
80
+		$models_with_datetime_fields = $this->getModelsWithDatetimeFields();
81
+		//we'll be doing each model as a batch.
82
+		$job_parameters->set_job_size(count($models_with_datetime_fields));
83
+		return new JobStepResponse(
84
+			$job_parameters,
85
+			esc_html__('Starting Datetime Offset Fix', 'event_espresso')
86
+		);
87
+	}
88
+
89
+	/**
90
+	 * Performs another step of the job
91
+	 *
92
+	 * @param JobParameters $job_parameters
93
+	 * @param int           $batch_size
94
+	 * @return JobStepResponse
95
+	 * @throws EE_Error
96
+	 * @throws InvalidArgumentException
97
+	 * @throws InvalidDataTypeException
98
+	 * @throws InvalidInterfaceException
99
+	 */
100
+	public function continue_job(JobParameters $job_parameters, $batch_size = 50)
101
+	{
102
+		$models_to_process = $this->getModelsWithDatetimeFields();
103
+		//let's pop off the a model and do the query to apply the offset.
104
+		$model_to_process = array_pop($models_to_process);
105
+		//update our record
106
+		$this->setModelsToProcess($models_to_process);
107
+		$this->processModel($model_to_process);
108
+		$this->updateCountOfModelsProcessed();
109
+		$job_parameters->set_units_processed($this->getCountOfModelsProcessed());
110
+		if (count($models_to_process) > 0) {
111
+			$job_parameters->set_status(JobParameters::status_continue);
112
+		} else {
113
+			$job_parameters->set_status(JobParameters::status_complete);
114
+		}
115
+		return new JobStepResponse(
116
+			$job_parameters,
117
+			sprintf(
118
+				esc_html__('Updated the offset for all datetime fields on the %s model.', 'event_espresso'),
119
+				$model_to_process
120
+			)
121
+		);
122
+	}
123
+
124
+	/**
125
+	 * Performs any clean-up logic when we know the job is completed
126
+	 *
127
+	 * @param JobParameters $job_parameters
128
+	 * @return JobStepResponse
129
+	 * @throws BatchRequestException
130
+	 */
131
+	public function cleanup_job(JobParameters $job_parameters)
132
+	{
133
+		//delete important saved options.
134
+		delete_option(self::MODELS_TO_PROCESS_OPTION_KEY);
135
+		delete_option(self::COUNT_OF_MODELS_PROCESSED);
136
+		delete_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE);
137
+		delete_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE);
138
+		return new JobStepResponse($job_parameters, esc_html__(
139
+			'Offset has been applied to all affected fields.',
140
+			'event_espresso'
141
+		));
142
+	}
143
+
144
+
145
+	/**
146
+	 * Contains the logic for processing a model and applying the datetime offset to affected fields on that model.
147
+	 * @param string $model_class_name
148
+	 * @throws EE_Error
149
+	 */
150
+	protected function processModel($model_class_name)
151
+	{
152
+		global $wpdb;
153
+		/** @var EEM_Base $model */
154
+		$model = $model_class_name::instance();
155
+		$original_offset = self::getOffset();
156
+		$start_date_range = self::getStartDateRange();
157
+		$end_date_range = self::getEndDateRange();
158
+		$sql_date_function = $original_offset > 0 ? 'DATE_ADD' : 'DATE_SUB';
159
+		$offset = abs($original_offset) * 60;
160
+		$date_ranges = array();
161
+		//since some affected models might have two tables, we have to get our tables and set up a query for each table.
162
+		foreach ($model->get_tables() as $table) {
163
+			$query = 'UPDATE ' . $table->get_table_name();
164
+			$fields_affected = array();
165
+			$inner_query = array();
166
+			foreach ($model->_get_fields_for_table($table->get_table_alias()) as $model_field) {
167
+				if ($model_field instanceof EE_Datetime_Field) {
168
+					$inner_query[$model_field->get_table_column()] = $model_field->get_table_column() . ' = '
169
+									 . $sql_date_function . '('
170
+									 . $model_field->get_table_column()
171
+									 . ", INTERVAL {$offset} MINUTE)";
172
+					$fields_affected[] = $model_field;
173
+				}
174
+			}
175
+			if (! $fields_affected) {
176
+				continue;
177
+			}
178
+			//do we do one query per column/field or one query for all fields on the model? It all depends on whether
179
+			//there is a date range applied or not.
180
+			if ($start_date_range instanceof DbSafeDateTime || $end_date_range instanceof DbSafeDateTime) {
181
+				$result = $this->doQueryForEachField($query, $inner_query, $start_date_range, $end_date_range);
182
+			} else {
183
+				$result = $this->doQueryForAllFields($query, $inner_query);
184
+			}
185
+
186
+			//record appropriate logs for the query
187
+			switch (true) {
188
+				case $result === false:
189
+					//record error.
190
+					$error_message = $wpdb->last_error;
191
+					//handle the edgecases where last_error might be empty.
192
+					if (! $error_message) {
193
+						$error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
194
+					}
195
+					$this->recordChangeLog($model, $original_offset, $table, $fields_affected, $error_message);
196
+					break;
197
+				case is_array($result) && ! empty($result):
198
+					foreach ($result as $field_name => $error_message) {
199
+						$this->recordChangeLog($model, $original_offset, $table, array($field_name), $error_message);
200
+					}
201
+					break;
202
+				default:
203
+					$this->recordChangeLog($model, $original_offset, $table, $fields_affected);
204
+			}
205
+		}
206
+	}
207
+
208
+
209
+	/**
210
+	 * Does the query on each $inner_query individually.
211
+	 *
212
+	 * @param string              $query
213
+	 * @param array               $inner_query
214
+	 * @param DbSafeDateTime|null $start_date_range
215
+	 * @param DbSafeDateTime|null $end_date_range
216
+	 * @return array  An array of any errors encountered and the fields they were for.
217
+	 */
218
+	private function doQueryForEachField($query, array $inner_query, $start_date_range, $end_date_range)
219
+	{
220
+		global $wpdb;
221
+		$errors = array();
222
+		foreach ($inner_query as $field_name => $field_query) {
223
+			$query_to_run = $query;
224
+			$where_conditions = array();
225
+			$query_to_run .= ' SET ' . $field_query;
226
+			if ($start_date_range instanceof DbSafeDateTime) {
227
+				$start_date = $start_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
228
+				$where_conditions[] = "{$field_name} > '{$start_date}'";
229
+			}
230
+			if ($end_date_range instanceof DbSafeDateTime) {
231
+				$end_date = $end_date_range->format(EE_Datetime_Field::mysql_timestamp_format);
232
+				$where_conditions[] = "{$field_name} < '{$end_date}'";
233
+			}
234
+			if ($where_conditions) {
235
+				$query_to_run .= ' WHERE ' . implode(' AND ', $where_conditions);
236
+			}
237
+			$result = $wpdb->query($query_to_run);
238
+			if ($result === false) {
239
+				//record error.
240
+				$error_message = $wpdb->last_error;
241
+				//handle the edgecases where last_error might be empty.
242
+				if (! $error_message) {
243
+					$error_message = esc_html__('Unknown mysql error occured.', 'event_espresso');
244
+				}
245
+				$errors[$field_name] = $error_message;
246
+			}
247
+		}
248
+		return $errors;
249
+	}
250
+
251
+
252
+	/**
253
+	 * Performs the query for all fields within the inner_query
254
+	 *
255
+	 * @param string $query
256
+	 * @param array  $inner_query
257
+	 * @return false|int
258
+	 */
259
+	private function doQueryForAllFields($query, array $inner_query)
260
+	{
261
+		global $wpdb;
262
+		$query .= ' SET ' . implode(',', $inner_query);
263
+		return $wpdb->query($query);
264
+	}
265
+
266
+
267
+	/**
268
+	 * Records a changelog entry using the given information.
269
+	 *
270
+	 * @param EEM_Base              $model
271
+	 * @param float                 $offset
272
+	 * @param EE_Table_Base         $table
273
+	 * @param EE_Model_Field_Base[] $model_fields_affected
274
+	 * @param string                $error_message   If present then there was an error so let's record that instead.
275
+	 * @throws EE_Error
276
+	 */
277
+	private function recordChangeLog(
278
+		EEM_Base $model,
279
+		$offset,
280
+		EE_Table_Base $table,
281
+		$model_fields_affected,
282
+		$error_message = ''
283
+	) {
284
+		//setup $fields list.
285
+		$fields = array();
286
+		/** @var EE_Datetime_Field $model_field */
287
+		foreach ($model_fields_affected as $model_field) {
288
+			if (! $model_field instanceof EE_Datetime_Field) {
289
+				continue;
290
+			}
291
+			$fields[] = $model_field->get_name();
292
+		}
293
+		//setup the message for the changelog entry.
294
+		$message = $error_message
295
+			? sprintf(
296
+				esc_html__(
297
+					'The %1$s table for the %2$s model did not have the offset of %3$f applied to its fields (%4$s), because of the following error:%5$s',
298
+					'event_espresso'
299
+				),
300
+				$table->get_table_name(),
301
+				$model->get_this_model_name(),
302
+				$offset,
303
+				implode(',', $fields),
304
+				$error_message
305
+			)
306
+			: sprintf(
307
+				esc_html__(
308
+					'The %1$s table for the %2$s model has had the offset of %3$f applied to its following fields: %4$s',
309
+					'event_espresso'
310
+				),
311
+				$table->get_table_name(),
312
+				$model->get_this_model_name(),
313
+				$offset,
314
+				implode(',', $fields)
315
+			);
316
+		//write to the log
317
+		$changelog = EE_Change_Log::new_instance(array(
318
+			'LOG_type' => $error_message
319
+				? self::DATETIME_OFFSET_FIX_CHANGELOG_ERROR_TYPE
320
+				: self::DATETIME_OFFSET_FIX_CHANGELOG_TYPE,
321
+			'LOG_message' => $message
322
+		));
323
+		$changelog->save();
324
+	}
325
+
326
+
327
+	/**
328
+	 * Returns an array of models that have datetime fields.
329
+	 * This array is added to a short lived transient cache to keep having to build this list to a minimum.
330
+	 *
331
+	 * @return array an array of model class names.
332
+	 * @throws EE_Error
333
+	 * @throws InvalidDataTypeException
334
+	 * @throws InvalidInterfaceException
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	private function getModelsWithDatetimeFields()
338
+	{
339
+		$this->getModelsToProcess();
340
+		if (! empty($this->models_with_datetime_fields)) {
341
+			return $this->models_with_datetime_fields;
342
+		}
343
+
344
+		$all_non_abstract_models = EE_Registry::instance()->non_abstract_db_models;
345
+		foreach ($all_non_abstract_models as $non_abstract_model) {
346
+			//get model instance
347
+			/** @var EEM_Base $non_abstract_model */
348
+			$non_abstract_model = $non_abstract_model::instance();
349
+			if ($non_abstract_model->get_a_field_of_type('EE_Datetime_Field') instanceof EE_Datetime_Field) {
350
+				$this->models_with_datetime_fields[] = get_class($non_abstract_model);
351
+			}
352
+		}
353
+		$this->setModelsToProcess($this->models_with_datetime_fields);
354
+		return $this->models_with_datetime_fields;
355
+	}
356
+
357
+
358
+	/**
359
+	 * This simply records the models that have been processed with our tracking option.
360
+	 * @param array $models_to_set  array of model class names.
361
+	 */
362
+	private function setModelsToProcess($models_to_set)
363
+	{
364
+		update_option(self::MODELS_TO_PROCESS_OPTION_KEY, $models_to_set);
365
+	}
366
+
367
+
368
+	/**
369
+	 * Used to keep track of how many models have been processed for the batch
370
+	 * @param $count
371
+	 */
372
+	private function updateCountOfModelsProcessed($count = 1)
373
+	{
374
+		$count = $this->getCountOfModelsProcessed() + (int) $count;
375
+		update_option(self::COUNT_OF_MODELS_PROCESSED, $count);
376
+	}
377
+
378
+
379
+	/**
380
+	 * Retrieve the tracked number of models processed between requests.
381
+	 * @return int
382
+	 */
383
+	private function getCountOfModelsProcessed()
384
+	{
385
+		return (int) get_option(self::COUNT_OF_MODELS_PROCESSED, 0);
386
+	}
387
+
388
+
389
+	/**
390
+	 * Returns the models that are left to process.
391
+	 * @return array  an array of model class names.
392
+	 */
393
+	private function getModelsToProcess()
394
+	{
395
+		if (empty($this->models_with_datetime_fields)) {
396
+			$this->models_with_datetime_fields = get_option(self::MODELS_TO_PROCESS_OPTION_KEY, array());
397
+		}
398
+		return $this->models_with_datetime_fields;
399
+	}
400
+
401
+
402
+	/**
403
+	 * Used to record the offset that will be applied to dates and times for EE_Datetime_Field columns.
404
+	 * @param float $offset
405
+	 */
406
+	public static function updateOffset($offset)
407
+	{
408
+		update_option(self::OFFSET_TO_APPLY_OPTION_KEY, $offset);
409
+	}
410
+
411
+
412
+	/**
413
+	 * Used to retrieve the saved offset that will be applied to dates and times for EE_Datetime_Field columns.
414
+	 *
415
+	 * @return float
416
+	 */
417
+	public static function getOffset()
418
+	{
419
+		return (float) get_option(self::OFFSET_TO_APPLY_OPTION_KEY, 0);
420
+	}
421
+
422
+
423
+	/**
424
+	 * Used to set the saved offset range start date.
425
+	 * @param DbSafeDateTime|null $start_date
426
+	 */
427
+	public static function updateStartDateRange(DbSafeDateTime $start_date = null)
428
+	{
429
+		$date_to_save = $start_date instanceof DbSafeDateTime
430
+			? $start_date->format('U')
431
+			: '';
432
+		update_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, $date_to_save);
433
+	}
434
+
435
+
436
+	/**
437
+	 * Used to get the saved offset range start date.
438
+	 * @return DbSafeDateTime|null
439
+	 */
440
+	public static function getStartDateRange()
441
+	{
442
+		$start_date = get_option(self::OPTION_KEY_OFFSET_RANGE_START_DATE, null);
443
+		try {
444
+			$datetime = DateTime::createFromFormat('U', $start_date, new DateTimeZone('UTC'));
445
+			$start_date = $datetime instanceof DateTime
446
+				? DbSafeDateTime::createFromDateTime($datetime)
447
+				: null;
448
+
449
+		} catch (Exception $e) {
450
+			$start_date = null;
451
+		}
452
+		return $start_date;
453
+	}
454
+
455
+
456
+
457
+	/**
458
+	 * Used to set the saved offset range end date.
459
+	 * @param DbSafeDateTime|null $end_date
460
+	 */
461
+	public static function updateEndDateRange(DbSafeDateTime $end_date = null)
462
+	{
463
+		$date_to_save = $end_date instanceof DbSafeDateTime
464
+			? $end_date->format('U')
465
+			: '';
466
+		update_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, $date_to_save);
467
+	}
468
+
469
+
470
+	/**
471
+	 * Used to get the saved offset range end date.
472
+	 * @return DbSafeDateTime|null
473
+	 */
474
+	public static function getEndDateRange()
475
+	{
476
+		$end_date = get_option(self::OPTION_KEY_OFFSET_RANGE_END_DATE, null);
477
+		try {
478
+			$datetime = DateTime::createFromFormat('U', $end_date, new DateTimeZone('UTC'));
479
+			$end_date = $datetime instanceof Datetime
480
+				? DbSafeDateTime::createFromDateTime($datetime)
481
+				: null;
482
+		} catch (Exception $e) {
483
+			$end_date = null;
484
+		}
485
+		return $end_date;
486
+	}
487 487
 }
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 1 patch
Indentation   +800 added lines, -800 removed lines patch added patch discarded remove patch
@@ -5,7 +5,7 @@  discard block
 block discarded – undo
5 5
 use EventEspresso\core\services\loaders\LoaderInterface;
6 6
 
7 7
 if (! defined('EVENT_ESPRESSO_VERSION')) {
8
-    exit('No direct script access allowed');
8
+	exit('No direct script access allowed');
9 9
 }
10 10
 
11 11
 
@@ -22,805 +22,805 @@  discard block
 block discarded – undo
22 22
 class EE_Dependency_Map
23 23
 {
24 24
 
25
-    /**
26
-     * This means that the requested class dependency is not present in the dependency map
27
-     */
28
-    const not_registered = 0;
29
-
30
-    /**
31
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
32
-     */
33
-    const load_new_object = 1;
34
-
35
-    /**
36
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
37
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
38
-     */
39
-    const load_from_cache = 2;
40
-
41
-    /**
42
-     * When registering a dependency,
43
-     * this indicates to keep any existing dependencies that already exist,
44
-     * and simply discard any new dependencies declared in the incoming data
45
-     */
46
-    const KEEP_EXISTING_DEPENDENCIES = 0;
47
-
48
-    /**
49
-     * When registering a dependency,
50
-     * this indicates to overwrite any existing dependencies that already exist using the incoming data
51
-     */
52
-    const OVERWRITE_DEPENDENCIES = 1;
53
-
54
-
55
-
56
-    /**
57
-     * @type EE_Dependency_Map $_instance
58
-     */
59
-    protected static $_instance;
60
-
61
-    /**
62
-     * @type EE_Request $request
63
-     */
64
-    protected $_request;
65
-
66
-    /**
67
-     * @type EE_Response $response
68
-     */
69
-    protected $_response;
70
-
71
-    /**
72
-     * @type LoaderInterface $loader
73
-     */
74
-    protected $loader;
75
-
76
-    /**
77
-     * @type array $_dependency_map
78
-     */
79
-    protected $_dependency_map = array();
80
-
81
-    /**
82
-     * @type array $_class_loaders
83
-     */
84
-    protected $_class_loaders = array();
85
-
86
-    /**
87
-     * @type array $_aliases
88
-     */
89
-    protected $_aliases = array();
90
-
91
-
92
-
93
-    /**
94
-     * EE_Dependency_Map constructor.
95
-     *
96
-     * @param EE_Request  $request
97
-     * @param EE_Response $response
98
-     */
99
-    protected function __construct(EE_Request $request, EE_Response $response)
100
-    {
101
-        $this->_request = $request;
102
-        $this->_response = $response;
103
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
104
-        do_action('EE_Dependency_Map____construct');
105
-    }
106
-
107
-
108
-
109
-    /**
110
-     * @throws InvalidDataTypeException
111
-     * @throws InvalidInterfaceException
112
-     * @throws InvalidArgumentException
113
-     */
114
-    public function initialize()
115
-    {
116
-        $this->_register_core_dependencies();
117
-        $this->_register_core_class_loaders();
118
-        $this->_register_core_aliases();
119
-    }
120
-
121
-
122
-
123
-    /**
124
-     * @singleton method used to instantiate class object
125
-     * @access    public
126
-     * @param EE_Request  $request
127
-     * @param EE_Response $response
128
-     * @return EE_Dependency_Map
129
-     */
130
-    public static function instance(EE_Request $request = null, EE_Response $response = null)
131
-    {
132
-        // check if class object is instantiated, and instantiated properly
133
-        if (! self::$_instance instanceof EE_Dependency_Map) {
134
-            self::$_instance = new EE_Dependency_Map($request, $response);
135
-        }
136
-        return self::$_instance;
137
-    }
138
-
139
-
140
-
141
-    /**
142
-     * @param LoaderInterface $loader
143
-     */
144
-    public function setLoader(LoaderInterface $loader)
145
-    {
146
-        $this->loader = $loader;
147
-    }
148
-
149
-
150
-
151
-    /**
152
-     * @param string $class
153
-     * @param array  $dependencies
154
-     * @param int    $overwrite
155
-     * @return bool
156
-     */
157
-    public static function register_dependencies(
158
-        $class,
159
-        array $dependencies,
160
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
161
-    ) {
162
-        return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
163
-    }
164
-
165
-
166
-
167
-    /**
168
-     * Assigns an array of class names and corresponding load sources (new or cached)
169
-     * to the class specified by the first parameter.
170
-     * IMPORTANT !!!
171
-     * The order of elements in the incoming $dependencies array MUST match
172
-     * the order of the constructor parameters for the class in question.
173
-     * This is especially important when overriding any existing dependencies that are registered.
174
-     * the third parameter controls whether any duplicate dependencies are overwritten or not.
175
-     *
176
-     * @param string $class
177
-     * @param array  $dependencies
178
-     * @param int    $overwrite
179
-     * @return bool
180
-     */
181
-    public function registerDependencies(
182
-        $class,
183
-        array $dependencies,
184
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
185
-    ) {
186
-        $class = trim($class, '\\');
187
-        $registered = false;
188
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
189
-            self::$_instance->_dependency_map[ $class ] = array();
190
-        }
191
-        // we need to make sure that any aliases used when registering a dependency
192
-        // get resolved to the correct class name
193
-        foreach ((array)$dependencies as $dependency => $load_source) {
194
-            $alias = self::$_instance->get_alias($dependency);
195
-            if (
196
-                $overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
197
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
198
-            ) {
199
-                unset($dependencies[$dependency]);
200
-                $dependencies[$alias] = $load_source;
201
-                $registered = true;
202
-            }
203
-        }
204
-        // now add our two lists of dependencies together.
205
-        // using Union (+=) favours the arrays in precedence from left to right,
206
-        // so $dependencies is NOT overwritten because it is listed first
207
-        // ie: with A = B + C, entries in B take precedence over duplicate entries in C
208
-        // Union is way faster than array_merge() but should be used with caution...
209
-        // especially with numerically indexed arrays
210
-        $dependencies += self::$_instance->_dependency_map[ $class ];
211
-        // now we need to ensure that the resulting dependencies
212
-        // array only has the entries that are required for the class
213
-        // so first count how many dependencies were originally registered for the class
214
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
215
-        // if that count is non-zero (meaning dependencies were already registered)
216
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
217
-            // then truncate the  final array to match that count
218
-            ? array_slice($dependencies, 0, $dependency_count)
219
-            // otherwise just take the incoming array because nothing previously existed
220
-            : $dependencies;
221
-        return $registered;
222
-    }
223
-
224
-
225
-
226
-    /**
227
-     * @param string $class_name
228
-     * @param string $loader
229
-     * @return bool
230
-     * @throws DomainException
231
-     */
232
-    public static function register_class_loader($class_name, $loader = 'load_core')
233
-    {
234
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
235
-            throw new DomainException(
236
-                esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
237
-            );
238
-        }
239
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
240
-        if (
241
-            ! is_callable($loader)
242
-            && (
243
-                strpos($loader, 'load_') !== 0
244
-                || ! method_exists('EE_Registry', $loader)
245
-            )
246
-        ) {
247
-            throw new DomainException(
248
-                sprintf(
249
-                    esc_html__(
250
-                        '"%1$s" is not a valid loader method on EE_Registry.',
251
-                        'event_espresso'
252
-                    ),
253
-                    $loader
254
-                )
255
-            );
256
-        }
257
-        $class_name = self::$_instance->get_alias($class_name);
258
-        if (! isset(self::$_instance->_class_loaders[$class_name])) {
259
-            self::$_instance->_class_loaders[$class_name] = $loader;
260
-            return true;
261
-        }
262
-        return false;
263
-    }
264
-
265
-
266
-
267
-    /**
268
-     * @return array
269
-     */
270
-    public function dependency_map()
271
-    {
272
-        return $this->_dependency_map;
273
-    }
274
-
275
-
276
-
277
-    /**
278
-     * returns TRUE if dependency map contains a listing for the provided class name
279
-     *
280
-     * @param string $class_name
281
-     * @return boolean
282
-     */
283
-    public function has($class_name = '')
284
-    {
285
-        // all legacy models have the same dependencies
286
-        if (strpos($class_name, 'EEM_') === 0) {
287
-            $class_name = 'LEGACY_MODELS';
288
-        }
289
-        return isset($this->_dependency_map[$class_name]) ? true : false;
290
-    }
291
-
292
-
293
-
294
-    /**
295
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
296
-     *
297
-     * @param string $class_name
298
-     * @param string $dependency
299
-     * @return bool
300
-     */
301
-    public function has_dependency_for_class($class_name = '', $dependency = '')
302
-    {
303
-        // all legacy models have the same dependencies
304
-        if (strpos($class_name, 'EEM_') === 0) {
305
-            $class_name = 'LEGACY_MODELS';
306
-        }
307
-        $dependency = $this->get_alias($dependency);
308
-        return isset($this->_dependency_map[$class_name], $this->_dependency_map[$class_name][$dependency])
309
-            ? true
310
-            : false;
311
-    }
312
-
313
-
314
-
315
-    /**
316
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
317
-     *
318
-     * @param string $class_name
319
-     * @param string $dependency
320
-     * @return int
321
-     */
322
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
323
-    {
324
-        // all legacy models have the same dependencies
325
-        if (strpos($class_name, 'EEM_') === 0) {
326
-            $class_name = 'LEGACY_MODELS';
327
-        }
328
-        $dependency = $this->get_alias($dependency);
329
-        return $this->has_dependency_for_class($class_name, $dependency)
330
-            ? $this->_dependency_map[$class_name][$dependency]
331
-            : EE_Dependency_Map::not_registered;
332
-    }
333
-
334
-
335
-
336
-    /**
337
-     * @param string $class_name
338
-     * @return string | Closure
339
-     */
340
-    public function class_loader($class_name)
341
-    {
342
-        // all legacy models use load_model()
343
-        if(strpos($class_name, 'EEM_') === 0){
344
-            return 'load_model';
345
-        }
346
-        $class_name = $this->get_alias($class_name);
347
-        return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
348
-    }
349
-
350
-
351
-
352
-    /**
353
-     * @return array
354
-     */
355
-    public function class_loaders()
356
-    {
357
-        return $this->_class_loaders;
358
-    }
359
-
360
-
361
-
362
-    /**
363
-     * adds an alias for a classname
364
-     *
365
-     * @param string $class_name the class name that should be used (concrete class to replace interface)
366
-     * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
367
-     * @param string $for_class  the class that has the dependency (is type hinting for the interface)
368
-     */
369
-    public function add_alias($class_name, $alias, $for_class = '')
370
-    {
371
-        if ($for_class !== '') {
372
-            if (! isset($this->_aliases[$for_class])) {
373
-                $this->_aliases[$for_class] = array();
374
-            }
375
-            $this->_aliases[$for_class][$class_name] = $alias;
376
-        }
377
-        $this->_aliases[$class_name] = $alias;
378
-    }
379
-
380
-
381
-
382
-    /**
383
-     * returns TRUE if the provided class name has an alias
384
-     *
385
-     * @param string $class_name
386
-     * @param string $for_class
387
-     * @return bool
388
-     */
389
-    public function has_alias($class_name = '', $for_class = '')
390
-    {
391
-        return isset($this->_aliases[$for_class], $this->_aliases[$for_class][$class_name])
392
-               || (
393
-                   isset($this->_aliases[$class_name])
394
-                   && ! is_array($this->_aliases[$class_name])
395
-               );
396
-    }
397
-
398
-
399
-
400
-    /**
401
-     * returns alias for class name if one exists, otherwise returns the original classname
402
-     * functions recursively, so that multiple aliases can be used to drill down to a classname
403
-     *  for example:
404
-     *      if the following two entries were added to the _aliases array:
405
-     *          array(
406
-     *              'interface_alias'           => 'some\namespace\interface'
407
-     *              'some\namespace\interface'  => 'some\namespace\classname'
408
-     *          )
409
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
410
-     *      to load an instance of 'some\namespace\classname'
411
-     *
412
-     * @param string $class_name
413
-     * @param string $for_class
414
-     * @return string
415
-     */
416
-    public function get_alias($class_name = '', $for_class = '')
417
-    {
418
-        if (! $this->has_alias($class_name, $for_class)) {
419
-            return $class_name;
420
-        }
421
-        if ($for_class !== '' && isset($this->_aliases[ $for_class ][ $class_name ])) {
422
-            return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
423
-        }
424
-        return $this->get_alias($this->_aliases[$class_name]);
425
-    }
426
-
427
-
428
-
429
-    /**
430
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
431
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
432
-     * This is done by using the following class constants:
433
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
434
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
435
-     */
436
-    protected function _register_core_dependencies()
437
-    {
438
-        $this->_dependency_map = array(
439
-            'EE_Request_Handler'                                                                                          => array(
440
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
441
-            ),
442
-            'EE_System'                                                                                                   => array(
443
-                'EE_Registry'                                => EE_Dependency_Map::load_from_cache,
444
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
445
-                'EE_Capabilities'                            => EE_Dependency_Map::load_from_cache,
446
-                'EE_Request'                                 => EE_Dependency_Map::load_from_cache,
447
-                'EE_Maintenance_Mode'                        => EE_Dependency_Map::load_from_cache,
448
-            ),
449
-            'EE_Session'                                                                                                  => array(
450
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
451
-                'EE_Encryption'                                           => EE_Dependency_Map::load_from_cache,
452
-            ),
453
-            'EE_Cart'                                                                                                     => array(
454
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
455
-            ),
456
-            'EE_Front_Controller'                                                                                         => array(
457
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
458
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
459
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
460
-            ),
461
-            'EE_Messenger_Collection_Loader'                                                                              => array(
462
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
463
-            ),
464
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
465
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
466
-            ),
467
-            'EE_Message_Resource_Manager'                                                                                 => array(
468
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
469
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
470
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
471
-            ),
472
-            'EE_Message_Factory'                                                                                          => array(
473
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
474
-            ),
475
-            'EE_messages'                                                                                                 => array(
476
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
477
-            ),
478
-            'EE_Messages_Generator'                                                                                       => array(
479
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
480
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
481
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
482
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
483
-            ),
484
-            'EE_Messages_Processor'                                                                                       => array(
485
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
-            ),
487
-            'EE_Messages_Queue'                                                                                           => array(
488
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
489
-            ),
490
-            'EE_Messages_Template_Defaults'                                                                               => array(
491
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
492
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
493
-            ),
494
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
495
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
496
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
497
-            ),
498
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
499
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
500
-            ),
501
-            'EventEspresso\services\commands\CommandHandler'                                                              => array(
502
-                'EE_Registry'         => EE_Dependency_Map::load_from_cache,
503
-                'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
504
-            ),
505
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
506
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
507
-            ),
508
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
509
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
510
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
511
-            ),
512
-            'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
513
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
514
-            ),
515
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
516
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
517
-            ),
518
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
519
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
520
-            ),
521
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
522
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
523
-            ),
524
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
525
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
526
-            ),
527
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
528
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
529
-            ),
530
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
531
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
532
-            ),
533
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
534
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
535
-            ),
536
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
537
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
538
-            ),
539
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
540
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
541
-            ),
542
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
543
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
-            ),
545
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
546
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
547
-            ),
548
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
549
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
550
-            ),
551
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
552
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
553
-            ),
554
-            'EE_Data_Migration_Class_Base'                                                                                => array(
555
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
556
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
557
-            ),
558
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
559
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
560
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
561
-            ),
562
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
563
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
564
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
565
-            ),
566
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
567
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
568
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
569
-            ),
570
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
571
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
572
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
573
-            ),
574
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
575
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
576
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
577
-            ),
578
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
579
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
580
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
581
-            ),
582
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
583
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
584
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
585
-            ),
586
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
587
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
588
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
589
-            ),
590
-            'EE_DMS_Core_4_9_0'                                                                                           => array(
591
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
592
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
593
-            ),
594
-            'EventEspresso\core\services\assets\Registry'                                                                 => array(
595
-                'EE_Template_Config' => EE_Dependency_Map::load_from_cache,
596
-                'EE_Currency_Config' => EE_Dependency_Map::load_from_cache,
597
-            ),
598
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
599
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
600
-            ),
601
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
602
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
603
-            ),
604
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
605
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
606
-            ),
607
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
608
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
609
-            ),
610
-            'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
611
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
612
-            ),
613
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
614
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
615
-            ),
616
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
617
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
-            ),
619
-            'EventEspresso\core\services\cache\BasicCacheManager'                        => array(
620
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
621
-            ),
622
-            'EventEspresso\core\services\cache\PostRelatedCacheManager'                  => array(
623
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
624
-            ),
625
-            'EventEspresso\core\domain\services\validation\email\EmailValidationService' => array(
626
-                'EE_Registration_Config'                                  => EE_Dependency_Map::load_from_cache,
627
-                'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
628
-            ),
629
-            'EventEspresso\core\domain\values\EmailAddress'                              => array(
630
-                null,
631
-                'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
632
-            ),
633
-            'EventEspresso\core\services\orm\ModelFieldFactory' => array(
634
-                'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
635
-            ),
636
-            'LEGACY_MODELS'                                                   => array(
637
-                null,
638
-                'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
639
-            ),
640
-            'EE_Module_Request_Router' => array(
641
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
642
-            ),
643
-            'EE_Registration_Processor' => array(
644
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
645
-            ),
646
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' => array(
647
-                null,
648
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
649
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
650
-            ),
651
-        );
652
-    }
653
-
654
-
655
-
656
-    /**
657
-     * Registers how core classes are loaded.
658
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
659
-     *        'EE_Request_Handler' => 'load_core'
660
-     *        'EE_Messages_Queue'  => 'load_lib'
661
-     *        'EEH_Debug_Tools'    => 'load_helper'
662
-     * or, if greater control is required, by providing a custom closure. For example:
663
-     *        'Some_Class' => function () {
664
-     *            return new Some_Class();
665
-     *        },
666
-     * This is required for instantiating dependencies
667
-     * where an interface has been type hinted in a class constructor. For example:
668
-     *        'Required_Interface' => function () {
669
-     *            return new A_Class_That_Implements_Required_Interface();
670
-     *        },
671
-     *
672
-     * @throws InvalidInterfaceException
673
-     * @throws InvalidDataTypeException
674
-     * @throws InvalidArgumentException
675
-     */
676
-    protected function _register_core_class_loaders()
677
-    {
678
-        //for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
679
-        //be used in a closure.
680
-        $request = &$this->_request;
681
-        $response = &$this->_response;
682
-        // $loader = &$this->loader;
683
-        $this->_class_loaders = array(
684
-            //load_core
685
-            'EE_Capabilities'                      => 'load_core',
686
-            'EE_Encryption'                        => 'load_core',
687
-            'EE_Front_Controller'                  => 'load_core',
688
-            'EE_Module_Request_Router'             => 'load_core',
689
-            'EE_Registry'                          => 'load_core',
690
-            'EE_Request'                           => function () use (&$request) {
691
-                return $request;
692
-            },
693
-            'EE_Response'                          => function () use (&$response) {
694
-                return $response;
695
-            },
696
-            'EE_Request_Handler'                   => 'load_core',
697
-            'EE_Session'                           => 'load_core',
698
-            'EE_Cron_Tasks'                        => 'load_core',
699
-            'EE_System'                            => 'load_core',
700
-            'EE_Maintenance_Mode'                  => 'load_core',
701
-            'EE_Register_CPTs'                     => 'load_core',
702
-            'EE_Admin'                             => 'load_core',
703
-            //load_lib
704
-            'EE_Message_Resource_Manager'          => 'load_lib',
705
-            'EE_Message_Type_Collection'           => 'load_lib',
706
-            'EE_Message_Type_Collection_Loader'    => 'load_lib',
707
-            'EE_Messenger_Collection'              => 'load_lib',
708
-            'EE_Messenger_Collection_Loader'       => 'load_lib',
709
-            'EE_Messages_Processor'                => 'load_lib',
710
-            'EE_Message_Repository'                => 'load_lib',
711
-            'EE_Messages_Queue'                    => 'load_lib',
712
-            'EE_Messages_Data_Handler_Collection'  => 'load_lib',
713
-            'EE_Message_Template_Group_Collection' => 'load_lib',
714
-            'EE_Payment_Method_Manager'            => 'load_lib',
715
-            'EE_Messages_Generator'                => function () {
716
-                return EE_Registry::instance()->load_lib(
717
-                    'Messages_Generator',
718
-                    array(),
719
-                    false,
720
-                    false
721
-                );
722
-            },
723
-            'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
724
-                return EE_Registry::instance()->load_lib(
725
-                    'Messages_Template_Defaults',
726
-                    $arguments,
727
-                    false,
728
-                    false
729
-                );
730
-            },
731
-            //load_model
732
-            // 'EEM_Attendee'                         => 'load_model',
733
-            // 'EEM_Message_Template_Group'           => 'load_model',
734
-            // 'EEM_Message_Template'                 => 'load_model',
735
-            //load_helper
736
-            'EEH_Parse_Shortcodes'                 => function () {
737
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
738
-                    return new EEH_Parse_Shortcodes();
739
-                }
740
-                return null;
741
-            },
742
-            'EE_Template_Config'                   => function () {
743
-                return EE_Config::instance()->template_settings;
744
-            },
745
-            'EE_Currency_Config'                   => function () {
746
-                return EE_Config::instance()->currency;
747
-            },
748
-            'EE_Registration_Config'                   => function () {
749
-                return EE_Config::instance()->registration;
750
-            },
751
-            'EventEspresso\core\services\loaders\Loader' => function () {
752
-                return LoaderFactory::getLoader();
753
-            },
754
-        );
755
-    }
756
-
757
-
758
-
759
-    /**
760
-     * can be used for supplying alternate names for classes,
761
-     * or for connecting interface names to instantiable classes
762
-     */
763
-    protected function _register_core_aliases()
764
-    {
765
-        $this->_aliases = array(
766
-            'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
767
-            'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
768
-            'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
769
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
770
-            'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
771
-            'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
772
-            'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
773
-            'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
774
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
775
-            'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
776
-            'CreateRegCodeCommandHandler'                                                  => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
777
-            'CreateRegUrlLinkCommandHandler'                                               => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
778
-            'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
779
-            'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
780
-            'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
781
-            'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
782
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
783
-            'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
784
-            'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
785
-            'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
786
-            'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
787
-            'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
788
-            'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
789
-            'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
790
-            'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
791
-            'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
792
-            'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
793
-            'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
794
-            'CommandFactoryInterface'                                                     => 'EventEspresso\core\services\commands\CommandFactoryInterface',
795
-            'EventEspresso\core\services\commands\CommandFactoryInterface'                => 'EventEspresso\core\services\commands\CommandFactory',
796
-            'EventEspresso\core\domain\services\session\SessionIdentifierInterface'       => 'EE_Session',
797
-            'EmailValidatorInterface'                                                     => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
798
-            'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface' => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
799
-            'NoticeConverterInterface'                                            => 'EventEspresso\core\services\notices\NoticeConverterInterface',
800
-            'EventEspresso\core\services\notices\NoticeConverterInterface'        => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
801
-            'NoticesContainerInterface'                                            => 'EventEspresso\core\services\notices\NoticesContainerInterface',
802
-            'EventEspresso\core\services\notices\NoticesContainerInterface'        => 'EventEspresso\core\services\notices\NoticesContainer',
803
-        );
804
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
805
-            $this->_aliases['EventEspresso\core\services\notices\NoticeConverterInterface'] = 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices';
806
-        }
807
-    }
808
-
809
-
810
-
811
-    /**
812
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
813
-     * request Primarily used by unit tests.
814
-     *
815
-     * @throws InvalidDataTypeException
816
-     * @throws InvalidInterfaceException
817
-     * @throws InvalidArgumentException
818
-     */
819
-    public function reset()
820
-    {
821
-        $this->_register_core_class_loaders();
822
-        $this->_register_core_dependencies();
823
-    }
25
+	/**
26
+	 * This means that the requested class dependency is not present in the dependency map
27
+	 */
28
+	const not_registered = 0;
29
+
30
+	/**
31
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
32
+	 */
33
+	const load_new_object = 1;
34
+
35
+	/**
36
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
37
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
38
+	 */
39
+	const load_from_cache = 2;
40
+
41
+	/**
42
+	 * When registering a dependency,
43
+	 * this indicates to keep any existing dependencies that already exist,
44
+	 * and simply discard any new dependencies declared in the incoming data
45
+	 */
46
+	const KEEP_EXISTING_DEPENDENCIES = 0;
47
+
48
+	/**
49
+	 * When registering a dependency,
50
+	 * this indicates to overwrite any existing dependencies that already exist using the incoming data
51
+	 */
52
+	const OVERWRITE_DEPENDENCIES = 1;
53
+
54
+
55
+
56
+	/**
57
+	 * @type EE_Dependency_Map $_instance
58
+	 */
59
+	protected static $_instance;
60
+
61
+	/**
62
+	 * @type EE_Request $request
63
+	 */
64
+	protected $_request;
65
+
66
+	/**
67
+	 * @type EE_Response $response
68
+	 */
69
+	protected $_response;
70
+
71
+	/**
72
+	 * @type LoaderInterface $loader
73
+	 */
74
+	protected $loader;
75
+
76
+	/**
77
+	 * @type array $_dependency_map
78
+	 */
79
+	protected $_dependency_map = array();
80
+
81
+	/**
82
+	 * @type array $_class_loaders
83
+	 */
84
+	protected $_class_loaders = array();
85
+
86
+	/**
87
+	 * @type array $_aliases
88
+	 */
89
+	protected $_aliases = array();
90
+
91
+
92
+
93
+	/**
94
+	 * EE_Dependency_Map constructor.
95
+	 *
96
+	 * @param EE_Request  $request
97
+	 * @param EE_Response $response
98
+	 */
99
+	protected function __construct(EE_Request $request, EE_Response $response)
100
+	{
101
+		$this->_request = $request;
102
+		$this->_response = $response;
103
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
104
+		do_action('EE_Dependency_Map____construct');
105
+	}
106
+
107
+
108
+
109
+	/**
110
+	 * @throws InvalidDataTypeException
111
+	 * @throws InvalidInterfaceException
112
+	 * @throws InvalidArgumentException
113
+	 */
114
+	public function initialize()
115
+	{
116
+		$this->_register_core_dependencies();
117
+		$this->_register_core_class_loaders();
118
+		$this->_register_core_aliases();
119
+	}
120
+
121
+
122
+
123
+	/**
124
+	 * @singleton method used to instantiate class object
125
+	 * @access    public
126
+	 * @param EE_Request  $request
127
+	 * @param EE_Response $response
128
+	 * @return EE_Dependency_Map
129
+	 */
130
+	public static function instance(EE_Request $request = null, EE_Response $response = null)
131
+	{
132
+		// check if class object is instantiated, and instantiated properly
133
+		if (! self::$_instance instanceof EE_Dependency_Map) {
134
+			self::$_instance = new EE_Dependency_Map($request, $response);
135
+		}
136
+		return self::$_instance;
137
+	}
138
+
139
+
140
+
141
+	/**
142
+	 * @param LoaderInterface $loader
143
+	 */
144
+	public function setLoader(LoaderInterface $loader)
145
+	{
146
+		$this->loader = $loader;
147
+	}
148
+
149
+
150
+
151
+	/**
152
+	 * @param string $class
153
+	 * @param array  $dependencies
154
+	 * @param int    $overwrite
155
+	 * @return bool
156
+	 */
157
+	public static function register_dependencies(
158
+		$class,
159
+		array $dependencies,
160
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
161
+	) {
162
+		return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
163
+	}
164
+
165
+
166
+
167
+	/**
168
+	 * Assigns an array of class names and corresponding load sources (new or cached)
169
+	 * to the class specified by the first parameter.
170
+	 * IMPORTANT !!!
171
+	 * The order of elements in the incoming $dependencies array MUST match
172
+	 * the order of the constructor parameters for the class in question.
173
+	 * This is especially important when overriding any existing dependencies that are registered.
174
+	 * the third parameter controls whether any duplicate dependencies are overwritten or not.
175
+	 *
176
+	 * @param string $class
177
+	 * @param array  $dependencies
178
+	 * @param int    $overwrite
179
+	 * @return bool
180
+	 */
181
+	public function registerDependencies(
182
+		$class,
183
+		array $dependencies,
184
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
185
+	) {
186
+		$class = trim($class, '\\');
187
+		$registered = false;
188
+		if (empty(self::$_instance->_dependency_map[ $class ])) {
189
+			self::$_instance->_dependency_map[ $class ] = array();
190
+		}
191
+		// we need to make sure that any aliases used when registering a dependency
192
+		// get resolved to the correct class name
193
+		foreach ((array)$dependencies as $dependency => $load_source) {
194
+			$alias = self::$_instance->get_alias($dependency);
195
+			if (
196
+				$overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
197
+				|| ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
198
+			) {
199
+				unset($dependencies[$dependency]);
200
+				$dependencies[$alias] = $load_source;
201
+				$registered = true;
202
+			}
203
+		}
204
+		// now add our two lists of dependencies together.
205
+		// using Union (+=) favours the arrays in precedence from left to right,
206
+		// so $dependencies is NOT overwritten because it is listed first
207
+		// ie: with A = B + C, entries in B take precedence over duplicate entries in C
208
+		// Union is way faster than array_merge() but should be used with caution...
209
+		// especially with numerically indexed arrays
210
+		$dependencies += self::$_instance->_dependency_map[ $class ];
211
+		// now we need to ensure that the resulting dependencies
212
+		// array only has the entries that are required for the class
213
+		// so first count how many dependencies were originally registered for the class
214
+		$dependency_count = count(self::$_instance->_dependency_map[ $class ]);
215
+		// if that count is non-zero (meaning dependencies were already registered)
216
+		self::$_instance->_dependency_map[ $class ] = $dependency_count
217
+			// then truncate the  final array to match that count
218
+			? array_slice($dependencies, 0, $dependency_count)
219
+			// otherwise just take the incoming array because nothing previously existed
220
+			: $dependencies;
221
+		return $registered;
222
+	}
223
+
224
+
225
+
226
+	/**
227
+	 * @param string $class_name
228
+	 * @param string $loader
229
+	 * @return bool
230
+	 * @throws DomainException
231
+	 */
232
+	public static function register_class_loader($class_name, $loader = 'load_core')
233
+	{
234
+		if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
235
+			throw new DomainException(
236
+				esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
237
+			);
238
+		}
239
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
240
+		if (
241
+			! is_callable($loader)
242
+			&& (
243
+				strpos($loader, 'load_') !== 0
244
+				|| ! method_exists('EE_Registry', $loader)
245
+			)
246
+		) {
247
+			throw new DomainException(
248
+				sprintf(
249
+					esc_html__(
250
+						'"%1$s" is not a valid loader method on EE_Registry.',
251
+						'event_espresso'
252
+					),
253
+					$loader
254
+				)
255
+			);
256
+		}
257
+		$class_name = self::$_instance->get_alias($class_name);
258
+		if (! isset(self::$_instance->_class_loaders[$class_name])) {
259
+			self::$_instance->_class_loaders[$class_name] = $loader;
260
+			return true;
261
+		}
262
+		return false;
263
+	}
264
+
265
+
266
+
267
+	/**
268
+	 * @return array
269
+	 */
270
+	public function dependency_map()
271
+	{
272
+		return $this->_dependency_map;
273
+	}
274
+
275
+
276
+
277
+	/**
278
+	 * returns TRUE if dependency map contains a listing for the provided class name
279
+	 *
280
+	 * @param string $class_name
281
+	 * @return boolean
282
+	 */
283
+	public function has($class_name = '')
284
+	{
285
+		// all legacy models have the same dependencies
286
+		if (strpos($class_name, 'EEM_') === 0) {
287
+			$class_name = 'LEGACY_MODELS';
288
+		}
289
+		return isset($this->_dependency_map[$class_name]) ? true : false;
290
+	}
291
+
292
+
293
+
294
+	/**
295
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
296
+	 *
297
+	 * @param string $class_name
298
+	 * @param string $dependency
299
+	 * @return bool
300
+	 */
301
+	public function has_dependency_for_class($class_name = '', $dependency = '')
302
+	{
303
+		// all legacy models have the same dependencies
304
+		if (strpos($class_name, 'EEM_') === 0) {
305
+			$class_name = 'LEGACY_MODELS';
306
+		}
307
+		$dependency = $this->get_alias($dependency);
308
+		return isset($this->_dependency_map[$class_name], $this->_dependency_map[$class_name][$dependency])
309
+			? true
310
+			: false;
311
+	}
312
+
313
+
314
+
315
+	/**
316
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
317
+	 *
318
+	 * @param string $class_name
319
+	 * @param string $dependency
320
+	 * @return int
321
+	 */
322
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
323
+	{
324
+		// all legacy models have the same dependencies
325
+		if (strpos($class_name, 'EEM_') === 0) {
326
+			$class_name = 'LEGACY_MODELS';
327
+		}
328
+		$dependency = $this->get_alias($dependency);
329
+		return $this->has_dependency_for_class($class_name, $dependency)
330
+			? $this->_dependency_map[$class_name][$dependency]
331
+			: EE_Dependency_Map::not_registered;
332
+	}
333
+
334
+
335
+
336
+	/**
337
+	 * @param string $class_name
338
+	 * @return string | Closure
339
+	 */
340
+	public function class_loader($class_name)
341
+	{
342
+		// all legacy models use load_model()
343
+		if(strpos($class_name, 'EEM_') === 0){
344
+			return 'load_model';
345
+		}
346
+		$class_name = $this->get_alias($class_name);
347
+		return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
348
+	}
349
+
350
+
351
+
352
+	/**
353
+	 * @return array
354
+	 */
355
+	public function class_loaders()
356
+	{
357
+		return $this->_class_loaders;
358
+	}
359
+
360
+
361
+
362
+	/**
363
+	 * adds an alias for a classname
364
+	 *
365
+	 * @param string $class_name the class name that should be used (concrete class to replace interface)
366
+	 * @param string $alias      the class name that would be type hinted for (abstract parent or interface)
367
+	 * @param string $for_class  the class that has the dependency (is type hinting for the interface)
368
+	 */
369
+	public function add_alias($class_name, $alias, $for_class = '')
370
+	{
371
+		if ($for_class !== '') {
372
+			if (! isset($this->_aliases[$for_class])) {
373
+				$this->_aliases[$for_class] = array();
374
+			}
375
+			$this->_aliases[$for_class][$class_name] = $alias;
376
+		}
377
+		$this->_aliases[$class_name] = $alias;
378
+	}
379
+
380
+
381
+
382
+	/**
383
+	 * returns TRUE if the provided class name has an alias
384
+	 *
385
+	 * @param string $class_name
386
+	 * @param string $for_class
387
+	 * @return bool
388
+	 */
389
+	public function has_alias($class_name = '', $for_class = '')
390
+	{
391
+		return isset($this->_aliases[$for_class], $this->_aliases[$for_class][$class_name])
392
+			   || (
393
+				   isset($this->_aliases[$class_name])
394
+				   && ! is_array($this->_aliases[$class_name])
395
+			   );
396
+	}
397
+
398
+
399
+
400
+	/**
401
+	 * returns alias for class name if one exists, otherwise returns the original classname
402
+	 * functions recursively, so that multiple aliases can be used to drill down to a classname
403
+	 *  for example:
404
+	 *      if the following two entries were added to the _aliases array:
405
+	 *          array(
406
+	 *              'interface_alias'           => 'some\namespace\interface'
407
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
408
+	 *          )
409
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
410
+	 *      to load an instance of 'some\namespace\classname'
411
+	 *
412
+	 * @param string $class_name
413
+	 * @param string $for_class
414
+	 * @return string
415
+	 */
416
+	public function get_alias($class_name = '', $for_class = '')
417
+	{
418
+		if (! $this->has_alias($class_name, $for_class)) {
419
+			return $class_name;
420
+		}
421
+		if ($for_class !== '' && isset($this->_aliases[ $for_class ][ $class_name ])) {
422
+			return $this->get_alias($this->_aliases[$for_class][$class_name], $for_class);
423
+		}
424
+		return $this->get_alias($this->_aliases[$class_name]);
425
+	}
426
+
427
+
428
+
429
+	/**
430
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
431
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
432
+	 * This is done by using the following class constants:
433
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
434
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
435
+	 */
436
+	protected function _register_core_dependencies()
437
+	{
438
+		$this->_dependency_map = array(
439
+			'EE_Request_Handler'                                                                                          => array(
440
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
441
+			),
442
+			'EE_System'                                                                                                   => array(
443
+				'EE_Registry'                                => EE_Dependency_Map::load_from_cache,
444
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
445
+				'EE_Capabilities'                            => EE_Dependency_Map::load_from_cache,
446
+				'EE_Request'                                 => EE_Dependency_Map::load_from_cache,
447
+				'EE_Maintenance_Mode'                        => EE_Dependency_Map::load_from_cache,
448
+			),
449
+			'EE_Session'                                                                                                  => array(
450
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
451
+				'EE_Encryption'                                           => EE_Dependency_Map::load_from_cache,
452
+			),
453
+			'EE_Cart'                                                                                                     => array(
454
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
455
+			),
456
+			'EE_Front_Controller'                                                                                         => array(
457
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
458
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
459
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
460
+			),
461
+			'EE_Messenger_Collection_Loader'                                                                              => array(
462
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
463
+			),
464
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
465
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
466
+			),
467
+			'EE_Message_Resource_Manager'                                                                                 => array(
468
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
469
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
470
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
471
+			),
472
+			'EE_Message_Factory'                                                                                          => array(
473
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
474
+			),
475
+			'EE_messages'                                                                                                 => array(
476
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
477
+			),
478
+			'EE_Messages_Generator'                                                                                       => array(
479
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
480
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
481
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
482
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
483
+			),
484
+			'EE_Messages_Processor'                                                                                       => array(
485
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
486
+			),
487
+			'EE_Messages_Queue'                                                                                           => array(
488
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
489
+			),
490
+			'EE_Messages_Template_Defaults'                                                                               => array(
491
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
492
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
493
+			),
494
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
495
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
496
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
497
+			),
498
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
499
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
500
+			),
501
+			'EventEspresso\services\commands\CommandHandler'                                                              => array(
502
+				'EE_Registry'         => EE_Dependency_Map::load_from_cache,
503
+				'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
504
+			),
505
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
506
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
507
+			),
508
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
509
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
510
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
511
+			),
512
+			'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
513
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
514
+			),
515
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
516
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
517
+			),
518
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
519
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
520
+			),
521
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
522
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
523
+			),
524
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
525
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
526
+			),
527
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
528
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
529
+			),
530
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
531
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
532
+			),
533
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
534
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
535
+			),
536
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
537
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
538
+			),
539
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
540
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
541
+			),
542
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
543
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
544
+			),
545
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
546
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
547
+			),
548
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
549
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
550
+			),
551
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
552
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
553
+			),
554
+			'EE_Data_Migration_Class_Base'                                                                                => array(
555
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
556
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
557
+			),
558
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
559
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
560
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
561
+			),
562
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
563
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
564
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
565
+			),
566
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
567
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
568
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
569
+			),
570
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
571
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
572
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
573
+			),
574
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
575
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
576
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
577
+			),
578
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
579
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
580
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
581
+			),
582
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
583
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
584
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
585
+			),
586
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
587
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
588
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
589
+			),
590
+			'EE_DMS_Core_4_9_0'                                                                                           => array(
591
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
592
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
593
+			),
594
+			'EventEspresso\core\services\assets\Registry'                                                                 => array(
595
+				'EE_Template_Config' => EE_Dependency_Map::load_from_cache,
596
+				'EE_Currency_Config' => EE_Dependency_Map::load_from_cache,
597
+			),
598
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
599
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
600
+			),
601
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
602
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
603
+			),
604
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
605
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
606
+			),
607
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
608
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
609
+			),
610
+			'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
611
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
612
+			),
613
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
614
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
615
+			),
616
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
617
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
618
+			),
619
+			'EventEspresso\core\services\cache\BasicCacheManager'                        => array(
620
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
621
+			),
622
+			'EventEspresso\core\services\cache\PostRelatedCacheManager'                  => array(
623
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
624
+			),
625
+			'EventEspresso\core\domain\services\validation\email\EmailValidationService' => array(
626
+				'EE_Registration_Config'                                  => EE_Dependency_Map::load_from_cache,
627
+				'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
628
+			),
629
+			'EventEspresso\core\domain\values\EmailAddress'                              => array(
630
+				null,
631
+				'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
632
+			),
633
+			'EventEspresso\core\services\orm\ModelFieldFactory' => array(
634
+				'EventEspresso\core\services\loaders\Loader'              => EE_Dependency_Map::load_from_cache,
635
+			),
636
+			'LEGACY_MODELS'                                                   => array(
637
+				null,
638
+				'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
639
+			),
640
+			'EE_Module_Request_Router' => array(
641
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
642
+			),
643
+			'EE_Registration_Processor' => array(
644
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
645
+			),
646
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager' => array(
647
+				null,
648
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
649
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
650
+			),
651
+		);
652
+	}
653
+
654
+
655
+
656
+	/**
657
+	 * Registers how core classes are loaded.
658
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
659
+	 *        'EE_Request_Handler' => 'load_core'
660
+	 *        'EE_Messages_Queue'  => 'load_lib'
661
+	 *        'EEH_Debug_Tools'    => 'load_helper'
662
+	 * or, if greater control is required, by providing a custom closure. For example:
663
+	 *        'Some_Class' => function () {
664
+	 *            return new Some_Class();
665
+	 *        },
666
+	 * This is required for instantiating dependencies
667
+	 * where an interface has been type hinted in a class constructor. For example:
668
+	 *        'Required_Interface' => function () {
669
+	 *            return new A_Class_That_Implements_Required_Interface();
670
+	 *        },
671
+	 *
672
+	 * @throws InvalidInterfaceException
673
+	 * @throws InvalidDataTypeException
674
+	 * @throws InvalidArgumentException
675
+	 */
676
+	protected function _register_core_class_loaders()
677
+	{
678
+		//for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
679
+		//be used in a closure.
680
+		$request = &$this->_request;
681
+		$response = &$this->_response;
682
+		// $loader = &$this->loader;
683
+		$this->_class_loaders = array(
684
+			//load_core
685
+			'EE_Capabilities'                      => 'load_core',
686
+			'EE_Encryption'                        => 'load_core',
687
+			'EE_Front_Controller'                  => 'load_core',
688
+			'EE_Module_Request_Router'             => 'load_core',
689
+			'EE_Registry'                          => 'load_core',
690
+			'EE_Request'                           => function () use (&$request) {
691
+				return $request;
692
+			},
693
+			'EE_Response'                          => function () use (&$response) {
694
+				return $response;
695
+			},
696
+			'EE_Request_Handler'                   => 'load_core',
697
+			'EE_Session'                           => 'load_core',
698
+			'EE_Cron_Tasks'                        => 'load_core',
699
+			'EE_System'                            => 'load_core',
700
+			'EE_Maintenance_Mode'                  => 'load_core',
701
+			'EE_Register_CPTs'                     => 'load_core',
702
+			'EE_Admin'                             => 'load_core',
703
+			//load_lib
704
+			'EE_Message_Resource_Manager'          => 'load_lib',
705
+			'EE_Message_Type_Collection'           => 'load_lib',
706
+			'EE_Message_Type_Collection_Loader'    => 'load_lib',
707
+			'EE_Messenger_Collection'              => 'load_lib',
708
+			'EE_Messenger_Collection_Loader'       => 'load_lib',
709
+			'EE_Messages_Processor'                => 'load_lib',
710
+			'EE_Message_Repository'                => 'load_lib',
711
+			'EE_Messages_Queue'                    => 'load_lib',
712
+			'EE_Messages_Data_Handler_Collection'  => 'load_lib',
713
+			'EE_Message_Template_Group_Collection' => 'load_lib',
714
+			'EE_Payment_Method_Manager'            => 'load_lib',
715
+			'EE_Messages_Generator'                => function () {
716
+				return EE_Registry::instance()->load_lib(
717
+					'Messages_Generator',
718
+					array(),
719
+					false,
720
+					false
721
+				);
722
+			},
723
+			'EE_Messages_Template_Defaults'        => function ($arguments = array()) {
724
+				return EE_Registry::instance()->load_lib(
725
+					'Messages_Template_Defaults',
726
+					$arguments,
727
+					false,
728
+					false
729
+				);
730
+			},
731
+			//load_model
732
+			// 'EEM_Attendee'                         => 'load_model',
733
+			// 'EEM_Message_Template_Group'           => 'load_model',
734
+			// 'EEM_Message_Template'                 => 'load_model',
735
+			//load_helper
736
+			'EEH_Parse_Shortcodes'                 => function () {
737
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
738
+					return new EEH_Parse_Shortcodes();
739
+				}
740
+				return null;
741
+			},
742
+			'EE_Template_Config'                   => function () {
743
+				return EE_Config::instance()->template_settings;
744
+			},
745
+			'EE_Currency_Config'                   => function () {
746
+				return EE_Config::instance()->currency;
747
+			},
748
+			'EE_Registration_Config'                   => function () {
749
+				return EE_Config::instance()->registration;
750
+			},
751
+			'EventEspresso\core\services\loaders\Loader' => function () {
752
+				return LoaderFactory::getLoader();
753
+			},
754
+		);
755
+	}
756
+
757
+
758
+
759
+	/**
760
+	 * can be used for supplying alternate names for classes,
761
+	 * or for connecting interface names to instantiable classes
762
+	 */
763
+	protected function _register_core_aliases()
764
+	{
765
+		$this->_aliases = array(
766
+			'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
767
+			'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
768
+			'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
769
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
770
+			'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
771
+			'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
772
+			'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
773
+			'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
774
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
775
+			'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
776
+			'CreateRegCodeCommandHandler'                                                  => 'EventEspresso\core\services\commands\registration\CreateRegCodeCommand',
777
+			'CreateRegUrlLinkCommandHandler'                                               => 'EventEspresso\core\services\commands\registration\CreateRegUrlLinkCommand',
778
+			'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
779
+			'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
780
+			'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
781
+			'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
782
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
783
+			'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
784
+			'CreateTransactionCommandHandler'                                     => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
785
+			'CreateAttendeeCommandHandler'                                        => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
786
+			'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
787
+			'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
788
+			'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
789
+			'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
790
+			'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
791
+			'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
792
+			'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
793
+			'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
794
+			'CommandFactoryInterface'                                                     => 'EventEspresso\core\services\commands\CommandFactoryInterface',
795
+			'EventEspresso\core\services\commands\CommandFactoryInterface'                => 'EventEspresso\core\services\commands\CommandFactory',
796
+			'EventEspresso\core\domain\services\session\SessionIdentifierInterface'       => 'EE_Session',
797
+			'EmailValidatorInterface'                                                     => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
798
+			'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface' => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
799
+			'NoticeConverterInterface'                                            => 'EventEspresso\core\services\notices\NoticeConverterInterface',
800
+			'EventEspresso\core\services\notices\NoticeConverterInterface'        => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
801
+			'NoticesContainerInterface'                                            => 'EventEspresso\core\services\notices\NoticesContainerInterface',
802
+			'EventEspresso\core\services\notices\NoticesContainerInterface'        => 'EventEspresso\core\services\notices\NoticesContainer',
803
+		);
804
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
805
+			$this->_aliases['EventEspresso\core\services\notices\NoticeConverterInterface'] = 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices';
806
+		}
807
+	}
808
+
809
+
810
+
811
+	/**
812
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
813
+	 * request Primarily used by unit tests.
814
+	 *
815
+	 * @throws InvalidDataTypeException
816
+	 * @throws InvalidInterfaceException
817
+	 * @throws InvalidArgumentException
818
+	 */
819
+	public function reset()
820
+	{
821
+		$this->_register_core_class_loaders();
822
+		$this->_register_core_dependencies();
823
+	}
824 824
 
825 825
 
826 826
 }
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/EE_PMT_Paypal_Express.pm.php 2 patches
Indentation   +140 added lines, -140 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('NO direct script access allowed');
2
+	exit('NO direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -17,153 +17,153 @@  discard block
 block discarded – undo
17 17
 class EE_PMT_Paypal_Express extends EE_PMT_Base
18 18
 {
19 19
 
20
-    /**
21
-     * EE_PMT_Paypal_Express constructor.
22
-     */
23
-    public function __construct($pm_instance = null)
24
-    {
25
-        require_once($this->file_folder() . 'EEG_Paypal_Express.gateway.php');
26
-        $this->_gateway = new EEG_Paypal_Express();
20
+	/**
21
+	 * EE_PMT_Paypal_Express constructor.
22
+	 */
23
+	public function __construct($pm_instance = null)
24
+	{
25
+		require_once($this->file_folder() . 'EEG_Paypal_Express.gateway.php');
26
+		$this->_gateway = new EEG_Paypal_Express();
27 27
 
28
-        $this->_pretty_name = esc_html__('PayPal Express', 'event_espresso');
29
-        $this->_template_path = $this->file_folder() . 'templates' . DS;
30
-        $this->_default_description = esc_html__(
31
-            // @codingStandardsIgnoreStart
32
-            'After clicking \'Finalize Registration\', you will be forwarded to PayPal website to Login and make your payment.',
33
-            // @codingStandardsIgnoreEnd
34
-            'event_espresso'
35
-        );
36
-        $this->_default_button_url = $this->file_url() . 'lib' . DS . 'paypal-express-checkout-logo.png';
28
+		$this->_pretty_name = esc_html__('PayPal Express', 'event_espresso');
29
+		$this->_template_path = $this->file_folder() . 'templates' . DS;
30
+		$this->_default_description = esc_html__(
31
+			// @codingStandardsIgnoreStart
32
+			'After clicking \'Finalize Registration\', you will be forwarded to PayPal website to Login and make your payment.',
33
+			// @codingStandardsIgnoreEnd
34
+			'event_espresso'
35
+		);
36
+		$this->_default_button_url = $this->file_url() . 'lib' . DS . 'paypal-express-checkout-logo.png';
37 37
 
38
-        parent::__construct($pm_instance);
39
-    }
38
+		parent::__construct($pm_instance);
39
+	}
40 40
 
41 41
 
42
-    /**
43
-     * Adds the help tab.
44
-     *
45
-     * @see EE_PMT_Base::help_tabs_config()
46
-     * @return array
47
-     */
48
-    public function help_tabs_config()
49
-    {
50
-        return array(
51
-            $this->get_help_tab_name() => array(
52
-                'title'    => esc_html__('PayPal Express Settings', 'event_espresso'),
53
-                'filename' => 'payment_methods_overview_paypal_express'
54
-            )
55
-        );
56
-    }
42
+	/**
43
+	 * Adds the help tab.
44
+	 *
45
+	 * @see EE_PMT_Base::help_tabs_config()
46
+	 * @return array
47
+	 */
48
+	public function help_tabs_config()
49
+	{
50
+		return array(
51
+			$this->get_help_tab_name() => array(
52
+				'title'    => esc_html__('PayPal Express Settings', 'event_espresso'),
53
+				'filename' => 'payment_methods_overview_paypal_express'
54
+			)
55
+		);
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     * Gets the form for all the settings related to this payment method type.
61
-     *
62
-     * @return EE_Payment_Method_Form
63
-     */
64
-    public function generate_new_settings_form()
65
-    {
66
-        EE_Registry::instance()->load_helper('Template');
67
-        $form = new EE_Payment_Method_Form(
68
-            array(
69
-                'extra_meta_inputs' => array(
70
-                    'api_username' => new EE_Text_Input(
71
-                        array(
72
-                            'html_label_text' => sprintf(
73
-                                esc_html__('API Username %s', 'event_espresso'),
74
-                                $this->get_help_tab_link()
75
-                            ),
76
-                            'required'        => true,
77
-                        )
78
-                    ),
79
-                    'api_password' => new EE_Text_Input(
80
-                        array(
81
-                            'html_label_text' => sprintf(
82
-                                esc_html__('API Password %s', 'event_espresso'),
83
-                                $this->get_help_tab_link()
84
-                            ),
85
-                            'required'        => true,
86
-                        )
87
-                    ),
88
-                    'api_signature' => new EE_Text_Input(
89
-                        array(
90
-                            'html_label_text' => sprintf(
91
-                                esc_html__('API Signature %s', 'event_espresso'),
92
-                                $this->get_help_tab_link()
93
-                            ),
94
-                            'required'        => true,
95
-                        )
96
-                    ),
97
-                    'request_shipping_addr' => new EE_Yes_No_Input(
98
-                        array(
99
-                            'html_label_text' => sprintf(
100
-                                esc_html__('Request Shipping Address %s', 'event_espresso'),
101
-                                $this->get_help_tab_link()
102
-                            ),
103
-                            'html_help_text'  => esc_html__(
104
-                                // @codingStandardsIgnoreStart
105
-                                'If set to "Yes", then a shipping address will be requested on the PayPal checkout page.',
106
-                                // @codingStandardsIgnoreEnd
107
-                                'event_espresso'
108
-                            ),
109
-                            'required'        => true,
110
-                            'default'         => false,
111
-                        )
112
-                    ),
113
-                    'image_url' => new EE_Admin_File_Uploader_Input(
114
-                        array(
115
-                            'html_label_text' => sprintf(
116
-                                esc_html__('Image URL %s', 'event_espresso'),
117
-                                $this->get_help_tab_link()
118
-                            ),
119
-                            'html_help_text'  => esc_html__(
120
-                                'Used for your business/personal logo on the PayPal page',
121
-                                'event_espresso'
122
-                            ),
123
-                            'required'        => false,
124
-                        )
125
-                    ),
126
-                )
127
-            )
128
-        );
129
-        return $form;
130
-    }
59
+	/**
60
+	 * Gets the form for all the settings related to this payment method type.
61
+	 *
62
+	 * @return EE_Payment_Method_Form
63
+	 */
64
+	public function generate_new_settings_form()
65
+	{
66
+		EE_Registry::instance()->load_helper('Template');
67
+		$form = new EE_Payment_Method_Form(
68
+			array(
69
+				'extra_meta_inputs' => array(
70
+					'api_username' => new EE_Text_Input(
71
+						array(
72
+							'html_label_text' => sprintf(
73
+								esc_html__('API Username %s', 'event_espresso'),
74
+								$this->get_help_tab_link()
75
+							),
76
+							'required'        => true,
77
+						)
78
+					),
79
+					'api_password' => new EE_Text_Input(
80
+						array(
81
+							'html_label_text' => sprintf(
82
+								esc_html__('API Password %s', 'event_espresso'),
83
+								$this->get_help_tab_link()
84
+							),
85
+							'required'        => true,
86
+						)
87
+					),
88
+					'api_signature' => new EE_Text_Input(
89
+						array(
90
+							'html_label_text' => sprintf(
91
+								esc_html__('API Signature %s', 'event_espresso'),
92
+								$this->get_help_tab_link()
93
+							),
94
+							'required'        => true,
95
+						)
96
+					),
97
+					'request_shipping_addr' => new EE_Yes_No_Input(
98
+						array(
99
+							'html_label_text' => sprintf(
100
+								esc_html__('Request Shipping Address %s', 'event_espresso'),
101
+								$this->get_help_tab_link()
102
+							),
103
+							'html_help_text'  => esc_html__(
104
+								// @codingStandardsIgnoreStart
105
+								'If set to "Yes", then a shipping address will be requested on the PayPal checkout page.',
106
+								// @codingStandardsIgnoreEnd
107
+								'event_espresso'
108
+							),
109
+							'required'        => true,
110
+							'default'         => false,
111
+						)
112
+					),
113
+					'image_url' => new EE_Admin_File_Uploader_Input(
114
+						array(
115
+							'html_label_text' => sprintf(
116
+								esc_html__('Image URL %s', 'event_espresso'),
117
+								$this->get_help_tab_link()
118
+							),
119
+							'html_help_text'  => esc_html__(
120
+								'Used for your business/personal logo on the PayPal page',
121
+								'event_espresso'
122
+							),
123
+							'required'        => false,
124
+						)
125
+					),
126
+				)
127
+			)
128
+		);
129
+		return $form;
130
+	}
131 131
 
132 132
 
133
-    /**
134
-     * Creates a billing form for this payment method type.
135
-     *
136
-     * @param \EE_Transaction $transaction
137
-     * @return \EE_Billing_Info_Form
138
-     */
139
-    public function generate_new_billing_form(EE_Transaction $transaction = null)
140
-    {
141
-        if ($this->_pm_instance->debug_mode()) {
142
-            $form = new EE_Billing_Info_Form(
143
-                $this->_pm_instance,
144
-                array(
145
-                    'name' => 'paypal_express_Info_Form',
146
-                    'subsections' => array(
147
-                        'paypal_express_debug_info' => new EE_Form_Section_Proper(
148
-                            array(
149
-                                'layout_strategy' => new EE_Template_Layout(
150
-                                    array(
151
-                                        'layout_template_file' => $this->_template_path
152
-                                                                    . 'paypal_express_debug_info.template.php',
153
-                                        'template_args'        => array(
154
-                                            'debug_mode' => $this->_pm_instance->debug_mode()
155
-                                        )
156
-                                    )
157
-                                )
158
-                            )
159
-                        )
160
-                    )
161
-                )
162
-            );
163
-            return $form;
164
-        }
133
+	/**
134
+	 * Creates a billing form for this payment method type.
135
+	 *
136
+	 * @param \EE_Transaction $transaction
137
+	 * @return \EE_Billing_Info_Form
138
+	 */
139
+	public function generate_new_billing_form(EE_Transaction $transaction = null)
140
+	{
141
+		if ($this->_pm_instance->debug_mode()) {
142
+			$form = new EE_Billing_Info_Form(
143
+				$this->_pm_instance,
144
+				array(
145
+					'name' => 'paypal_express_Info_Form',
146
+					'subsections' => array(
147
+						'paypal_express_debug_info' => new EE_Form_Section_Proper(
148
+							array(
149
+								'layout_strategy' => new EE_Template_Layout(
150
+									array(
151
+										'layout_template_file' => $this->_template_path
152
+																	. 'paypal_express_debug_info.template.php',
153
+										'template_args'        => array(
154
+											'debug_mode' => $this->_pm_instance->debug_mode()
155
+										)
156
+									)
157
+								)
158
+							)
159
+						)
160
+					)
161
+				)
162
+			);
163
+			return $form;
164
+		}
165 165
 
166
-        return false;
167
-    }
166
+		return false;
167
+	}
168 168
 }
169 169
 // End of file EE_PMT_Paypal_Express.pm.php
170 170
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +4 added lines, -4 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('NO direct script access allowed');
3 3
 }
4 4
 
@@ -22,18 +22,18 @@  discard block
 block discarded – undo
22 22
      */
23 23
     public function __construct($pm_instance = null)
24 24
     {
25
-        require_once($this->file_folder() . 'EEG_Paypal_Express.gateway.php');
25
+        require_once($this->file_folder().'EEG_Paypal_Express.gateway.php');
26 26
         $this->_gateway = new EEG_Paypal_Express();
27 27
 
28 28
         $this->_pretty_name = esc_html__('PayPal Express', 'event_espresso');
29
-        $this->_template_path = $this->file_folder() . 'templates' . DS;
29
+        $this->_template_path = $this->file_folder().'templates'.DS;
30 30
         $this->_default_description = esc_html__(
31 31
             // @codingStandardsIgnoreStart
32 32
             'After clicking \'Finalize Registration\', you will be forwarded to PayPal website to Login and make your payment.',
33 33
             // @codingStandardsIgnoreEnd
34 34
             'event_espresso'
35 35
         );
36
-        $this->_default_button_url = $this->file_url() . 'lib' . DS . 'paypal-express-checkout-logo.png';
36
+        $this->_default_button_url = $this->file_url().'lib'.DS.'paypal-express-checkout-logo.png';
37 37
 
38 38
         parent::__construct($pm_instance);
39 39
     }
Please login to merge, or discard this patch.
payment_methods/Paypal_Express/EEG_Paypal_Express.gateway.php 2 patches
Indentation   +669 added lines, -669 removed lines patch added patch discarded remove patch
@@ -1,5 +1,5 @@  discard block
 block discarded – undo
1 1
 <?php if (! defined('EVENT_ESPRESSO_VERSION')) {
2
-    exit('NO direct script access allowed');
2
+	exit('NO direct script access allowed');
3 3
 }
4 4
 
5 5
 
@@ -16,678 +16,678 @@  discard block
 block discarded – undo
16 16
  */
17 17
 //Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
18 18
 if (! function_exists('mb_strcut')) {
19
-    /**
20
-     * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
21
-     * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
22
-     * @param $string
23
-     * @param $start
24
-     * @param $length
25
-     * @return bool|string
26
-     */
27
-    function mb_strcut($string, $start, $length = null)
28
-    {
29
-        return mb_substr($string, $start, $length);
30
-    }
19
+	/**
20
+	 * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
21
+	 * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
22
+	 * @param $string
23
+	 * @param $start
24
+	 * @param $length
25
+	 * @return bool|string
26
+	 */
27
+	function mb_strcut($string, $start, $length = null)
28
+	{
29
+		return mb_substr($string, $start, $length);
30
+	}
31 31
 }
32 32
 class EEG_Paypal_Express extends EE_Offsite_Gateway
33 33
 {
34 34
 
35
-    /**
36
-     * Merchant API Username.
37
-     *
38
-     * @var string
39
-     */
40
-    protected $_api_username;
41
-
42
-    /**
43
-     * Merchant API Password.
44
-     *
45
-     * @var string
46
-     */
47
-    protected $_api_password;
48
-
49
-    /**
50
-     * API Signature.
51
-     *
52
-     * @var string
53
-     */
54
-    protected $_api_signature;
55
-
56
-    /**
57
-     * Request Shipping address on PP checkout page.
58
-     *
59
-     * @var string
60
-     */
61
-    protected $_request_shipping_addr;
62
-
63
-    /**
64
-     * Business/personal logo.
65
-     *
66
-     * @var string
67
-     */
68
-    protected $_image_url;
69
-
70
-    /**
71
-     * gateway URL variable
72
-     *
73
-     * @var string
74
-     */
75
-    protected $_base_gateway_url = '';
76
-
77
-
78
-
79
-    /**
80
-     * EEG_Paypal_Express constructor.
81
-     */
82
-    public function __construct()
83
-    {
84
-        $this->_currencies_supported = array(
85
-            'USD',
86
-            'AUD',
87
-            'BRL',
88
-            'CAD',
89
-            'CZK',
90
-            'DKK',
91
-            'EUR',
92
-            'HKD',
93
-            'HUF',
94
-            'ILS',
95
-            'JPY',
96
-            'MYR',
97
-            'MXN',
98
-            'NOK',
99
-            'NZD',
100
-            'PHP',
101
-            'PLN',
102
-            'GBP',
103
-            'RUB',
104
-            'SGD',
105
-            'SEK',
106
-            'CHF',
107
-            'TWD',
108
-            'THB',
109
-            'TRY',
110
-        );
111
-        parent::__construct();
112
-    }
113
-
114
-
115
-
116
-    /**
117
-     * Sets the gateway URL variable based on whether debug mode is enabled or not.
118
-     *
119
-     * @param array $settings_array
120
-     */
121
-    public function set_settings($settings_array)
122
-    {
123
-        parent::set_settings($settings_array);
124
-        // Redirect URL.
125
-        $this->_base_gateway_url = $this->_debug_mode
126
-            ? 'https://api-3t.sandbox.paypal.com/nvp'
127
-            : 'https://api-3t.paypal.com/nvp';
128
-    }
129
-
130
-
131
-
132
-    /**
133
-     * @param EEI_Payment $payment
134
-     * @param array       $billing_info
135
-     * @param string      $return_url
136
-     * @param string      $notify_url
137
-     * @param string      $cancel_url
138
-     * @return \EE_Payment|\EEI_Payment
139
-     * @throws \EE_Error
140
-     */
141
-    public function set_redirection_info(
142
-        $payment,
143
-        $billing_info = array(),
144
-        $return_url = null,
145
-        $notify_url = null,
146
-        $cancel_url = null
147
-    ) {
148
-        if (! $payment instanceof EEI_Payment) {
149
-            $payment->set_gateway_response(
150
-                esc_html__(
151
-                    'Error. No associated payment was found.',
152
-                    'event_espresso'
153
-                )
154
-            );
155
-            $payment->set_status($this->_pay_model->failed_status());
156
-            return $payment;
157
-        }
158
-        $transaction = $payment->transaction();
159
-        if (! $transaction instanceof EEI_Transaction) {
160
-            $payment->set_gateway_response(
161
-                esc_html__(
162
-                    'Could not process this payment because it has no associated transaction.',
163
-                    'event_espresso'
164
-                )
165
-            );
166
-            $payment->set_status($this->_pay_model->failed_status());
167
-            return $payment;
168
-        }
169
-        $order_description = mb_strcut($this->_format_order_description($payment), 0, 127);
170
-        $primary_registration = $transaction->primary_registration();
171
-        $primary_attendee = $primary_registration instanceof EE_Registration
172
-            ? $primary_registration->attendee()
173
-            : false;
174
-        $locale = explode('-', get_bloginfo('language'));
175
-        // Gather request parameters.
176
-        $token_request_dtls = array(
177
-            'METHOD'                         => 'SetExpressCheckout',
178
-            'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
179
-            'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
180
-            'PAYMENTREQUEST_0_DESC'          => $order_description,
181
-            'RETURNURL'                      => $return_url,
182
-            'CANCELURL'                      => $cancel_url,
183
-            'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
184
-            // Buyer does not need to create a PayPal account to check out.
185
-            // This is referred to as PayPal Account Optional.
186
-            'SOLUTIONTYPE'                   => 'Sole',
187
-            //EE will blow up if you change this
188
-            'BUTTONSOURCE'                   => 'EventEspresso_SP',
189
-            // Locale of the pages displayed by PayPal during Express Checkout.
190
-            'LOCALECODE'                     => $locale[1]
191
-        );
192
-        // Show itemized list.
193
-        $itemized_list = $this->itemize_list($payment, $transaction);
194
-        $token_request_dtls = array_merge($token_request_dtls, $itemized_list);
195
-        // Automatically filling out shipping and contact information.
196
-        if ($this->_request_shipping_addr && $primary_attendee instanceof EEI_Attendee) {
197
-            // If you do not pass the shipping address, PayPal obtains it from the buyer's account profile.
198
-            $token_request_dtls['NOSHIPPING'] = '2';
199
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET'] = $primary_attendee->address();
200
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $primary_attendee->address2();
201
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOCITY'] = $primary_attendee->city();
202
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTATE'] = $primary_attendee->state_abbrev();
203
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $primary_attendee->country_ID();
204
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip();
205
-            $token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email();
206
-            $token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone();
207
-        } elseif (! $this->_request_shipping_addr) {
208
-            // Do not request shipping details on the PP Checkout page.
209
-            $token_request_dtls['NOSHIPPING'] = '1';
210
-            $token_request_dtls['REQCONFIRMSHIPPING'] = '0';
211
-        }
212
-        // Used a business/personal logo on the PayPal page.
213
-        if (! empty($this->_image_url)) {
214
-            $token_request_dtls['LOGOIMG'] = $this->_image_url;
215
-        }
216
-        $token_request_dtls = apply_filters(
217
-            'FHEE__EEG_Paypal_Express__set_redirection_info__arguments',
218
-            $token_request_dtls,
219
-            $this
220
-        );
221
-        // Request PayPal token.
222
-        $token_request_response = $this->_ppExpress_request($token_request_dtls, 'Payment Token', $payment);
223
-        $token_rstatus = $this->_ppExpress_check_response($token_request_response);
224
-        $response_args = (isset($token_rstatus['args']) && is_array($token_rstatus['args']))
225
-            ? $token_rstatus['args']
226
-            : array();
227
-        if ($token_rstatus['status']) {
228
-            // We got the Token so we may continue with the payment and redirect the client.
229
-            $payment->set_details($response_args);
230
-            $gateway_url = $this->_debug_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
231
-            $payment->set_redirect_url(
232
-                $gateway_url
233
-                . '/checkoutnow?useraction=commit&cmd=_express-checkout&token='
234
-                . $response_args['TOKEN']
235
-            );
236
-        } else {
237
-            if (isset($response_args['L_ERRORCODE'])) {
238
-                $payment->set_gateway_response($response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']);
239
-            } else {
240
-                $payment->set_gateway_response(
241
-                    esc_html__(
242
-                        'Error occurred while trying to setup the Express Checkout.',
243
-                        'event_espresso'
244
-                    )
245
-                );
246
-            }
247
-            $payment->set_details($response_args);
248
-            $payment->set_status($this->_pay_model->failed_status());
249
-        }
250
-        return $payment;
251
-    }
252
-
253
-
254
-
255
-    /**
256
-     * @param array           $update_info {
257
-     * @type string           $gateway_txn_id
258
-     * @type string status an EEMI_Payment status
259
-     *                                     }
260
-     * @param EEI_Transaction $transaction
261
-     * @return EEI_Payment
262
-     */
263
-    public function handle_payment_update($update_info, $transaction)
264
-    {
265
-        $payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : null;
266
-        if ($payment instanceof EEI_Payment) {
267
-            $this->log(array('Return from Authorization' => $update_info), $payment);
268
-            $transaction = $payment->transaction();
269
-            if (! $transaction instanceof EEI_Transaction) {
270
-                $payment->set_gateway_response(
271
-                    esc_html__(
272
-                        'Could not process this payment because it has no associated transaction.',
273
-                        'event_espresso'
274
-                    )
275
-                );
276
-                $payment->set_status($this->_pay_model->failed_status());
277
-                return $payment;
278
-            }
279
-            $primary_registrant = $transaction->primary_registration();
280
-            $payment_details = $payment->details();
281
-            // Check if we still have the token.
282
-            if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
283
-                $payment->set_status($this->_pay_model->failed_status());
284
-                return $payment;
285
-            }
286
-            $cdetails_request_dtls = array(
287
-                'METHOD' => 'GetExpressCheckoutDetails',
288
-                'TOKEN'  => $payment_details['TOKEN'],
289
-            );
290
-            // Request Customer Details.
291
-            $cdetails_request_response = $this->_ppExpress_request(
292
-                $cdetails_request_dtls,
293
-                'Customer Details',
294
-                $payment
295
-            );
296
-            $cdetails_rstatus = $this->_ppExpress_check_response($cdetails_request_response);
297
-            $cdata_response_args = (isset($cdetails_rstatus['args']) && is_array($cdetails_rstatus['args']))
298
-                ? $cdetails_rstatus['args']
299
-                : array();
300
-            if ($cdetails_rstatus['status']) {
301
-                // We got the PayerID so now we can Complete the transaction.
302
-                $docheckout_request_dtls = array(
303
-                    'METHOD'                         => 'DoExpressCheckoutPayment',
304
-                    'PAYERID'                        => $cdata_response_args['PAYERID'],
305
-                    'TOKEN'                          => $payment_details['TOKEN'],
306
-                    'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
307
-                    'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
308
-                    'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
309
-                    //EE will blow up if you change this
310
-                    'BUTTONSOURCE'                   => 'EventEspresso_SP',
311
-                );
312
-                 // Include itemized list.
313
-                $itemized_list = $this->itemize_list(
314
-                    $payment,
315
-                    $transaction,
316
-                    $cdata_response_args
317
-                );
318
-                $docheckout_request_dtls = array_merge($docheckout_request_dtls, $itemized_list);
319
-                // Payment Checkout/Capture.
320
-                $docheckout_request_response = $this->_ppExpress_request(
321
-                    $docheckout_request_dtls,
322
-                    'Do Payment',
323
-                    $payment
324
-                );
325
-                $docheckout_rstatus = $this->_ppExpress_check_response($docheckout_request_response);
326
-                $docheckout_response_args = (isset($docheckout_rstatus['args']) && is_array($docheckout_rstatus['args']))
327
-                    ? $docheckout_rstatus['args']
328
-                    : array();
329
-                if ($docheckout_rstatus['status']) {
330
-                    // All is well, payment approved.
331
-                    $primary_registration_code = $primary_registrant instanceof EE_Registration ?
332
-                        $primary_registrant->reg_code()
333
-                        : '';
334
-                    $payment->set_extra_accntng($primary_registration_code);
335
-                    $payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT'])
336
-                        ? (float)$docheckout_response_args['PAYMENTINFO_0_AMT']
337
-                        : 0);
338
-                    $payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'])
339
-                        ? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']
340
-                        : null);
341
-                    $payment->set_details($cdata_response_args);
342
-                    $payment->set_gateway_response(isset($docheckout_response_args['PAYMENTINFO_0_ACK'])
343
-                        ? $docheckout_response_args['PAYMENTINFO_0_ACK']
344
-                        : '');
345
-                    $payment->set_status($this->_pay_model->approved_status());
346
-                } else {
347
-                    if (isset($docheckout_response_args['L_ERRORCODE'])) {
348
-                        $payment->set_gateway_response(
349
-                            $docheckout_response_args['L_ERRORCODE']
350
-                            . '; '
351
-                            . $docheckout_response_args['L_SHORTMESSAGE']
352
-                        );
353
-                    } else {
354
-                        $payment->set_gateway_response(
355
-                            esc_html__(
356
-                                'Error occurred while trying to Capture the funds.',
357
-                                'event_espresso'
358
-                            )
359
-                        );
360
-                    }
361
-                    $payment->set_details($docheckout_response_args);
362
-                    $payment->set_status($this->_pay_model->declined_status());
363
-                }
364
-            } else {
365
-                if (isset($cdata_response_args['L_ERRORCODE'])) {
366
-                    $payment->set_gateway_response(
367
-                        $cdata_response_args['L_ERRORCODE']
368
-                        . '; '
369
-                        . $cdata_response_args['L_SHORTMESSAGE']
370
-                    );
371
-                } else {
372
-                    $payment->set_gateway_response(
373
-                        esc_html__(
374
-                            'Error occurred while trying to get payment Details from PayPal.',
375
-                            'event_espresso'
376
-                        )
377
-                    );
378
-                }
379
-                $payment->set_details($cdata_response_args);
380
-                $payment->set_status($this->_pay_model->failed_status());
381
-            }
382
-        } else {
383
-            $payment->set_gateway_response(
384
-                esc_html__(
385
-                    'Error occurred while trying to process the payment.',
386
-                    'event_espresso'
387
-                )
388
-            );
389
-            $payment->set_status($this->_pay_model->failed_status());
390
-        }
391
-        return $payment;
392
-    }
393
-
394
-
395
-
396
-    /**
397
-     *  Make a list of items that are in the giver transaction.
398
-     *
399
-     * @param EEI_Payment     $payment
400
-     * @param EEI_Transaction $transaction
401
-     * @param array           $request_response_args Data from a previous communication with PP.
402
-     * @return array
403
-     */
404
-    public function itemize_list(EEI_Payment $payment, EEI_Transaction $transaction, $request_response_args = array())
405
-    {
406
-        $itemized_list = array();
407
-        // If we have data from a previous communication with PP (on this transaction) we may use that for our list...
408
-        if (
409
-            ! empty($request_response_args)
410
-            && array_key_exists('L_PAYMENTREQUEST_0_AMT0', $request_response_args)
411
-            && array_key_exists('PAYMENTREQUEST_0_ITEMAMT', $request_response_args)
412
-        ) {
413
-            foreach ($request_response_args as $arg_key => $arg_val) {
414
-                if (
415
-                    strpos($arg_key, 'PAYMENTREQUEST_') !== false
416
-                    && strpos($arg_key, 'NOTIFYURL') === false
417
-                ) {
418
-                    $itemized_list[$arg_key] = $arg_val;
419
-                }
420
-            }
421
-            // If we got only a few Items then something is not right.
422
-            if (count($itemized_list) > 2) {
423
-                return $itemized_list;
424
-            } else {
425
-                if (WP_DEBUG) {
426
-                    throw new EE_Error(
427
-                        sprintf(
428
-                            esc_html__(
429
-                                // @codingStandardsIgnoreStart
430
-                                'Unable to continue with the checkout because a proper purchase list could not be generated. The purchased list we could have sent was %1$s',
431
-                                // @codingStandardsIgnoreEnd
432
-                                'event_espresso'
433
-                            ),
434
-                            wp_json_encode($itemized_list)
435
-                        )
436
-                    );
437
-                }
438
-                // Reset the list and log an error, maybe allow to try and generate a new list (below).
439
-                $itemized_list = array();
440
-                $this->log(
441
-                    array(
442
-                        esc_html__(
443
-                            'Could not generate a proper item list with:',
444
-                            'event_espresso'
445
-                        ) => $request_response_args
446
-                    ),
447
-                    $payment
448
-                );
449
-            }
450
-        }
451
-        // ...otherwise we generate a new list for this transaction.
452
-        if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) {
453
-            $item_num = 0;
454
-            $itemized_sum = 0;
455
-            $total_line_items = $transaction->total_line_item();
456
-            // Go through each item in the list.
457
-            foreach ($total_line_items->get_items() as $line_item) {
458
-                if ($line_item instanceof EE_Line_Item) {
459
-                    // PayPal doesn't like line items with 0.00 amount, so we may skip those.
460
-                    if (EEH_Money::compare_floats($line_item->total(), '0.00', '==')) {
461
-                        continue;
462
-                    }
463
-                    $unit_price = $line_item->unit_price();
464
-                    $line_item_quantity = $line_item->quantity();
465
-                    // This is a discount.
466
-                    if ($line_item->is_percent()) {
467
-                        $unit_price = $line_item->total();
468
-                        $line_item_quantity = 1;
469
-                    }
470
-                    // Item Name.
471
-                    $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
472
-                        $this->_format_line_item_name($line_item, $payment),
473
-                        0,
474
-                        127
475
-                    );
476
-                    // Item description.
477
-                    $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = mb_strcut(
478
-                        $this->_format_line_item_desc($line_item, $payment),
479
-                        0,
480
-                        127
481
-                    );
482
-                    // Cost of individual item.
483
-                    $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $this->format_currency($unit_price);
484
-                    // Item Number.
485
-                    $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
486
-                    // Item quantity.
487
-                    $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = $line_item_quantity;
488
-                    // Digital item is sold.
489
-                    $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
490
-                    $itemized_sum += $line_item->total();
491
-                    ++$item_num;
492
-                }
493
-            }
494
-            // Item's sales S/H and tax amount.
495
-            $itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $total_line_items->get_items_total();
496
-            $itemized_list['PAYMENTREQUEST_0_TAXAMT'] = $total_line_items->get_total_tax();
497
-            $itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
498
-            $itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
499
-            $itemized_sum_diff_from_txn_total = round(
500
-                $transaction->total() - $itemized_sum - $total_line_items->get_total_tax(),
501
-                2
502
-            );
503
-            // If we were not able to recognize some item like promotion, surcharge or cancellation,
504
-            // add the difference as an extra line item.
505
-            if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) {
506
-                // Item Name.
507
-                $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
508
-                    esc_html__(
509
-                        'Other (promotion/surcharge/cancellation)',
510
-                        'event_espresso'
511
-                    ),
512
-                    0,
513
-                    127
514
-                );
515
-                // Item description.
516
-                $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = '';
517
-                // Cost of individual item.
518
-                $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $this->format_currency(
519
-                    $itemized_sum_diff_from_txn_total
520
-                );
521
-                // Item Number.
522
-                $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
523
-                // Item quantity.
524
-                $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = 1;
525
-                // Digital item is sold.
526
-                $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
527
-                $item_num++;
528
-            }
529
-        } else {
530
-            // Just one Item.
531
-            // Item Name.
532
-            $itemized_list['L_PAYMENTREQUEST_0_NAME0'] = mb_strcut(
533
-                $this->_format_partial_payment_line_item_name($payment),
534
-                0,
535
-                127
536
-            );
537
-            // Item description.
538
-            $itemized_list['L_PAYMENTREQUEST_0_DESC0'] = mb_strcut(
539
-                $this->_format_partial_payment_line_item_desc($payment),
540
-                0,
541
-                127
542
-            );
543
-            // Cost of individual item.
544
-            $itemized_list['L_PAYMENTREQUEST_0_AMT0'] = $this->format_currency($payment->amount());
545
-            // Item Number.
546
-            $itemized_list['L_PAYMENTREQUEST_0_NUMBER0'] = 1;
547
-            // Item quantity.
548
-            $itemized_list['L_PAYMENTREQUEST_0_QTY0'] = 1;
549
-            // Digital item is sold.
550
-            $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
551
-            // Item's sales S/H and tax amount.
552
-            $itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $this->format_currency($payment->amount());
553
-            $itemized_list['PAYMENTREQUEST_0_TAXAMT'] = '0';
554
-            $itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
555
-            $itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
556
-        }
557
-        return $itemized_list;
558
-    }
559
-
560
-
561
-
562
-    /**
563
-     *  Make the Express checkout request.
564
-     *
565
-     * @param array       $request_params
566
-     * @param string      $request_text
567
-     * @param EEI_Payment $payment
568
-     * @return mixed
569
-     */
570
-    public function _ppExpress_request($request_params, $request_text, $payment)
571
-    {
572
-        $request_dtls = array(
573
-            'VERSION'   => '204.0',
574
-            'USER'      => urlencode($this->_api_username),
575
-            'PWD'       => urlencode($this->_api_password),
576
-            'SIGNATURE' => urlencode($this->_api_signature),
577
-        );
578
-        $dtls = array_merge($request_dtls, $request_params);
579
-        $this->_log_clean_request($dtls, $payment, $request_text . ' Request');
580
-        // Request Customer Details.
581
-        $request_response = wp_remote_post(
582
-            $this->_base_gateway_url,
583
-            array(
584
-                'method'      => 'POST',
585
-                'timeout'     => 45,
586
-                'httpversion' => '1.1',
587
-                'cookies'     => array(),
588
-                'headers'     => array(),
589
-                'body'        => http_build_query($dtls),
590
-            )
591
-        );
592
-        // Log the response.
593
-        $this->log(array($request_text . ' Response' => $request_response), $payment);
594
-        return $request_response;
595
-    }
596
-
597
-
598
-
599
-    /**
600
-     *  Check the response status.
601
-     *
602
-     * @param mixed $request_response
603
-     * @return array
604
-     */
605
-    public function _ppExpress_check_response($request_response)
606
-    {
607
-        if (is_wp_error($request_response) || empty($request_response['body'])) {
608
-            // If we got here then there was an error in this request.
609
-            return array('status' => false, 'args' => $request_response);
610
-        }
611
-        $response_args = array();
612
-        parse_str(urldecode($request_response['body']), $response_args);
613
-        if (! isset($response_args['ACK'])) {
614
-            return array('status' => false, 'args' => $request_response);
615
-        }
616
-        if (
617
-            (
618
-                isset($response_args['PAYERID'])
619
-                || isset($response_args['TOKEN'])
620
-                || isset($response_args['PAYMENTINFO_0_TRANSACTIONID'])
621
-                || (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed')
622
-            )
623
-            && in_array($response_args['ACK'], array('Success', 'SuccessWithWarning'), true)
624
-        ) {
625
-            // Response status OK, return response parameters for further processing.
626
-            return array('status' => true, 'args' => $response_args);
627
-        }
628
-        $errors = $this->_get_errors($response_args);
629
-        return array('status' => false, 'args' => $errors);
630
-    }
631
-
632
-
633
-
634
-    /**
635
-     *  Log a "Cleared" request.
636
-     *
637
-     * @param array       $request
638
-     * @param EEI_Payment $payment
639
-     * @param string      $info
640
-     * @return void
641
-     */
642
-    private function _log_clean_request($request, $payment, $info)
643
-    {
644
-        $cleaned_request_data = $request;
645
-        unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']);
646
-        $this->log(array($info => $cleaned_request_data), $payment);
647
-    }
648
-
649
-
650
-
651
-    /**
652
-     *  Get error from the response data.
653
-     *
654
-     * @param array $data_array
655
-     * @return array
656
-     */
657
-    private function _get_errors($data_array)
658
-    {
659
-        $errors = array();
660
-        $n = 0;
661
-        while (isset($data_array["L_ERRORCODE{$n}"])) {
662
-            $l_error_code = isset($data_array["L_ERRORCODE{$n}"])
663
-                ? $data_array["L_ERRORCODE{$n}"]
664
-                : '';
665
-            $l_severity_code = isset($data_array["L_SEVERITYCODE{$n}"])
666
-                ? $data_array["L_SEVERITYCODE{$n}"]
667
-                : '';
668
-            $l_short_message = isset($data_array["L_SHORTMESSAGE{$n}"])
669
-                ? $data_array["L_SHORTMESSAGE{$n}"]
670
-                : '';
671
-            $l_long_message = isset($data_array["L_LONGMESSAGE{$n}"])
672
-                ? $data_array["L_LONGMESSAGE{$n}"]
673
-                : '';
674
-            if ($n === 0) {
675
-                $errors = array(
676
-                    'L_ERRORCODE'    => $l_error_code,
677
-                    'L_SHORTMESSAGE' => $l_short_message,
678
-                    'L_LONGMESSAGE'  => $l_long_message,
679
-                    'L_SEVERITYCODE' => $l_severity_code,
680
-                );
681
-            } else {
682
-                $errors['L_ERRORCODE'] .= ', ' . $l_error_code;
683
-                $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
684
-                $errors['L_LONGMESSAGE'] .= ', ' . $l_long_message;
685
-                $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
686
-            }
687
-            $n++;
688
-        }
689
-        return $errors;
690
-    }
35
+	/**
36
+	 * Merchant API Username.
37
+	 *
38
+	 * @var string
39
+	 */
40
+	protected $_api_username;
41
+
42
+	/**
43
+	 * Merchant API Password.
44
+	 *
45
+	 * @var string
46
+	 */
47
+	protected $_api_password;
48
+
49
+	/**
50
+	 * API Signature.
51
+	 *
52
+	 * @var string
53
+	 */
54
+	protected $_api_signature;
55
+
56
+	/**
57
+	 * Request Shipping address on PP checkout page.
58
+	 *
59
+	 * @var string
60
+	 */
61
+	protected $_request_shipping_addr;
62
+
63
+	/**
64
+	 * Business/personal logo.
65
+	 *
66
+	 * @var string
67
+	 */
68
+	protected $_image_url;
69
+
70
+	/**
71
+	 * gateway URL variable
72
+	 *
73
+	 * @var string
74
+	 */
75
+	protected $_base_gateway_url = '';
76
+
77
+
78
+
79
+	/**
80
+	 * EEG_Paypal_Express constructor.
81
+	 */
82
+	public function __construct()
83
+	{
84
+		$this->_currencies_supported = array(
85
+			'USD',
86
+			'AUD',
87
+			'BRL',
88
+			'CAD',
89
+			'CZK',
90
+			'DKK',
91
+			'EUR',
92
+			'HKD',
93
+			'HUF',
94
+			'ILS',
95
+			'JPY',
96
+			'MYR',
97
+			'MXN',
98
+			'NOK',
99
+			'NZD',
100
+			'PHP',
101
+			'PLN',
102
+			'GBP',
103
+			'RUB',
104
+			'SGD',
105
+			'SEK',
106
+			'CHF',
107
+			'TWD',
108
+			'THB',
109
+			'TRY',
110
+		);
111
+		parent::__construct();
112
+	}
113
+
114
+
115
+
116
+	/**
117
+	 * Sets the gateway URL variable based on whether debug mode is enabled or not.
118
+	 *
119
+	 * @param array $settings_array
120
+	 */
121
+	public function set_settings($settings_array)
122
+	{
123
+		parent::set_settings($settings_array);
124
+		// Redirect URL.
125
+		$this->_base_gateway_url = $this->_debug_mode
126
+			? 'https://api-3t.sandbox.paypal.com/nvp'
127
+			: 'https://api-3t.paypal.com/nvp';
128
+	}
129
+
130
+
131
+
132
+	/**
133
+	 * @param EEI_Payment $payment
134
+	 * @param array       $billing_info
135
+	 * @param string      $return_url
136
+	 * @param string      $notify_url
137
+	 * @param string      $cancel_url
138
+	 * @return \EE_Payment|\EEI_Payment
139
+	 * @throws \EE_Error
140
+	 */
141
+	public function set_redirection_info(
142
+		$payment,
143
+		$billing_info = array(),
144
+		$return_url = null,
145
+		$notify_url = null,
146
+		$cancel_url = null
147
+	) {
148
+		if (! $payment instanceof EEI_Payment) {
149
+			$payment->set_gateway_response(
150
+				esc_html__(
151
+					'Error. No associated payment was found.',
152
+					'event_espresso'
153
+				)
154
+			);
155
+			$payment->set_status($this->_pay_model->failed_status());
156
+			return $payment;
157
+		}
158
+		$transaction = $payment->transaction();
159
+		if (! $transaction instanceof EEI_Transaction) {
160
+			$payment->set_gateway_response(
161
+				esc_html__(
162
+					'Could not process this payment because it has no associated transaction.',
163
+					'event_espresso'
164
+				)
165
+			);
166
+			$payment->set_status($this->_pay_model->failed_status());
167
+			return $payment;
168
+		}
169
+		$order_description = mb_strcut($this->_format_order_description($payment), 0, 127);
170
+		$primary_registration = $transaction->primary_registration();
171
+		$primary_attendee = $primary_registration instanceof EE_Registration
172
+			? $primary_registration->attendee()
173
+			: false;
174
+		$locale = explode('-', get_bloginfo('language'));
175
+		// Gather request parameters.
176
+		$token_request_dtls = array(
177
+			'METHOD'                         => 'SetExpressCheckout',
178
+			'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
179
+			'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
180
+			'PAYMENTREQUEST_0_DESC'          => $order_description,
181
+			'RETURNURL'                      => $return_url,
182
+			'CANCELURL'                      => $cancel_url,
183
+			'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
184
+			// Buyer does not need to create a PayPal account to check out.
185
+			// This is referred to as PayPal Account Optional.
186
+			'SOLUTIONTYPE'                   => 'Sole',
187
+			//EE will blow up if you change this
188
+			'BUTTONSOURCE'                   => 'EventEspresso_SP',
189
+			// Locale of the pages displayed by PayPal during Express Checkout.
190
+			'LOCALECODE'                     => $locale[1]
191
+		);
192
+		// Show itemized list.
193
+		$itemized_list = $this->itemize_list($payment, $transaction);
194
+		$token_request_dtls = array_merge($token_request_dtls, $itemized_list);
195
+		// Automatically filling out shipping and contact information.
196
+		if ($this->_request_shipping_addr && $primary_attendee instanceof EEI_Attendee) {
197
+			// If you do not pass the shipping address, PayPal obtains it from the buyer's account profile.
198
+			$token_request_dtls['NOSHIPPING'] = '2';
199
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET'] = $primary_attendee->address();
200
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTREET2'] = $primary_attendee->address2();
201
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOCITY'] = $primary_attendee->city();
202
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOSTATE'] = $primary_attendee->state_abbrev();
203
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOCOUNTRYCODE'] = $primary_attendee->country_ID();
204
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip();
205
+			$token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email();
206
+			$token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone();
207
+		} elseif (! $this->_request_shipping_addr) {
208
+			// Do not request shipping details on the PP Checkout page.
209
+			$token_request_dtls['NOSHIPPING'] = '1';
210
+			$token_request_dtls['REQCONFIRMSHIPPING'] = '0';
211
+		}
212
+		// Used a business/personal logo on the PayPal page.
213
+		if (! empty($this->_image_url)) {
214
+			$token_request_dtls['LOGOIMG'] = $this->_image_url;
215
+		}
216
+		$token_request_dtls = apply_filters(
217
+			'FHEE__EEG_Paypal_Express__set_redirection_info__arguments',
218
+			$token_request_dtls,
219
+			$this
220
+		);
221
+		// Request PayPal token.
222
+		$token_request_response = $this->_ppExpress_request($token_request_dtls, 'Payment Token', $payment);
223
+		$token_rstatus = $this->_ppExpress_check_response($token_request_response);
224
+		$response_args = (isset($token_rstatus['args']) && is_array($token_rstatus['args']))
225
+			? $token_rstatus['args']
226
+			: array();
227
+		if ($token_rstatus['status']) {
228
+			// We got the Token so we may continue with the payment and redirect the client.
229
+			$payment->set_details($response_args);
230
+			$gateway_url = $this->_debug_mode ? 'https://www.sandbox.paypal.com' : 'https://www.paypal.com';
231
+			$payment->set_redirect_url(
232
+				$gateway_url
233
+				. '/checkoutnow?useraction=commit&cmd=_express-checkout&token='
234
+				. $response_args['TOKEN']
235
+			);
236
+		} else {
237
+			if (isset($response_args['L_ERRORCODE'])) {
238
+				$payment->set_gateway_response($response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']);
239
+			} else {
240
+				$payment->set_gateway_response(
241
+					esc_html__(
242
+						'Error occurred while trying to setup the Express Checkout.',
243
+						'event_espresso'
244
+					)
245
+				);
246
+			}
247
+			$payment->set_details($response_args);
248
+			$payment->set_status($this->_pay_model->failed_status());
249
+		}
250
+		return $payment;
251
+	}
252
+
253
+
254
+
255
+	/**
256
+	 * @param array           $update_info {
257
+	 * @type string           $gateway_txn_id
258
+	 * @type string status an EEMI_Payment status
259
+	 *                                     }
260
+	 * @param EEI_Transaction $transaction
261
+	 * @return EEI_Payment
262
+	 */
263
+	public function handle_payment_update($update_info, $transaction)
264
+	{
265
+		$payment = $transaction instanceof EEI_Transaction ? $transaction->last_payment() : null;
266
+		if ($payment instanceof EEI_Payment) {
267
+			$this->log(array('Return from Authorization' => $update_info), $payment);
268
+			$transaction = $payment->transaction();
269
+			if (! $transaction instanceof EEI_Transaction) {
270
+				$payment->set_gateway_response(
271
+					esc_html__(
272
+						'Could not process this payment because it has no associated transaction.',
273
+						'event_espresso'
274
+					)
275
+				);
276
+				$payment->set_status($this->_pay_model->failed_status());
277
+				return $payment;
278
+			}
279
+			$primary_registrant = $transaction->primary_registration();
280
+			$payment_details = $payment->details();
281
+			// Check if we still have the token.
282
+			if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
283
+				$payment->set_status($this->_pay_model->failed_status());
284
+				return $payment;
285
+			}
286
+			$cdetails_request_dtls = array(
287
+				'METHOD' => 'GetExpressCheckoutDetails',
288
+				'TOKEN'  => $payment_details['TOKEN'],
289
+			);
290
+			// Request Customer Details.
291
+			$cdetails_request_response = $this->_ppExpress_request(
292
+				$cdetails_request_dtls,
293
+				'Customer Details',
294
+				$payment
295
+			);
296
+			$cdetails_rstatus = $this->_ppExpress_check_response($cdetails_request_response);
297
+			$cdata_response_args = (isset($cdetails_rstatus['args']) && is_array($cdetails_rstatus['args']))
298
+				? $cdetails_rstatus['args']
299
+				: array();
300
+			if ($cdetails_rstatus['status']) {
301
+				// We got the PayerID so now we can Complete the transaction.
302
+				$docheckout_request_dtls = array(
303
+					'METHOD'                         => 'DoExpressCheckoutPayment',
304
+					'PAYERID'                        => $cdata_response_args['PAYERID'],
305
+					'TOKEN'                          => $payment_details['TOKEN'],
306
+					'PAYMENTREQUEST_0_PAYMENTACTION' => 'Sale',
307
+					'PAYMENTREQUEST_0_AMT'           => $payment->amount(),
308
+					'PAYMENTREQUEST_0_CURRENCYCODE'  => $payment->currency_code(),
309
+					//EE will blow up if you change this
310
+					'BUTTONSOURCE'                   => 'EventEspresso_SP',
311
+				);
312
+				 // Include itemized list.
313
+				$itemized_list = $this->itemize_list(
314
+					$payment,
315
+					$transaction,
316
+					$cdata_response_args
317
+				);
318
+				$docheckout_request_dtls = array_merge($docheckout_request_dtls, $itemized_list);
319
+				// Payment Checkout/Capture.
320
+				$docheckout_request_response = $this->_ppExpress_request(
321
+					$docheckout_request_dtls,
322
+					'Do Payment',
323
+					$payment
324
+				);
325
+				$docheckout_rstatus = $this->_ppExpress_check_response($docheckout_request_response);
326
+				$docheckout_response_args = (isset($docheckout_rstatus['args']) && is_array($docheckout_rstatus['args']))
327
+					? $docheckout_rstatus['args']
328
+					: array();
329
+				if ($docheckout_rstatus['status']) {
330
+					// All is well, payment approved.
331
+					$primary_registration_code = $primary_registrant instanceof EE_Registration ?
332
+						$primary_registrant->reg_code()
333
+						: '';
334
+					$payment->set_extra_accntng($primary_registration_code);
335
+					$payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT'])
336
+						? (float)$docheckout_response_args['PAYMENTINFO_0_AMT']
337
+						: 0);
338
+					$payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'])
339
+						? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']
340
+						: null);
341
+					$payment->set_details($cdata_response_args);
342
+					$payment->set_gateway_response(isset($docheckout_response_args['PAYMENTINFO_0_ACK'])
343
+						? $docheckout_response_args['PAYMENTINFO_0_ACK']
344
+						: '');
345
+					$payment->set_status($this->_pay_model->approved_status());
346
+				} else {
347
+					if (isset($docheckout_response_args['L_ERRORCODE'])) {
348
+						$payment->set_gateway_response(
349
+							$docheckout_response_args['L_ERRORCODE']
350
+							. '; '
351
+							. $docheckout_response_args['L_SHORTMESSAGE']
352
+						);
353
+					} else {
354
+						$payment->set_gateway_response(
355
+							esc_html__(
356
+								'Error occurred while trying to Capture the funds.',
357
+								'event_espresso'
358
+							)
359
+						);
360
+					}
361
+					$payment->set_details($docheckout_response_args);
362
+					$payment->set_status($this->_pay_model->declined_status());
363
+				}
364
+			} else {
365
+				if (isset($cdata_response_args['L_ERRORCODE'])) {
366
+					$payment->set_gateway_response(
367
+						$cdata_response_args['L_ERRORCODE']
368
+						. '; '
369
+						. $cdata_response_args['L_SHORTMESSAGE']
370
+					);
371
+				} else {
372
+					$payment->set_gateway_response(
373
+						esc_html__(
374
+							'Error occurred while trying to get payment Details from PayPal.',
375
+							'event_espresso'
376
+						)
377
+					);
378
+				}
379
+				$payment->set_details($cdata_response_args);
380
+				$payment->set_status($this->_pay_model->failed_status());
381
+			}
382
+		} else {
383
+			$payment->set_gateway_response(
384
+				esc_html__(
385
+					'Error occurred while trying to process the payment.',
386
+					'event_espresso'
387
+				)
388
+			);
389
+			$payment->set_status($this->_pay_model->failed_status());
390
+		}
391
+		return $payment;
392
+	}
393
+
394
+
395
+
396
+	/**
397
+	 *  Make a list of items that are in the giver transaction.
398
+	 *
399
+	 * @param EEI_Payment     $payment
400
+	 * @param EEI_Transaction $transaction
401
+	 * @param array           $request_response_args Data from a previous communication with PP.
402
+	 * @return array
403
+	 */
404
+	public function itemize_list(EEI_Payment $payment, EEI_Transaction $transaction, $request_response_args = array())
405
+	{
406
+		$itemized_list = array();
407
+		// If we have data from a previous communication with PP (on this transaction) we may use that for our list...
408
+		if (
409
+			! empty($request_response_args)
410
+			&& array_key_exists('L_PAYMENTREQUEST_0_AMT0', $request_response_args)
411
+			&& array_key_exists('PAYMENTREQUEST_0_ITEMAMT', $request_response_args)
412
+		) {
413
+			foreach ($request_response_args as $arg_key => $arg_val) {
414
+				if (
415
+					strpos($arg_key, 'PAYMENTREQUEST_') !== false
416
+					&& strpos($arg_key, 'NOTIFYURL') === false
417
+				) {
418
+					$itemized_list[$arg_key] = $arg_val;
419
+				}
420
+			}
421
+			// If we got only a few Items then something is not right.
422
+			if (count($itemized_list) > 2) {
423
+				return $itemized_list;
424
+			} else {
425
+				if (WP_DEBUG) {
426
+					throw new EE_Error(
427
+						sprintf(
428
+							esc_html__(
429
+								// @codingStandardsIgnoreStart
430
+								'Unable to continue with the checkout because a proper purchase list could not be generated. The purchased list we could have sent was %1$s',
431
+								// @codingStandardsIgnoreEnd
432
+								'event_espresso'
433
+							),
434
+							wp_json_encode($itemized_list)
435
+						)
436
+					);
437
+				}
438
+				// Reset the list and log an error, maybe allow to try and generate a new list (below).
439
+				$itemized_list = array();
440
+				$this->log(
441
+					array(
442
+						esc_html__(
443
+							'Could not generate a proper item list with:',
444
+							'event_espresso'
445
+						) => $request_response_args
446
+					),
447
+					$payment
448
+				);
449
+			}
450
+		}
451
+		// ...otherwise we generate a new list for this transaction.
452
+		if ($this->_money->compare_floats($payment->amount(), $transaction->total(), '==')) {
453
+			$item_num = 0;
454
+			$itemized_sum = 0;
455
+			$total_line_items = $transaction->total_line_item();
456
+			// Go through each item in the list.
457
+			foreach ($total_line_items->get_items() as $line_item) {
458
+				if ($line_item instanceof EE_Line_Item) {
459
+					// PayPal doesn't like line items with 0.00 amount, so we may skip those.
460
+					if (EEH_Money::compare_floats($line_item->total(), '0.00', '==')) {
461
+						continue;
462
+					}
463
+					$unit_price = $line_item->unit_price();
464
+					$line_item_quantity = $line_item->quantity();
465
+					// This is a discount.
466
+					if ($line_item->is_percent()) {
467
+						$unit_price = $line_item->total();
468
+						$line_item_quantity = 1;
469
+					}
470
+					// Item Name.
471
+					$itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
472
+						$this->_format_line_item_name($line_item, $payment),
473
+						0,
474
+						127
475
+					);
476
+					// Item description.
477
+					$itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = mb_strcut(
478
+						$this->_format_line_item_desc($line_item, $payment),
479
+						0,
480
+						127
481
+					);
482
+					// Cost of individual item.
483
+					$itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $this->format_currency($unit_price);
484
+					// Item Number.
485
+					$itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
486
+					// Item quantity.
487
+					$itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = $line_item_quantity;
488
+					// Digital item is sold.
489
+					$itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
490
+					$itemized_sum += $line_item->total();
491
+					++$item_num;
492
+				}
493
+			}
494
+			// Item's sales S/H and tax amount.
495
+			$itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $total_line_items->get_items_total();
496
+			$itemized_list['PAYMENTREQUEST_0_TAXAMT'] = $total_line_items->get_total_tax();
497
+			$itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
498
+			$itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
499
+			$itemized_sum_diff_from_txn_total = round(
500
+				$transaction->total() - $itemized_sum - $total_line_items->get_total_tax(),
501
+				2
502
+			);
503
+			// If we were not able to recognize some item like promotion, surcharge or cancellation,
504
+			// add the difference as an extra line item.
505
+			if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) {
506
+				// Item Name.
507
+				$itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
508
+					esc_html__(
509
+						'Other (promotion/surcharge/cancellation)',
510
+						'event_espresso'
511
+					),
512
+					0,
513
+					127
514
+				);
515
+				// Item description.
516
+				$itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = '';
517
+				// Cost of individual item.
518
+				$itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $this->format_currency(
519
+					$itemized_sum_diff_from_txn_total
520
+				);
521
+				// Item Number.
522
+				$itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
523
+				// Item quantity.
524
+				$itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = 1;
525
+				// Digital item is sold.
526
+				$itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
527
+				$item_num++;
528
+			}
529
+		} else {
530
+			// Just one Item.
531
+			// Item Name.
532
+			$itemized_list['L_PAYMENTREQUEST_0_NAME0'] = mb_strcut(
533
+				$this->_format_partial_payment_line_item_name($payment),
534
+				0,
535
+				127
536
+			);
537
+			// Item description.
538
+			$itemized_list['L_PAYMENTREQUEST_0_DESC0'] = mb_strcut(
539
+				$this->_format_partial_payment_line_item_desc($payment),
540
+				0,
541
+				127
542
+			);
543
+			// Cost of individual item.
544
+			$itemized_list['L_PAYMENTREQUEST_0_AMT0'] = $this->format_currency($payment->amount());
545
+			// Item Number.
546
+			$itemized_list['L_PAYMENTREQUEST_0_NUMBER0'] = 1;
547
+			// Item quantity.
548
+			$itemized_list['L_PAYMENTREQUEST_0_QTY0'] = 1;
549
+			// Digital item is sold.
550
+			$itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY0'] = 'Physical';
551
+			// Item's sales S/H and tax amount.
552
+			$itemized_list['PAYMENTREQUEST_0_ITEMAMT'] = $this->format_currency($payment->amount());
553
+			$itemized_list['PAYMENTREQUEST_0_TAXAMT'] = '0';
554
+			$itemized_list['PAYMENTREQUEST_0_SHIPPINGAMT'] = '0';
555
+			$itemized_list['PAYMENTREQUEST_0_HANDLINGAMT'] = '0';
556
+		}
557
+		return $itemized_list;
558
+	}
559
+
560
+
561
+
562
+	/**
563
+	 *  Make the Express checkout request.
564
+	 *
565
+	 * @param array       $request_params
566
+	 * @param string      $request_text
567
+	 * @param EEI_Payment $payment
568
+	 * @return mixed
569
+	 */
570
+	public function _ppExpress_request($request_params, $request_text, $payment)
571
+	{
572
+		$request_dtls = array(
573
+			'VERSION'   => '204.0',
574
+			'USER'      => urlencode($this->_api_username),
575
+			'PWD'       => urlencode($this->_api_password),
576
+			'SIGNATURE' => urlencode($this->_api_signature),
577
+		);
578
+		$dtls = array_merge($request_dtls, $request_params);
579
+		$this->_log_clean_request($dtls, $payment, $request_text . ' Request');
580
+		// Request Customer Details.
581
+		$request_response = wp_remote_post(
582
+			$this->_base_gateway_url,
583
+			array(
584
+				'method'      => 'POST',
585
+				'timeout'     => 45,
586
+				'httpversion' => '1.1',
587
+				'cookies'     => array(),
588
+				'headers'     => array(),
589
+				'body'        => http_build_query($dtls),
590
+			)
591
+		);
592
+		// Log the response.
593
+		$this->log(array($request_text . ' Response' => $request_response), $payment);
594
+		return $request_response;
595
+	}
596
+
597
+
598
+
599
+	/**
600
+	 *  Check the response status.
601
+	 *
602
+	 * @param mixed $request_response
603
+	 * @return array
604
+	 */
605
+	public function _ppExpress_check_response($request_response)
606
+	{
607
+		if (is_wp_error($request_response) || empty($request_response['body'])) {
608
+			// If we got here then there was an error in this request.
609
+			return array('status' => false, 'args' => $request_response);
610
+		}
611
+		$response_args = array();
612
+		parse_str(urldecode($request_response['body']), $response_args);
613
+		if (! isset($response_args['ACK'])) {
614
+			return array('status' => false, 'args' => $request_response);
615
+		}
616
+		if (
617
+			(
618
+				isset($response_args['PAYERID'])
619
+				|| isset($response_args['TOKEN'])
620
+				|| isset($response_args['PAYMENTINFO_0_TRANSACTIONID'])
621
+				|| (isset($response_args['PAYMENTSTATUS']) && $response_args['PAYMENTSTATUS'] === 'Completed')
622
+			)
623
+			&& in_array($response_args['ACK'], array('Success', 'SuccessWithWarning'), true)
624
+		) {
625
+			// Response status OK, return response parameters for further processing.
626
+			return array('status' => true, 'args' => $response_args);
627
+		}
628
+		$errors = $this->_get_errors($response_args);
629
+		return array('status' => false, 'args' => $errors);
630
+	}
631
+
632
+
633
+
634
+	/**
635
+	 *  Log a "Cleared" request.
636
+	 *
637
+	 * @param array       $request
638
+	 * @param EEI_Payment $payment
639
+	 * @param string      $info
640
+	 * @return void
641
+	 */
642
+	private function _log_clean_request($request, $payment, $info)
643
+	{
644
+		$cleaned_request_data = $request;
645
+		unset($cleaned_request_data['PWD'], $cleaned_request_data['USER'], $cleaned_request_data['SIGNATURE']);
646
+		$this->log(array($info => $cleaned_request_data), $payment);
647
+	}
648
+
649
+
650
+
651
+	/**
652
+	 *  Get error from the response data.
653
+	 *
654
+	 * @param array $data_array
655
+	 * @return array
656
+	 */
657
+	private function _get_errors($data_array)
658
+	{
659
+		$errors = array();
660
+		$n = 0;
661
+		while (isset($data_array["L_ERRORCODE{$n}"])) {
662
+			$l_error_code = isset($data_array["L_ERRORCODE{$n}"])
663
+				? $data_array["L_ERRORCODE{$n}"]
664
+				: '';
665
+			$l_severity_code = isset($data_array["L_SEVERITYCODE{$n}"])
666
+				? $data_array["L_SEVERITYCODE{$n}"]
667
+				: '';
668
+			$l_short_message = isset($data_array["L_SHORTMESSAGE{$n}"])
669
+				? $data_array["L_SHORTMESSAGE{$n}"]
670
+				: '';
671
+			$l_long_message = isset($data_array["L_LONGMESSAGE{$n}"])
672
+				? $data_array["L_LONGMESSAGE{$n}"]
673
+				: '';
674
+			if ($n === 0) {
675
+				$errors = array(
676
+					'L_ERRORCODE'    => $l_error_code,
677
+					'L_SHORTMESSAGE' => $l_short_message,
678
+					'L_LONGMESSAGE'  => $l_long_message,
679
+					'L_SEVERITYCODE' => $l_severity_code,
680
+				);
681
+			} else {
682
+				$errors['L_ERRORCODE'] .= ', ' . $l_error_code;
683
+				$errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
684
+				$errors['L_LONGMESSAGE'] .= ', ' . $l_long_message;
685
+				$errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
686
+			}
687
+			$n++;
688
+		}
689
+		return $errors;
690
+	}
691 691
 
692 692
 }
693 693
 // End of file EEG_Paypal_Express.gateway.php
Please login to merge, or discard this patch.
Spacing   +29 added lines, -29 removed lines patch added patch discarded remove patch
@@ -1,4 +1,4 @@  discard block
 block discarded – undo
1
-<?php if (! defined('EVENT_ESPRESSO_VERSION')) {
1
+<?php if ( ! defined('EVENT_ESPRESSO_VERSION')) {
2 2
     exit('NO direct script access allowed');
3 3
 }
4 4
 
@@ -15,7 +15,7 @@  discard block
 block discarded – undo
15 15
  * ----------------------------------------------
16 16
  */
17 17
 //Quickfix to address https://events.codebasehq.com/projects/event-espresso/tickets/11089 ASAP
18
-if (! function_exists('mb_strcut')) {
18
+if ( ! function_exists('mb_strcut')) {
19 19
     /**
20 20
      * Very simple mimic of mb_substr (which WP ensures exists in wp-includes/compat.php). Still has all the problems of mb_substr
21 21
      * (namely, that we might send too many characters to PayPal; however in this case they just issue a warning but nothing breaks)
@@ -145,7 +145,7 @@  discard block
 block discarded – undo
145 145
         $notify_url = null,
146 146
         $cancel_url = null
147 147
     ) {
148
-        if (! $payment instanceof EEI_Payment) {
148
+        if ( ! $payment instanceof EEI_Payment) {
149 149
             $payment->set_gateway_response(
150 150
                 esc_html__(
151 151
                     'Error. No associated payment was found.',
@@ -156,7 +156,7 @@  discard block
 block discarded – undo
156 156
             return $payment;
157 157
         }
158 158
         $transaction = $payment->transaction();
159
-        if (! $transaction instanceof EEI_Transaction) {
159
+        if ( ! $transaction instanceof EEI_Transaction) {
160 160
             $payment->set_gateway_response(
161 161
                 esc_html__(
162 162
                     'Could not process this payment because it has no associated transaction.',
@@ -204,13 +204,13 @@  discard block
 block discarded – undo
204 204
             $token_request_dtls['PAYMENTREQUEST_0_SHIPTOZIP'] = $primary_attendee->zip();
205 205
             $token_request_dtls['PAYMENTREQUEST_0_EMAIL'] = $primary_attendee->email();
206 206
             $token_request_dtls['PAYMENTREQUEST_0_SHIPTOPHONENUM'] = $primary_attendee->phone();
207
-        } elseif (! $this->_request_shipping_addr) {
207
+        } elseif ( ! $this->_request_shipping_addr) {
208 208
             // Do not request shipping details on the PP Checkout page.
209 209
             $token_request_dtls['NOSHIPPING'] = '1';
210 210
             $token_request_dtls['REQCONFIRMSHIPPING'] = '0';
211 211
         }
212 212
         // Used a business/personal logo on the PayPal page.
213
-        if (! empty($this->_image_url)) {
213
+        if ( ! empty($this->_image_url)) {
214 214
             $token_request_dtls['LOGOIMG'] = $this->_image_url;
215 215
         }
216 216
         $token_request_dtls = apply_filters(
@@ -235,7 +235,7 @@  discard block
 block discarded – undo
235 235
             );
236 236
         } else {
237 237
             if (isset($response_args['L_ERRORCODE'])) {
238
-                $payment->set_gateway_response($response_args['L_ERRORCODE'] . '; ' . $response_args['L_SHORTMESSAGE']);
238
+                $payment->set_gateway_response($response_args['L_ERRORCODE'].'; '.$response_args['L_SHORTMESSAGE']);
239 239
             } else {
240 240
                 $payment->set_gateway_response(
241 241
                     esc_html__(
@@ -266,7 +266,7 @@  discard block
 block discarded – undo
266 266
         if ($payment instanceof EEI_Payment) {
267 267
             $this->log(array('Return from Authorization' => $update_info), $payment);
268 268
             $transaction = $payment->transaction();
269
-            if (! $transaction instanceof EEI_Transaction) {
269
+            if ( ! $transaction instanceof EEI_Transaction) {
270 270
                 $payment->set_gateway_response(
271 271
                     esc_html__(
272 272
                         'Could not process this payment because it has no associated transaction.',
@@ -279,7 +279,7 @@  discard block
 block discarded – undo
279 279
             $primary_registrant = $transaction->primary_registration();
280 280
             $payment_details = $payment->details();
281 281
             // Check if we still have the token.
282
-            if (! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
282
+            if ( ! isset($payment_details['TOKEN']) || empty($payment_details['TOKEN'])) {
283 283
                 $payment->set_status($this->_pay_model->failed_status());
284 284
                 return $payment;
285 285
             }
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
                         : '';
334 334
                     $payment->set_extra_accntng($primary_registration_code);
335 335
                     $payment->set_amount(isset($docheckout_response_args['PAYMENTINFO_0_AMT'])
336
-                        ? (float)$docheckout_response_args['PAYMENTINFO_0_AMT']
336
+                        ? (float) $docheckout_response_args['PAYMENTINFO_0_AMT']
337 337
                         : 0);
338 338
                     $payment->set_txn_id_chq_nmbr(isset($docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID'])
339 339
                         ? $docheckout_response_args['PAYMENTINFO_0_TRANSACTIONID']
@@ -468,25 +468,25 @@  discard block
 block discarded – undo
468 468
                         $line_item_quantity = 1;
469 469
                     }
470 470
                     // Item Name.
471
-                    $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
471
+                    $itemized_list['L_PAYMENTREQUEST_0_NAME'.$item_num] = mb_strcut(
472 472
                         $this->_format_line_item_name($line_item, $payment),
473 473
                         0,
474 474
                         127
475 475
                     );
476 476
                     // Item description.
477
-                    $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = mb_strcut(
477
+                    $itemized_list['L_PAYMENTREQUEST_0_DESC'.$item_num] = mb_strcut(
478 478
                         $this->_format_line_item_desc($line_item, $payment),
479 479
                         0,
480 480
                         127
481 481
                     );
482 482
                     // Cost of individual item.
483
-                    $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $this->format_currency($unit_price);
483
+                    $itemized_list['L_PAYMENTREQUEST_0_AMT'.$item_num] = $this->format_currency($unit_price);
484 484
                     // Item Number.
485
-                    $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
485
+                    $itemized_list['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1;
486 486
                     // Item quantity.
487
-                    $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = $line_item_quantity;
487
+                    $itemized_list['L_PAYMENTREQUEST_0_QTY'.$item_num] = $line_item_quantity;
488 488
                     // Digital item is sold.
489
-                    $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
489
+                    $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY'.$item_num] = 'Physical';
490 490
                     $itemized_sum += $line_item->total();
491 491
                     ++$item_num;
492 492
                 }
@@ -504,7 +504,7 @@  discard block
 block discarded – undo
504 504
             // add the difference as an extra line item.
505 505
             if ($this->_money->compare_floats($itemized_sum_diff_from_txn_total, 0, '!=')) {
506 506
                 // Item Name.
507
-                $itemized_list['L_PAYMENTREQUEST_0_NAME' . $item_num] = mb_strcut(
507
+                $itemized_list['L_PAYMENTREQUEST_0_NAME'.$item_num] = mb_strcut(
508 508
                     esc_html__(
509 509
                         'Other (promotion/surcharge/cancellation)',
510 510
                         'event_espresso'
@@ -513,17 +513,17 @@  discard block
 block discarded – undo
513 513
                     127
514 514
                 );
515 515
                 // Item description.
516
-                $itemized_list['L_PAYMENTREQUEST_0_DESC' . $item_num] = '';
516
+                $itemized_list['L_PAYMENTREQUEST_0_DESC'.$item_num] = '';
517 517
                 // Cost of individual item.
518
-                $itemized_list['L_PAYMENTREQUEST_0_AMT' . $item_num] = $this->format_currency(
518
+                $itemized_list['L_PAYMENTREQUEST_0_AMT'.$item_num] = $this->format_currency(
519 519
                     $itemized_sum_diff_from_txn_total
520 520
                 );
521 521
                 // Item Number.
522
-                $itemized_list['L_PAYMENTREQUEST_0_NUMBER' . $item_num] = $item_num + 1;
522
+                $itemized_list['L_PAYMENTREQUEST_0_NUMBER'.$item_num] = $item_num + 1;
523 523
                 // Item quantity.
524
-                $itemized_list['L_PAYMENTREQUEST_0_QTY' . $item_num] = 1;
524
+                $itemized_list['L_PAYMENTREQUEST_0_QTY'.$item_num] = 1;
525 525
                 // Digital item is sold.
526
-                $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY' . $item_num] = 'Physical';
526
+                $itemized_list['L_PAYMENTREQUEST_0_ITEMCATEGORY'.$item_num] = 'Physical';
527 527
                 $item_num++;
528 528
             }
529 529
         } else {
@@ -576,7 +576,7 @@  discard block
 block discarded – undo
576 576
             'SIGNATURE' => urlencode($this->_api_signature),
577 577
         );
578 578
         $dtls = array_merge($request_dtls, $request_params);
579
-        $this->_log_clean_request($dtls, $payment, $request_text . ' Request');
579
+        $this->_log_clean_request($dtls, $payment, $request_text.' Request');
580 580
         // Request Customer Details.
581 581
         $request_response = wp_remote_post(
582 582
             $this->_base_gateway_url,
@@ -590,7 +590,7 @@  discard block
 block discarded – undo
590 590
             )
591 591
         );
592 592
         // Log the response.
593
-        $this->log(array($request_text . ' Response' => $request_response), $payment);
593
+        $this->log(array($request_text.' Response' => $request_response), $payment);
594 594
         return $request_response;
595 595
     }
596 596
 
@@ -610,7 +610,7 @@  discard block
 block discarded – undo
610 610
         }
611 611
         $response_args = array();
612 612
         parse_str(urldecode($request_response['body']), $response_args);
613
-        if (! isset($response_args['ACK'])) {
613
+        if ( ! isset($response_args['ACK'])) {
614 614
             return array('status' => false, 'args' => $request_response);
615 615
         }
616 616
         if (
@@ -679,10 +679,10 @@  discard block
 block discarded – undo
679 679
                     'L_SEVERITYCODE' => $l_severity_code,
680 680
                 );
681 681
             } else {
682
-                $errors['L_ERRORCODE'] .= ', ' . $l_error_code;
683
-                $errors['L_SHORTMESSAGE'] .= ', ' . $l_short_message;
684
-                $errors['L_LONGMESSAGE'] .= ', ' . $l_long_message;
685
-                $errors['L_SEVERITYCODE'] .= ', ' . $l_severity_code;
682
+                $errors['L_ERRORCODE'] .= ', '.$l_error_code;
683
+                $errors['L_SHORTMESSAGE'] .= ', '.$l_short_message;
684
+                $errors['L_LONGMESSAGE'] .= ', '.$l_long_message;
685
+                $errors['L_SEVERITYCODE'] .= ', '.$l_severity_code;
686 686
             }
687 687
             $n++;
688 688
         }
Please login to merge, or discard this patch.
core/domain/services/event/EventSpacesCalculator.php 2 patches
Indentation   +660 added lines, -660 removed lines patch added patch discarded remove patch
@@ -31,666 +31,666 @@
 block discarded – undo
31 31
 class EventSpacesCalculator
32 32
 {
33 33
 
34
-    /**
35
-     * @var EE_Event $event
36
-     */
37
-    private $event;
38
-
39
-    /**
40
-     * @var array $datetime_query_params
41
-     */
42
-    private $datetime_query_params;
43
-
44
-    /**
45
-     * @var EE_Ticket[] $active_tickets
46
-     */
47
-    private $active_tickets = array();
48
-
49
-    /**
50
-     * @var EE_Datetime[] $datetimes
51
-     */
52
-    private $datetimes = array();
53
-
54
-    /**
55
-     * Array of Ticket IDs grouped by Datetime
56
-     *
57
-     * @var array $datetimes
58
-     */
59
-    private $datetime_tickets = array();
60
-
61
-    /**
62
-     * Max spaces for each Datetime (reg limit - previous sold)
63
-     *
64
-     * @var array $datetime_spaces
65
-     */
66
-    private $datetime_spaces = array();
67
-
68
-    /**
69
-     * Array of Datetime IDs grouped by Ticket
70
-     *
71
-     * @var array[] $ticket_datetimes
72
-     */
73
-    private $ticket_datetimes = array();
74
-
75
-    /**
76
-     * maximum ticket quantities for each ticket (adjusted for reg limit)
77
-     *
78
-     * @var array $ticket_quantities
79
-     */
80
-    private $ticket_quantities = array();
81
-
82
-    /**
83
-     * total quantity of sold and reserved for each ticket
84
-     *
85
-     * @var array $tickets_sold
86
-     */
87
-    private $tickets_sold = array();
88
-
89
-    /**
90
-     * total spaces available across all datetimes
91
-     *
92
-     * @var array $total_spaces
93
-     */
94
-    private $total_spaces = array();
95
-
96
-    /**
97
-     * @var boolean $debug
98
-     */
99
-    private $debug = false;
100
-
101
-    /**
102
-     * @var null|int $spaces_remaining
103
-     */
104
-    private $spaces_remaining;
105
-
106
-    /**
107
-     * @var null|int $total_spaces_available
108
-     */
109
-    private $total_spaces_available;
110
-
111
-
112
-
113
-    /**
114
-     * EventSpacesCalculator constructor.
115
-     *
116
-     * @param EE_Event $event
117
-     * @param array    $datetime_query_params
118
-     * @throws EE_Error
119
-     */
120
-    public function __construct(EE_Event $event, array $datetime_query_params = array())
121
-    {
122
-        $this->event                 = $event;
123
-        $this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
124
-        $this->setHooks();
125
-    }
126
-
127
-
128
-
129
-    /**
130
-     * @return void
131
-     */
132
-    private function setHooks()
133
-    {
134
-        add_action( 'AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
-        add_action( 'AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
-        add_action( 'AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
-        add_action( 'AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
-        add_action( 'AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
-        add_action( 'AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
-        add_action( 'AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
-        add_action( 'AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     * @return void
148
-     */
149
-    public function clearResults()
150
-    {
151
-        $this->spaces_remaining = null;
152
-        $this->total_spaces_available = null;
153
-    }
154
-
155
-
156
-
157
-    /**
158
-     * @return EE_Ticket[]
159
-     * @throws EE_Error
160
-     * @throws InvalidDataTypeException
161
-     * @throws InvalidInterfaceException
162
-     * @throws InvalidArgumentException
163
-     */
164
-    public function getActiveTickets()
165
-    {
166
-        if (empty($this->active_tickets)) {
167
-            $this->active_tickets = $this->event->tickets(
168
-                array(
169
-                    array(
170
-                        'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
171
-                        'TKT_deleted'  => false,
172
-                    ),
173
-                    'order_by' => array('TKT_qty' => 'ASC'),
174
-                )
175
-            );
176
-        }
177
-        return $this->active_tickets;
178
-    }
179
-
180
-
181
-
182
-    /**
183
-     * @param EE_Ticket[] $active_tickets
184
-     * @throws EE_Error
185
-     * @throws DomainException
186
-     * @throws UnexpectedEntityException
187
-     */
188
-    public function setActiveTickets(array $active_tickets = array())
189
-    {
190
-        if ( ! empty($active_tickets)) {
191
-            foreach ($active_tickets as $active_ticket) {
192
-                $this->validateTicket($active_ticket);
193
-            }
194
-            // sort incoming array by ticket quantity (asc)
195
-            usort(
196
-                $active_tickets,
197
-                function (EE_Ticket $a, EE_Ticket $b) {
198
-                    if ($a->qty() === $b->qty()) {
199
-                        return 0;
200
-                    }
201
-                    return ($a->qty() < $b->qty())
202
-                        ? -1
203
-                        : 1;
204
-                }
205
-            );
206
-        }
207
-        $this->active_tickets = $active_tickets;
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     * @param $ticket
214
-     * @throws DomainException
215
-     * @throws EE_Error
216
-     * @throws UnexpectedEntityException
217
-     */
218
-    private function validateTicket($ticket)
219
-    {
220
-        if ( ! $ticket instanceof EE_Ticket) {
221
-            throw new DomainException(
222
-                esc_html__(
223
-                    'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
224
-                    'event_espresso'
225
-                )
226
-            );
227
-        }
228
-        if ($ticket->get_event_ID() !== $this->event->ID()) {
229
-            throw new DomainException(
230
-                sprintf(
231
-                    esc_html__(
232
-                        'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
233
-                        'event_espresso'
234
-                    ),
235
-                    $ticket->get_event_ID(),
236
-                    $this->event->ID()
237
-                )
238
-            );
239
-        }
240
-    }
241
-
242
-
243
-
244
-    /**
245
-     * @return EE_Datetime[]
246
-     */
247
-    public function getDatetimes()
248
-    {
249
-        return $this->datetimes;
250
-    }
251
-
252
-
253
-
254
-    /**
255
-     * @param EE_Datetime $datetime
256
-     * @throws EE_Error
257
-     * @throws DomainException
258
-     */
259
-    public function setDatetime(EE_Datetime $datetime)
260
-    {
261
-        if ($datetime->event()->ID() !== $this->event->ID()) {
262
-            throw new DomainException(
263
-                sprintf(
264
-                    esc_html__(
265
-                        'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
266
-                        'event_espresso'
267
-                    ),
268
-                    $datetime->event()->ID(),
269
-                    $this->event->ID()
270
-                )
271
-            );
272
-        }
273
-        $this->datetimes[ $datetime->ID() ] = $datetime;
274
-    }
275
-
276
-
277
-
278
-    /**
279
-     * calculate spaces remaining based on "saleable" tickets
280
-     *
281
-     * @return float|int
282
-     * @throws EE_Error
283
-     * @throws DomainException
284
-     * @throws UnexpectedEntityException
285
-     * @throws InvalidDataTypeException
286
-     * @throws InvalidInterfaceException
287
-     * @throws InvalidArgumentException
288
-     */
289
-    public function spacesRemaining()
290
-    {
291
-        if ($this->spaces_remaining === null) {
292
-            $this->initialize();
293
-            $this->spaces_remaining = $this->calculate();
294
-        }
295
-        return $this->spaces_remaining;
296
-    }
297
-
298
-
299
-
300
-    /**
301
-     * calculates total available spaces for an event with no regard for sold tickets
302
-     *
303
-     * @return int|float
304
-     * @throws EE_Error
305
-     * @throws DomainException
306
-     * @throws UnexpectedEntityException
307
-     * @throws InvalidDataTypeException
308
-     * @throws InvalidInterfaceException
309
-     * @throws InvalidArgumentException
310
-     */
311
-    public function totalSpacesAvailable()
312
-    {
313
-        if($this->total_spaces_available === null) {
314
-            $this->initialize();
315
-            $this->total_spaces_available = $this->calculate(false);
316
-        }
317
-        return $this->total_spaces_available;
318
-    }
319
-
320
-
321
-
322
-    /**
323
-     * Loops through the active tickets for the event
324
-     * and builds a series of data arrays that will be used for calculating
325
-     * the total maximum available spaces, as well as the spaces remaining.
326
-     * Because ticket quantities affect datetime spaces and vice versa,
327
-     * we need to be constantly updating these data arrays as things change,
328
-     * which is the entire reason for their existence.
329
-     *
330
-     * @throws EE_Error
331
-     * @throws DomainException
332
-     * @throws UnexpectedEntityException
333
-     * @throws InvalidDataTypeException
334
-     * @throws InvalidInterfaceException
335
-     * @throws InvalidArgumentException
336
-     */
337
-    private function initialize()
338
-    {
339
-        if ($this->debug) {
340
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
341
-        }
342
-        $this->datetime_tickets  = array();
343
-        $this->datetime_spaces   = array();
344
-        $this->ticket_datetimes  = array();
345
-        $this->ticket_quantities = array();
346
-        $this->tickets_sold      = array();
347
-        $this->total_spaces      = array();
348
-        $active_tickets          = $this->getActiveTickets();
349
-        if ( ! empty($active_tickets)) {
350
-            foreach ($active_tickets as $ticket) {
351
-                $this->validateTicket($ticket);
352
-                // we need to index our data arrays using strings for the purpose of sorting,
353
-                // but we also need them to be unique, so  we'll just prepend a letter T to the ID
354
-                $ticket_identifier = "T{$ticket->ID()}";
355
-                // to start, we'll just consider the raw qty to be the maximum availability for this ticket
356
-                $max_tickets = $ticket->qty();
357
-                // but we'll adjust that after looping over each datetime for the ticket and checking reg limits
358
-                $ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
359
-                foreach ($ticket_datetimes as $datetime) {
360
-                    // save all datetimes
361
-                    $this->setDatetime($datetime);
362
-                    $datetime_identifier = "D{$datetime->ID()}";
363
-                    $reg_limit           = $datetime->reg_limit();
364
-                    // ticket quantity can not exceed datetime reg limit
365
-                    $max_tickets = min($max_tickets, $reg_limit);
366
-                    // as described earlier, because we need to be able to constantly adjust numbers for things,
367
-                    // we are going to move all of our data into the following arrays:
368
-                    // datetime spaces initially represents the reg limit for each datetime,
369
-                    // but this will get adjusted as tickets are accounted for
370
-                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
371
-                    // just an array of ticket IDs grouped by datetime
372
-                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
373
-                    // and an array of datetime IDs grouped by ticket
374
-                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
375
-                }
376
-                // total quantity of sold and reserved for each ticket
377
-                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
378
-                // and the maximum ticket quantities for each ticket (adjusted for reg limit)
379
-                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
380
-            }
381
-        }
382
-        // sort datetime spaces by reg limit, but maintain our string indexes
383
-        asort($this->datetime_spaces, SORT_NUMERIC);
384
-        // datetime tickets need to be sorted in the SAME order as the above array...
385
-        // so we'll just use array_merge() to take the structure of datetime_spaces
386
-        // but overwrite all of the data with that from datetime_tickets
387
-        $this->datetime_tickets = array_merge(
388
-            $this->datetime_spaces,
389
-            $this->datetime_tickets
390
-        );
391
-        if ($this->debug) {
392
-            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
393
-            \EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
394
-            \EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
395
-        }
396
-    }
397
-
398
-
399
-
400
-    /**
401
-     * performs calculations on initialized data
402
-     *
403
-     * @param bool $consider_sold
404
-     * @return int|float
405
-     */
406
-    private function calculate($consider_sold = true)
407
-    {
408
-        if ($this->debug) {
409
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
410
-        }
411
-        if ($consider_sold) {
412
-            // subtract amounts sold from all ticket quantities and datetime spaces
413
-            $this->adjustTicketQuantitiesDueToSales();
414
-        }
415
-        foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
416
-            $this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
417
-        }
418
-        // total spaces available is just the sum of the spaces available for each datetime
419
-        $spaces_remaining = array_sum($this->total_spaces);
420
-        if ($this->debug) {
421
-            \EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
422
-            \EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
423
-            \EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
424
-        }
425
-        return $spaces_remaining;
426
-    }
427
-
428
-
429
-    /**
430
-     * subtracts amount of  tickets sold from ticket quantities and datetime spaces
431
-     */
432
-    private function adjustTicketQuantitiesDueToSales()
433
-    {
434
-        if ($this->debug) {
435
-            \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
436
-        }
437
-        foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
438
-            if (isset($this->ticket_quantities[ $ticket_identifier ])){
439
-                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
440
-                if ($this->debug) {
441
-                    \EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
442
-                }
443
-            }
444
-            if (
445
-                isset($this->ticket_datetimes[ $ticket_identifier ])
446
-                && is_array($this->ticket_datetimes[ $ticket_identifier ])
447
-            ){
448
-                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
449
-                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
450
-                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
451
-                        if ($this->debug) {
452
-                            \EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
453
-                                'subtracting', __FILE__, __LINE__);
454
-                        }
455
-                    }
456
-                }
457
-            }
458
-        }
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     * @param string $datetime_identifier
465
-     * @param array  $tickets
466
-     */
467
-    private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
468
-    {
469
-        // make sure a reg limit is set for the datetime
470
-        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
471
-            ? $this->datetime_spaces[ $datetime_identifier ]
472
-            : 0;
473
-        // and bail if it is not
474
-        if ( ! $reg_limit) {
475
-            if ($this->debug) {
476
-                \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
477
-            }
478
-            return;
479
-        }
480
-        if ($this->debug) {
481
-            \EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
482
-            \EEH_Debug_Tools::printr("{$reg_limit}", 'REG LIMIT', __FILE__, __LINE__);
483
-        }
484
-        // number of allocated spaces always starts at zero
485
-        $spaces_allocated                           = 0;
486
-        $this->total_spaces[ $datetime_identifier ] = 0;
487
-        foreach ($tickets as $ticket_identifier) {
488
-            $spaces_allocated = $this->calculateAvailableSpacesForTicket(
489
-                $datetime_identifier,
490
-                $reg_limit,
491
-                $ticket_identifier,
492
-                $spaces_allocated
493
-            );
494
-        }
495
-        // spaces can't be negative
496
-        $spaces_allocated = max($spaces_allocated, 0);
497
-        if ($spaces_allocated) {
498
-            // track any non-zero values
499
-            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
500
-            if ($this->debug) {
501
-                \EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
502
-            }
503
-        } else {
504
-            if ($this->debug) {
505
-                \EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
506
-            }
507
-        }
508
-        if ($this->debug) {
509
-            \EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
510
-                __LINE__);
511
-            \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
512
-            \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
513
-        }
514
-    }
515
-
516
-
517
-
518
-    /**
519
-     * @param string $datetime_identifier
520
-     * @param int    $reg_limit
521
-     * @param string $ticket_identifier
522
-     * @param int    $spaces_allocated
523
-     * @return int
524
-     */
525
-    private function calculateAvailableSpacesForTicket(
526
-        $datetime_identifier,
527
-        $reg_limit,
528
-        $ticket_identifier,
529
-        $spaces_allocated
530
-    ) {
531
-        // make sure ticket quantity is set
532
-        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
533
-            ? $this->ticket_quantities[ $ticket_identifier ]
534
-            : 0;
535
-        if ($this->debug) {
536
-            \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
537
-            \EEH_Debug_Tools::printr("{$ticket_quantity}", "ticket $ticket_identifier quantity: ",
538
-                __FILE__, __LINE__, 2);
539
-        }
540
-        if ($ticket_quantity) {
541
-            if ($this->debug) {
542
-                \EEH_Debug_Tools::printr(
543
-                    ($spaces_allocated <= $reg_limit)
544
-                        ? 'true'
545
-                        : 'false',
546
-                    ' . spaces_allocated <= reg_limit = ',
547
-                    __FILE__, __LINE__
548
-                );
549
-            }
550
-            // if the datetime is NOT at full capacity yet
551
-            if ($spaces_allocated <= $reg_limit) {
552
-                // then the maximum ticket quantity we can allocate is the lowest value of either:
553
-                //  the number of remaining spaces for the datetime, which is the limit - spaces already taken
554
-                //  or the maximum ticket quantity
555
-                $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
556
-                // adjust the available quantity in our tracking array
557
-                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
558
-                // and increment spaces allocated for this datetime
559
-                $spaces_allocated += $ticket_quantity;
560
-                $at_capacity = $spaces_allocated >= $reg_limit;
561
-                if ($this->debug) {
562
-                    \EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
563
-                        __FILE__, __LINE__,   3);
564
-                    if ($at_capacity) {
565
-                        \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
566
-                    }
567
-                }
568
-                // now adjust all other datetimes that allow access to this ticket
569
-                $this->adjustDatetimes(
570
-                    $datetime_identifier,
571
-                    $ticket_identifier,
572
-                    $ticket_quantity,
573
-                    $at_capacity
574
-                );
575
-            }
576
-        }
577
-        return $spaces_allocated;
578
-    }
579
-
580
-
581
-
582
-    /**
583
-     * subtracts ticket amounts from all datetime reg limits
584
-     * that allow access to the ticket specified,
585
-     * because that ticket could be used
586
-     * to attend any of the datetimes it has access to
587
-     *
588
-     * @param string $datetime_identifier
589
-     * @param string $ticket_identifier
590
-     * @param bool   $at_capacity
591
-     * @param int    $ticket_quantity
592
-     */
593
-    private function adjustDatetimes(
594
-        $datetime_identifier,
595
-        $ticket_identifier,
596
-        $ticket_quantity,
597
-        $at_capacity
598
-    ) {
599
-        /** @var array $datetime_tickets */
600
-        foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
601
-            if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
602
-                continue;
603
-            }
604
-            $adjusted = $this->adjustDatetimeSpaces(
605
-                $datetime_ID,
606
-                $ticket_identifier,
607
-                $ticket_quantity
608
-            );
609
-            // skip to next ticket if nothing changed
610
-            if (! ($adjusted || $at_capacity)) {
611
-                continue;
612
-            }
613
-            // then all of it's tickets are now unavailable
614
-            foreach ($datetime_tickets as $datetime_ticket) {
615
-                if (
616
-                    ($ticket_identifier === $datetime_ticket || $at_capacity)
617
-                    && isset($this->ticket_quantities[ $datetime_ticket ])
618
-                    && $this->ticket_quantities[ $datetime_ticket ] > 0
619
-                ) {
620
-                    if ($this->debug) {
621
-                        \EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
622
-                            __LINE__);
623
-                    }
624
-                    // if this datetime is at full capacity, set any tracked available quantities to zero
625
-                    // otherwise just subtract the ticket quantity
626
-                    $new_quantity = $at_capacity
627
-                        ? 0
628
-                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
629
-                    // don't let ticket quantity go below zero
630
-                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
631
-                    if ($this->debug) {
632
-                        \EEH_Debug_Tools::printr(
633
-                            $at_capacity
634
-                                ? "0 because Datetime {$datetime_identifier} is at capacity"
635
-                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
636
-                            " . . . . {$datetime_ticket} quantity set to ",
637
-                            __FILE__, __LINE__
638
-                        );
639
-                    }
640
-                }
641
-                // but we also need to adjust spaces for any other datetimes this ticket has access to
642
-                if ($datetime_ticket === $ticket_identifier) {
643
-                    if (isset($this->ticket_datetimes[ $datetime_ticket ])
644
-                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
645
-                    ) {
646
-                        if ($this->debug) {
647
-                            \EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
648
-                                __LINE__);
649
-                        }
650
-                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
651
-                            // don't adjust the current datetime twice
652
-                            if ($datetime !== $datetime_identifier) {
653
-                                $this->adjustDatetimeSpaces(
654
-                                    $datetime,
655
-                                    $datetime_ticket,
656
-                                    $ticket_quantity
657
-                                );
658
-                            }
659
-                        }
660
-                    }
661
-                }
662
-            }
663
-        }
664
-    }
665
-
666
-    private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
667
-    {
668
-        // does datetime have spaces available?
669
-        // and does the supplied ticket have access to this datetime ?
670
-        if (
671
-            $this->datetime_spaces[ $datetime_identifier ] > 0
672
-            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
673
-            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
674
-            ) {
675
-            if ($this->debug) {
676
-                \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
677
-                \EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
678
-            }
679
-            // then decrement the available spaces for the datetime
680
-            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
681
-            // but don't let quantities go below zero
682
-            $this->datetime_spaces[ $datetime_identifier ] = max(
683
-                $this->datetime_spaces[ $datetime_identifier ],
684
-                0
685
-            );
686
-            if ($this->debug) {
687
-                \EEH_Debug_Tools::printr("{$ticket_quantity}",
688
-                    " . . . {$datetime_identifier} capacity reduced by", __FILE__, __LINE__);
689
-            }
690
-            return true;
691
-        }
692
-        return false;
693
-    }
34
+	/**
35
+	 * @var EE_Event $event
36
+	 */
37
+	private $event;
38
+
39
+	/**
40
+	 * @var array $datetime_query_params
41
+	 */
42
+	private $datetime_query_params;
43
+
44
+	/**
45
+	 * @var EE_Ticket[] $active_tickets
46
+	 */
47
+	private $active_tickets = array();
48
+
49
+	/**
50
+	 * @var EE_Datetime[] $datetimes
51
+	 */
52
+	private $datetimes = array();
53
+
54
+	/**
55
+	 * Array of Ticket IDs grouped by Datetime
56
+	 *
57
+	 * @var array $datetimes
58
+	 */
59
+	private $datetime_tickets = array();
60
+
61
+	/**
62
+	 * Max spaces for each Datetime (reg limit - previous sold)
63
+	 *
64
+	 * @var array $datetime_spaces
65
+	 */
66
+	private $datetime_spaces = array();
67
+
68
+	/**
69
+	 * Array of Datetime IDs grouped by Ticket
70
+	 *
71
+	 * @var array[] $ticket_datetimes
72
+	 */
73
+	private $ticket_datetimes = array();
74
+
75
+	/**
76
+	 * maximum ticket quantities for each ticket (adjusted for reg limit)
77
+	 *
78
+	 * @var array $ticket_quantities
79
+	 */
80
+	private $ticket_quantities = array();
81
+
82
+	/**
83
+	 * total quantity of sold and reserved for each ticket
84
+	 *
85
+	 * @var array $tickets_sold
86
+	 */
87
+	private $tickets_sold = array();
88
+
89
+	/**
90
+	 * total spaces available across all datetimes
91
+	 *
92
+	 * @var array $total_spaces
93
+	 */
94
+	private $total_spaces = array();
95
+
96
+	/**
97
+	 * @var boolean $debug
98
+	 */
99
+	private $debug = false;
100
+
101
+	/**
102
+	 * @var null|int $spaces_remaining
103
+	 */
104
+	private $spaces_remaining;
105
+
106
+	/**
107
+	 * @var null|int $total_spaces_available
108
+	 */
109
+	private $total_spaces_available;
110
+
111
+
112
+
113
+	/**
114
+	 * EventSpacesCalculator constructor.
115
+	 *
116
+	 * @param EE_Event $event
117
+	 * @param array    $datetime_query_params
118
+	 * @throws EE_Error
119
+	 */
120
+	public function __construct(EE_Event $event, array $datetime_query_params = array())
121
+	{
122
+		$this->event                 = $event;
123
+		$this->datetime_query_params = $datetime_query_params + array('order_by' => array('DTT_reg_limit' => 'ASC'));
124
+		$this->setHooks();
125
+	}
126
+
127
+
128
+
129
+	/**
130
+	 * @return void
131
+	 */
132
+	private function setHooks()
133
+	{
134
+		add_action( 'AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
+		add_action( 'AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
+		add_action( 'AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
+		add_action( 'AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
+		add_action( 'AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
+		add_action( 'AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
+		add_action( 'AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
+		add_action( 'AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 * @return void
148
+	 */
149
+	public function clearResults()
150
+	{
151
+		$this->spaces_remaining = null;
152
+		$this->total_spaces_available = null;
153
+	}
154
+
155
+
156
+
157
+	/**
158
+	 * @return EE_Ticket[]
159
+	 * @throws EE_Error
160
+	 * @throws InvalidDataTypeException
161
+	 * @throws InvalidInterfaceException
162
+	 * @throws InvalidArgumentException
163
+	 */
164
+	public function getActiveTickets()
165
+	{
166
+		if (empty($this->active_tickets)) {
167
+			$this->active_tickets = $this->event->tickets(
168
+				array(
169
+					array(
170
+						'TKT_end_date' => array('>=', EEM_Ticket::instance()->current_time_for_query('TKT_end_date')),
171
+						'TKT_deleted'  => false,
172
+					),
173
+					'order_by' => array('TKT_qty' => 'ASC'),
174
+				)
175
+			);
176
+		}
177
+		return $this->active_tickets;
178
+	}
179
+
180
+
181
+
182
+	/**
183
+	 * @param EE_Ticket[] $active_tickets
184
+	 * @throws EE_Error
185
+	 * @throws DomainException
186
+	 * @throws UnexpectedEntityException
187
+	 */
188
+	public function setActiveTickets(array $active_tickets = array())
189
+	{
190
+		if ( ! empty($active_tickets)) {
191
+			foreach ($active_tickets as $active_ticket) {
192
+				$this->validateTicket($active_ticket);
193
+			}
194
+			// sort incoming array by ticket quantity (asc)
195
+			usort(
196
+				$active_tickets,
197
+				function (EE_Ticket $a, EE_Ticket $b) {
198
+					if ($a->qty() === $b->qty()) {
199
+						return 0;
200
+					}
201
+					return ($a->qty() < $b->qty())
202
+						? -1
203
+						: 1;
204
+				}
205
+			);
206
+		}
207
+		$this->active_tickets = $active_tickets;
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 * @param $ticket
214
+	 * @throws DomainException
215
+	 * @throws EE_Error
216
+	 * @throws UnexpectedEntityException
217
+	 */
218
+	private function validateTicket($ticket)
219
+	{
220
+		if ( ! $ticket instanceof EE_Ticket) {
221
+			throw new DomainException(
222
+				esc_html__(
223
+					'Invalid Ticket. Only EE_Ticket objects can be used to calculate event space availability.',
224
+					'event_espresso'
225
+				)
226
+			);
227
+		}
228
+		if ($ticket->get_event_ID() !== $this->event->ID()) {
229
+			throw new DomainException(
230
+				sprintf(
231
+					esc_html__(
232
+						'An EE_Ticket for Event %1$d was supplied while calculating event space availability for Event %2$d.',
233
+						'event_espresso'
234
+					),
235
+					$ticket->get_event_ID(),
236
+					$this->event->ID()
237
+				)
238
+			);
239
+		}
240
+	}
241
+
242
+
243
+
244
+	/**
245
+	 * @return EE_Datetime[]
246
+	 */
247
+	public function getDatetimes()
248
+	{
249
+		return $this->datetimes;
250
+	}
251
+
252
+
253
+
254
+	/**
255
+	 * @param EE_Datetime $datetime
256
+	 * @throws EE_Error
257
+	 * @throws DomainException
258
+	 */
259
+	public function setDatetime(EE_Datetime $datetime)
260
+	{
261
+		if ($datetime->event()->ID() !== $this->event->ID()) {
262
+			throw new DomainException(
263
+				sprintf(
264
+					esc_html__(
265
+						'An EE_Datetime for Event %1$d was supplied while calculating event space availability for Event %2$d.',
266
+						'event_espresso'
267
+					),
268
+					$datetime->event()->ID(),
269
+					$this->event->ID()
270
+				)
271
+			);
272
+		}
273
+		$this->datetimes[ $datetime->ID() ] = $datetime;
274
+	}
275
+
276
+
277
+
278
+	/**
279
+	 * calculate spaces remaining based on "saleable" tickets
280
+	 *
281
+	 * @return float|int
282
+	 * @throws EE_Error
283
+	 * @throws DomainException
284
+	 * @throws UnexpectedEntityException
285
+	 * @throws InvalidDataTypeException
286
+	 * @throws InvalidInterfaceException
287
+	 * @throws InvalidArgumentException
288
+	 */
289
+	public function spacesRemaining()
290
+	{
291
+		if ($this->spaces_remaining === null) {
292
+			$this->initialize();
293
+			$this->spaces_remaining = $this->calculate();
294
+		}
295
+		return $this->spaces_remaining;
296
+	}
297
+
298
+
299
+
300
+	/**
301
+	 * calculates total available spaces for an event with no regard for sold tickets
302
+	 *
303
+	 * @return int|float
304
+	 * @throws EE_Error
305
+	 * @throws DomainException
306
+	 * @throws UnexpectedEntityException
307
+	 * @throws InvalidDataTypeException
308
+	 * @throws InvalidInterfaceException
309
+	 * @throws InvalidArgumentException
310
+	 */
311
+	public function totalSpacesAvailable()
312
+	{
313
+		if($this->total_spaces_available === null) {
314
+			$this->initialize();
315
+			$this->total_spaces_available = $this->calculate(false);
316
+		}
317
+		return $this->total_spaces_available;
318
+	}
319
+
320
+
321
+
322
+	/**
323
+	 * Loops through the active tickets for the event
324
+	 * and builds a series of data arrays that will be used for calculating
325
+	 * the total maximum available spaces, as well as the spaces remaining.
326
+	 * Because ticket quantities affect datetime spaces and vice versa,
327
+	 * we need to be constantly updating these data arrays as things change,
328
+	 * which is the entire reason for their existence.
329
+	 *
330
+	 * @throws EE_Error
331
+	 * @throws DomainException
332
+	 * @throws UnexpectedEntityException
333
+	 * @throws InvalidDataTypeException
334
+	 * @throws InvalidInterfaceException
335
+	 * @throws InvalidArgumentException
336
+	 */
337
+	private function initialize()
338
+	{
339
+		if ($this->debug) {
340
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
341
+		}
342
+		$this->datetime_tickets  = array();
343
+		$this->datetime_spaces   = array();
344
+		$this->ticket_datetimes  = array();
345
+		$this->ticket_quantities = array();
346
+		$this->tickets_sold      = array();
347
+		$this->total_spaces      = array();
348
+		$active_tickets          = $this->getActiveTickets();
349
+		if ( ! empty($active_tickets)) {
350
+			foreach ($active_tickets as $ticket) {
351
+				$this->validateTicket($ticket);
352
+				// we need to index our data arrays using strings for the purpose of sorting,
353
+				// but we also need them to be unique, so  we'll just prepend a letter T to the ID
354
+				$ticket_identifier = "T{$ticket->ID()}";
355
+				// to start, we'll just consider the raw qty to be the maximum availability for this ticket
356
+				$max_tickets = $ticket->qty();
357
+				// but we'll adjust that after looping over each datetime for the ticket and checking reg limits
358
+				$ticket_datetimes = $ticket->datetimes($this->datetime_query_params);
359
+				foreach ($ticket_datetimes as $datetime) {
360
+					// save all datetimes
361
+					$this->setDatetime($datetime);
362
+					$datetime_identifier = "D{$datetime->ID()}";
363
+					$reg_limit           = $datetime->reg_limit();
364
+					// ticket quantity can not exceed datetime reg limit
365
+					$max_tickets = min($max_tickets, $reg_limit);
366
+					// as described earlier, because we need to be able to constantly adjust numbers for things,
367
+					// we are going to move all of our data into the following arrays:
368
+					// datetime spaces initially represents the reg limit for each datetime,
369
+					// but this will get adjusted as tickets are accounted for
370
+					$this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
371
+					// just an array of ticket IDs grouped by datetime
372
+					$this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
373
+					// and an array of datetime IDs grouped by ticket
374
+					$this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
375
+				}
376
+				// total quantity of sold and reserved for each ticket
377
+				$this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
378
+				// and the maximum ticket quantities for each ticket (adjusted for reg limit)
379
+				$this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
380
+			}
381
+		}
382
+		// sort datetime spaces by reg limit, but maintain our string indexes
383
+		asort($this->datetime_spaces, SORT_NUMERIC);
384
+		// datetime tickets need to be sorted in the SAME order as the above array...
385
+		// so we'll just use array_merge() to take the structure of datetime_spaces
386
+		// but overwrite all of the data with that from datetime_tickets
387
+		$this->datetime_tickets = array_merge(
388
+			$this->datetime_spaces,
389
+			$this->datetime_tickets
390
+		);
391
+		if ($this->debug) {
392
+			\EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
393
+			\EEH_Debug_Tools::printr($this->datetime_tickets, 'datetime_tickets', __FILE__, __LINE__);
394
+			\EEH_Debug_Tools::printr($this->ticket_quantities, 'ticket_quantities', __FILE__, __LINE__);
395
+		}
396
+	}
397
+
398
+
399
+
400
+	/**
401
+	 * performs calculations on initialized data
402
+	 *
403
+	 * @param bool $consider_sold
404
+	 * @return int|float
405
+	 */
406
+	private function calculate($consider_sold = true)
407
+	{
408
+		if ($this->debug) {
409
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
410
+		}
411
+		if ($consider_sold) {
412
+			// subtract amounts sold from all ticket quantities and datetime spaces
413
+			$this->adjustTicketQuantitiesDueToSales();
414
+		}
415
+		foreach ($this->datetime_tickets as $datetime_identifier => $tickets) {
416
+			$this->trackAvailableSpacesForDatetimes($datetime_identifier, $tickets);
417
+		}
418
+		// total spaces available is just the sum of the spaces available for each datetime
419
+		$spaces_remaining = array_sum($this->total_spaces);
420
+		if ($this->debug) {
421
+			\EEH_Debug_Tools::printr($this->total_spaces, '$this->total_spaces', __FILE__, __LINE__);
422
+			\EEH_Debug_Tools::printr($this->tickets_sold, '$this->tickets_sold', __FILE__, __LINE__);
423
+			\EEH_Debug_Tools::printr($spaces_remaining, '$spaces_remaining', __FILE__, __LINE__);
424
+		}
425
+		return $spaces_remaining;
426
+	}
427
+
428
+
429
+	/**
430
+	 * subtracts amount of  tickets sold from ticket quantities and datetime spaces
431
+	 */
432
+	private function adjustTicketQuantitiesDueToSales()
433
+	{
434
+		if ($this->debug) {
435
+			\EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
436
+		}
437
+		foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
438
+			if (isset($this->ticket_quantities[ $ticket_identifier ])){
439
+				$this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
440
+				if ($this->debug) {
441
+					\EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
442
+				}
443
+			}
444
+			if (
445
+				isset($this->ticket_datetimes[ $ticket_identifier ])
446
+				&& is_array($this->ticket_datetimes[ $ticket_identifier ])
447
+			){
448
+				foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
449
+					if (isset($this->ticket_quantities[ $ticket_identifier ])) {
450
+						$this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
451
+						if ($this->debug) {
452
+							\EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
453
+								'subtracting', __FILE__, __LINE__);
454
+						}
455
+					}
456
+				}
457
+			}
458
+		}
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 * @param string $datetime_identifier
465
+	 * @param array  $tickets
466
+	 */
467
+	private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
468
+	{
469
+		// make sure a reg limit is set for the datetime
470
+		$reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
471
+			? $this->datetime_spaces[ $datetime_identifier ]
472
+			: 0;
473
+		// and bail if it is not
474
+		if ( ! $reg_limit) {
475
+			if ($this->debug) {
476
+				\EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__);
477
+			}
478
+			return;
479
+		}
480
+		if ($this->debug) {
481
+			\EEH_Debug_Tools::printr($datetime_identifier, '* $datetime_identifier', __FILE__, __LINE__, 1);
482
+			\EEH_Debug_Tools::printr("{$reg_limit}", 'REG LIMIT', __FILE__, __LINE__);
483
+		}
484
+		// number of allocated spaces always starts at zero
485
+		$spaces_allocated                           = 0;
486
+		$this->total_spaces[ $datetime_identifier ] = 0;
487
+		foreach ($tickets as $ticket_identifier) {
488
+			$spaces_allocated = $this->calculateAvailableSpacesForTicket(
489
+				$datetime_identifier,
490
+				$reg_limit,
491
+				$ticket_identifier,
492
+				$spaces_allocated
493
+			);
494
+		}
495
+		// spaces can't be negative
496
+		$spaces_allocated = max($spaces_allocated, 0);
497
+		if ($spaces_allocated) {
498
+			// track any non-zero values
499
+			$this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
500
+			if ($this->debug) {
501
+				\EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
502
+			}
503
+		} else {
504
+			if ($this->debug) {
505
+				\EEH_Debug_Tools::printr(' ', ' . NO TICKETS AVAILABLE FOR DATETIME', __FILE__, __LINE__);
506
+			}
507
+		}
508
+		if ($this->debug) {
509
+			\EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
510
+				__LINE__);
511
+			\EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
512
+			\EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
513
+		}
514
+	}
515
+
516
+
517
+
518
+	/**
519
+	 * @param string $datetime_identifier
520
+	 * @param int    $reg_limit
521
+	 * @param string $ticket_identifier
522
+	 * @param int    $spaces_allocated
523
+	 * @return int
524
+	 */
525
+	private function calculateAvailableSpacesForTicket(
526
+		$datetime_identifier,
527
+		$reg_limit,
528
+		$ticket_identifier,
529
+		$spaces_allocated
530
+	) {
531
+		// make sure ticket quantity is set
532
+		$ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
533
+			? $this->ticket_quantities[ $ticket_identifier ]
534
+			: 0;
535
+		if ($this->debug) {
536
+			\EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
537
+			\EEH_Debug_Tools::printr("{$ticket_quantity}", "ticket $ticket_identifier quantity: ",
538
+				__FILE__, __LINE__, 2);
539
+		}
540
+		if ($ticket_quantity) {
541
+			if ($this->debug) {
542
+				\EEH_Debug_Tools::printr(
543
+					($spaces_allocated <= $reg_limit)
544
+						? 'true'
545
+						: 'false',
546
+					' . spaces_allocated <= reg_limit = ',
547
+					__FILE__, __LINE__
548
+				);
549
+			}
550
+			// if the datetime is NOT at full capacity yet
551
+			if ($spaces_allocated <= $reg_limit) {
552
+				// then the maximum ticket quantity we can allocate is the lowest value of either:
553
+				//  the number of remaining spaces for the datetime, which is the limit - spaces already taken
554
+				//  or the maximum ticket quantity
555
+				$ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
556
+				// adjust the available quantity in our tracking array
557
+				$this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
558
+				// and increment spaces allocated for this datetime
559
+				$spaces_allocated += $ticket_quantity;
560
+				$at_capacity = $spaces_allocated >= $reg_limit;
561
+				if ($this->debug) {
562
+					\EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
563
+						__FILE__, __LINE__,   3);
564
+					if ($at_capacity) {
565
+						\EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
566
+					}
567
+				}
568
+				// now adjust all other datetimes that allow access to this ticket
569
+				$this->adjustDatetimes(
570
+					$datetime_identifier,
571
+					$ticket_identifier,
572
+					$ticket_quantity,
573
+					$at_capacity
574
+				);
575
+			}
576
+		}
577
+		return $spaces_allocated;
578
+	}
579
+
580
+
581
+
582
+	/**
583
+	 * subtracts ticket amounts from all datetime reg limits
584
+	 * that allow access to the ticket specified,
585
+	 * because that ticket could be used
586
+	 * to attend any of the datetimes it has access to
587
+	 *
588
+	 * @param string $datetime_identifier
589
+	 * @param string $ticket_identifier
590
+	 * @param bool   $at_capacity
591
+	 * @param int    $ticket_quantity
592
+	 */
593
+	private function adjustDatetimes(
594
+		$datetime_identifier,
595
+		$ticket_identifier,
596
+		$ticket_quantity,
597
+		$at_capacity
598
+	) {
599
+		/** @var array $datetime_tickets */
600
+		foreach ($this->datetime_tickets as $datetime_ID => $datetime_tickets) {
601
+			if ($datetime_ID !== $datetime_identifier || ! is_array($datetime_tickets)) {
602
+				continue;
603
+			}
604
+			$adjusted = $this->adjustDatetimeSpaces(
605
+				$datetime_ID,
606
+				$ticket_identifier,
607
+				$ticket_quantity
608
+			);
609
+			// skip to next ticket if nothing changed
610
+			if (! ($adjusted || $at_capacity)) {
611
+				continue;
612
+			}
613
+			// then all of it's tickets are now unavailable
614
+			foreach ($datetime_tickets as $datetime_ticket) {
615
+				if (
616
+					($ticket_identifier === $datetime_ticket || $at_capacity)
617
+					&& isset($this->ticket_quantities[ $datetime_ticket ])
618
+					&& $this->ticket_quantities[ $datetime_ticket ] > 0
619
+				) {
620
+					if ($this->debug) {
621
+						\EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
622
+							__LINE__);
623
+					}
624
+					// if this datetime is at full capacity, set any tracked available quantities to zero
625
+					// otherwise just subtract the ticket quantity
626
+					$new_quantity = $at_capacity
627
+						? 0
628
+						: $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
629
+					// don't let ticket quantity go below zero
630
+					$this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
631
+					if ($this->debug) {
632
+						\EEH_Debug_Tools::printr(
633
+							$at_capacity
634
+								? "0 because Datetime {$datetime_identifier} is at capacity"
635
+								: "{$this->ticket_quantities[ $datetime_ticket ]}",
636
+							" . . . . {$datetime_ticket} quantity set to ",
637
+							__FILE__, __LINE__
638
+						);
639
+					}
640
+				}
641
+				// but we also need to adjust spaces for any other datetimes this ticket has access to
642
+				if ($datetime_ticket === $ticket_identifier) {
643
+					if (isset($this->ticket_datetimes[ $datetime_ticket ])
644
+						&& is_array($this->ticket_datetimes[ $datetime_ticket ])
645
+					) {
646
+						if ($this->debug) {
647
+							\EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
648
+								__LINE__);
649
+						}
650
+						foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
651
+							// don't adjust the current datetime twice
652
+							if ($datetime !== $datetime_identifier) {
653
+								$this->adjustDatetimeSpaces(
654
+									$datetime,
655
+									$datetime_ticket,
656
+									$ticket_quantity
657
+								);
658
+							}
659
+						}
660
+					}
661
+				}
662
+			}
663
+		}
664
+	}
665
+
666
+	private function adjustDatetimeSpaces($datetime_identifier, $ticket_identifier, $ticket_quantity = 0)
667
+	{
668
+		// does datetime have spaces available?
669
+		// and does the supplied ticket have access to this datetime ?
670
+		if (
671
+			$this->datetime_spaces[ $datetime_identifier ] > 0
672
+			&& isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
673
+			&& in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
674
+			) {
675
+			if ($this->debug) {
676
+				\EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
677
+				\EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
678
+			}
679
+			// then decrement the available spaces for the datetime
680
+			$this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
681
+			// but don't let quantities go below zero
682
+			$this->datetime_spaces[ $datetime_identifier ] = max(
683
+				$this->datetime_spaces[ $datetime_identifier ],
684
+				0
685
+			);
686
+			if ($this->debug) {
687
+				\EEH_Debug_Tools::printr("{$ticket_quantity}",
688
+					" . . . {$datetime_identifier} capacity reduced by", __FILE__, __LINE__);
689
+			}
690
+			return true;
691
+		}
692
+		return false;
693
+	}
694 694
 
695 695
 }
696 696
 // Location: EventSpacesCalculator.php
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -131,14 +131,14 @@  discard block
 block discarded – undo
131 131
      */
132 132
     private function setHooks()
133 133
     {
134
-        add_action( 'AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
-        add_action( 'AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
-        add_action( 'AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
-        add_action( 'AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
-        add_action( 'AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
-        add_action( 'AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
-        add_action( 'AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
-        add_action( 'AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
134
+        add_action('AHEE__EE_Ticket__increase_sold', array($this, 'clearResults'));
135
+        add_action('AHEE__EE_Ticket__decrease_sold', array($this, 'clearResults'));
136
+        add_action('AHEE__EE_Datetime__increase_sold', array($this, 'clearResults'));
137
+        add_action('AHEE__EE_Datetime__decrease_sold', array($this, 'clearResults'));
138
+        add_action('AHEE__EE_Ticket__increase_reserved', array($this, 'clearResults'));
139
+        add_action('AHEE__EE_Ticket__decrease_reserved', array($this, 'clearResults'));
140
+        add_action('AHEE__EE_Datetime__increase_reserved', array($this, 'clearResults'));
141
+        add_action('AHEE__EE_Datetime__decrease_reserved', array($this, 'clearResults'));
142 142
     }
143 143
 
144 144
 
@@ -194,7 +194,7 @@  discard block
 block discarded – undo
194 194
             // sort incoming array by ticket quantity (asc)
195 195
             usort(
196 196
                 $active_tickets,
197
-                function (EE_Ticket $a, EE_Ticket $b) {
197
+                function(EE_Ticket $a, EE_Ticket $b) {
198 198
                     if ($a->qty() === $b->qty()) {
199 199
                         return 0;
200 200
                     }
@@ -270,7 +270,7 @@  discard block
 block discarded – undo
270 270
                 )
271 271
             );
272 272
         }
273
-        $this->datetimes[ $datetime->ID() ] = $datetime;
273
+        $this->datetimes[$datetime->ID()] = $datetime;
274 274
     }
275 275
 
276 276
 
@@ -310,7 +310,7 @@  discard block
 block discarded – undo
310 310
      */
311 311
     public function totalSpacesAvailable()
312 312
     {
313
-        if($this->total_spaces_available === null) {
313
+        if ($this->total_spaces_available === null) {
314 314
             $this->initialize();
315 315
             $this->total_spaces_available = $this->calculate(false);
316 316
         }
@@ -367,16 +367,16 @@  discard block
 block discarded – undo
367 367
                     // we are going to move all of our data into the following arrays:
368 368
                     // datetime spaces initially represents the reg limit for each datetime,
369 369
                     // but this will get adjusted as tickets are accounted for
370
-                    $this->datetime_spaces[ $datetime_identifier ] = $reg_limit;
370
+                    $this->datetime_spaces[$datetime_identifier] = $reg_limit;
371 371
                     // just an array of ticket IDs grouped by datetime
372
-                    $this->datetime_tickets[ $datetime_identifier ][] = $ticket_identifier;
372
+                    $this->datetime_tickets[$datetime_identifier][] = $ticket_identifier;
373 373
                     // and an array of datetime IDs grouped by ticket
374
-                    $this->ticket_datetimes[ $ticket_identifier ][] = $datetime_identifier;
374
+                    $this->ticket_datetimes[$ticket_identifier][] = $datetime_identifier;
375 375
                 }
376 376
                 // total quantity of sold and reserved for each ticket
377
-                $this->tickets_sold[ $ticket_identifier ] = $ticket->sold() + $ticket->reserved();
377
+                $this->tickets_sold[$ticket_identifier] = $ticket->sold() + $ticket->reserved();
378 378
                 // and the maximum ticket quantities for each ticket (adjusted for reg limit)
379
-                $this->ticket_quantities[ $ticket_identifier ] = $max_tickets;
379
+                $this->ticket_quantities[$ticket_identifier] = $max_tickets;
380 380
             }
381 381
         }
382 382
         // sort datetime spaces by reg limit, but maintain our string indexes
@@ -435,19 +435,19 @@  discard block
 block discarded – undo
435 435
             \EEH_Debug_Tools::printr(__FUNCTION__, __CLASS__, __FILE__, __LINE__, 2);
436 436
         }
437 437
         foreach ($this->tickets_sold as $ticket_identifier => $tickets_sold) {
438
-            if (isset($this->ticket_quantities[ $ticket_identifier ])){
439
-                $this->ticket_quantities[ $ticket_identifier ] -= $tickets_sold;
438
+            if (isset($this->ticket_quantities[$ticket_identifier])) {
439
+                $this->ticket_quantities[$ticket_identifier] -= $tickets_sold;
440 440
                 if ($this->debug) {
441 441
                     \EEH_Debug_Tools::printr("{$tickets_sold} sales for ticket {$ticket_identifier} ", 'subtracting', __FILE__, __LINE__);
442 442
                 }
443 443
             }
444 444
             if (
445
-                isset($this->ticket_datetimes[ $ticket_identifier ])
446
-                && is_array($this->ticket_datetimes[ $ticket_identifier ])
447
-            ){
448
-                foreach ($this->ticket_datetimes[ $ticket_identifier ] as $ticket_datetime) {
449
-                    if (isset($this->ticket_quantities[ $ticket_identifier ])) {
450
-                        $this->datetime_spaces[ $ticket_datetime ] -= $tickets_sold;
445
+                isset($this->ticket_datetimes[$ticket_identifier])
446
+                && is_array($this->ticket_datetimes[$ticket_identifier])
447
+            ) {
448
+                foreach ($this->ticket_datetimes[$ticket_identifier] as $ticket_datetime) {
449
+                    if (isset($this->ticket_quantities[$ticket_identifier])) {
450
+                        $this->datetime_spaces[$ticket_datetime] -= $tickets_sold;
451 451
                         if ($this->debug) {
452 452
                             \EEH_Debug_Tools::printr("{$tickets_sold} sales for datetime {$ticket_datetime} ",
453 453
                                 'subtracting', __FILE__, __LINE__);
@@ -467,8 +467,8 @@  discard block
 block discarded – undo
467 467
     private function trackAvailableSpacesForDatetimes($datetime_identifier, array $tickets)
468 468
     {
469 469
         // make sure a reg limit is set for the datetime
470
-        $reg_limit = isset($this->datetime_spaces[ $datetime_identifier ])
471
-            ? $this->datetime_spaces[ $datetime_identifier ]
470
+        $reg_limit = isset($this->datetime_spaces[$datetime_identifier])
471
+            ? $this->datetime_spaces[$datetime_identifier]
472 472
             : 0;
473 473
         // and bail if it is not
474 474
         if ( ! $reg_limit) {
@@ -483,7 +483,7 @@  discard block
 block discarded – undo
483 483
         }
484 484
         // number of allocated spaces always starts at zero
485 485
         $spaces_allocated                           = 0;
486
-        $this->total_spaces[ $datetime_identifier ] = 0;
486
+        $this->total_spaces[$datetime_identifier] = 0;
487 487
         foreach ($tickets as $ticket_identifier) {
488 488
             $spaces_allocated = $this->calculateAvailableSpacesForTicket(
489 489
                 $datetime_identifier,
@@ -496,9 +496,9 @@  discard block
 block discarded – undo
496 496
         $spaces_allocated = max($spaces_allocated, 0);
497 497
         if ($spaces_allocated) {
498 498
             // track any non-zero values
499
-            $this->total_spaces[ $datetime_identifier ] += $spaces_allocated;
499
+            $this->total_spaces[$datetime_identifier] += $spaces_allocated;
500 500
             if ($this->debug) {
501
-                \EEH_Debug_Tools::printr((string)$spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
501
+                \EEH_Debug_Tools::printr((string) $spaces_allocated, ' . $spaces_allocated: ', __FILE__, __LINE__);
502 502
             }
503 503
         } else {
504 504
             if ($this->debug) {
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
             }
507 507
         }
508 508
         if ($this->debug) {
509
-            \EEH_Debug_Tools::printr($this->total_spaces[ $datetime_identifier ], '$total_spaces', __FILE__,
509
+            \EEH_Debug_Tools::printr($this->total_spaces[$datetime_identifier], '$total_spaces', __FILE__,
510 510
                 __LINE__);
511 511
             \EEH_Debug_Tools::printr($this->ticket_quantities, '$ticket_quantities', __FILE__, __LINE__);
512 512
             \EEH_Debug_Tools::printr($this->datetime_spaces, 'datetime_spaces', __FILE__, __LINE__);
@@ -529,8 +529,8 @@  discard block
 block discarded – undo
529 529
         $spaces_allocated
530 530
     ) {
531 531
         // make sure ticket quantity is set
532
-        $ticket_quantity = isset($this->ticket_quantities[ $ticket_identifier ])
533
-            ? $this->ticket_quantities[ $ticket_identifier ]
532
+        $ticket_quantity = isset($this->ticket_quantities[$ticket_identifier])
533
+            ? $this->ticket_quantities[$ticket_identifier]
534 534
             : 0;
535 535
         if ($this->debug) {
536 536
             \EEH_Debug_Tools::printr("{$spaces_allocated}", '$spaces_allocated', __FILE__, __LINE__);
@@ -554,13 +554,13 @@  discard block
 block discarded – undo
554 554
                 //  or the maximum ticket quantity
555 555
                 $ticket_quantity = min($reg_limit - $spaces_allocated, $ticket_quantity);
556 556
                 // adjust the available quantity in our tracking array
557
-                $this->ticket_quantities[ $ticket_identifier ] -= $ticket_quantity;
557
+                $this->ticket_quantities[$ticket_identifier] -= $ticket_quantity;
558 558
                 // and increment spaces allocated for this datetime
559 559
                 $spaces_allocated += $ticket_quantity;
560 560
                 $at_capacity = $spaces_allocated >= $reg_limit;
561 561
                 if ($this->debug) {
562 562
                     \EEH_Debug_Tools::printr("{$ticket_quantity} {$ticket_identifier} tickets", ' > > allocate ',
563
-                        __FILE__, __LINE__,   3);
563
+                        __FILE__, __LINE__, 3);
564 564
                     if ($at_capacity) {
565 565
                         \EEH_Debug_Tools::printr('AT CAPACITY', " . {$datetime_identifier}", __FILE__, __LINE__, 3);
566 566
                     }
@@ -607,15 +607,15 @@  discard block
 block discarded – undo
607 607
                 $ticket_quantity
608 608
             );
609 609
             // skip to next ticket if nothing changed
610
-            if (! ($adjusted || $at_capacity)) {
610
+            if ( ! ($adjusted || $at_capacity)) {
611 611
                 continue;
612 612
             }
613 613
             // then all of it's tickets are now unavailable
614 614
             foreach ($datetime_tickets as $datetime_ticket) {
615 615
                 if (
616 616
                     ($ticket_identifier === $datetime_ticket || $at_capacity)
617
-                    && isset($this->ticket_quantities[ $datetime_ticket ])
618
-                    && $this->ticket_quantities[ $datetime_ticket ] > 0
617
+                    && isset($this->ticket_quantities[$datetime_ticket])
618
+                    && $this->ticket_quantities[$datetime_ticket] > 0
619 619
                 ) {
620 620
                     if ($this->debug) {
621 621
                         \EEH_Debug_Tools::printr($datetime_ticket, ' . . . adjust ticket quantities for', __FILE__,
@@ -625,14 +625,14 @@  discard block
 block discarded – undo
625 625
                     // otherwise just subtract the ticket quantity
626 626
                     $new_quantity = $at_capacity
627 627
                         ? 0
628
-                        : $this->ticket_quantities[ $datetime_ticket ] - $ticket_quantity;
628
+                        : $this->ticket_quantities[$datetime_ticket] - $ticket_quantity;
629 629
                     // don't let ticket quantity go below zero
630
-                    $this->ticket_quantities[ $datetime_ticket ] = max($new_quantity, 0);
630
+                    $this->ticket_quantities[$datetime_ticket] = max($new_quantity, 0);
631 631
                     if ($this->debug) {
632 632
                         \EEH_Debug_Tools::printr(
633 633
                             $at_capacity
634 634
                                 ? "0 because Datetime {$datetime_identifier} is at capacity"
635
-                                : "{$this->ticket_quantities[ $datetime_ticket ]}",
635
+                                : "{$this->ticket_quantities[$datetime_ticket]}",
636 636
                             " . . . . {$datetime_ticket} quantity set to ",
637 637
                             __FILE__, __LINE__
638 638
                         );
@@ -640,14 +640,14 @@  discard block
 block discarded – undo
640 640
                 }
641 641
                 // but we also need to adjust spaces for any other datetimes this ticket has access to
642 642
                 if ($datetime_ticket === $ticket_identifier) {
643
-                    if (isset($this->ticket_datetimes[ $datetime_ticket ])
644
-                        && is_array($this->ticket_datetimes[ $datetime_ticket ])
643
+                    if (isset($this->ticket_datetimes[$datetime_ticket])
644
+                        && is_array($this->ticket_datetimes[$datetime_ticket])
645 645
                     ) {
646 646
                         if ($this->debug) {
647 647
                             \EEH_Debug_Tools::printr($datetime_ticket, ' . . adjust other Datetimes for', __FILE__,
648 648
                                 __LINE__);
649 649
                         }
650
-                        foreach ($this->ticket_datetimes[ $datetime_ticket ] as $datetime) {
650
+                        foreach ($this->ticket_datetimes[$datetime_ticket] as $datetime) {
651 651
                             // don't adjust the current datetime twice
652 652
                             if ($datetime !== $datetime_identifier) {
653 653
                                 $this->adjustDatetimeSpaces(
@@ -668,19 +668,19 @@  discard block
 block discarded – undo
668 668
         // does datetime have spaces available?
669 669
         // and does the supplied ticket have access to this datetime ?
670 670
         if (
671
-            $this->datetime_spaces[ $datetime_identifier ] > 0
672
-            && isset($this->datetime_spaces[ $datetime_identifier ], $this->datetime_tickets[ $datetime_identifier ])
673
-            && in_array($ticket_identifier, $this->datetime_tickets[ $datetime_identifier ], true)
671
+            $this->datetime_spaces[$datetime_identifier] > 0
672
+            && isset($this->datetime_spaces[$datetime_identifier], $this->datetime_tickets[$datetime_identifier])
673
+            && in_array($ticket_identifier, $this->datetime_tickets[$datetime_identifier], true)
674 674
             ) {
675 675
             if ($this->debug) {
676 676
                 \EEH_Debug_Tools::printr($datetime_identifier, ' . . adjust Datetime Spaces for', __FILE__, __LINE__);
677
-                \EEH_Debug_Tools::printr("{$this->datetime_spaces[ $datetime_identifier ]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
677
+                \EEH_Debug_Tools::printr("{$this->datetime_spaces[$datetime_identifier]}", " . . current  {$datetime_identifier} spaces available", __FILE__, __LINE__);
678 678
             }
679 679
             // then decrement the available spaces for the datetime
680
-            $this->datetime_spaces[ $datetime_identifier ] -= $ticket_quantity;
680
+            $this->datetime_spaces[$datetime_identifier] -= $ticket_quantity;
681 681
             // but don't let quantities go below zero
682
-            $this->datetime_spaces[ $datetime_identifier ] = max(
683
-                $this->datetime_spaces[ $datetime_identifier ],
682
+            $this->datetime_spaces[$datetime_identifier] = max(
683
+                $this->datetime_spaces[$datetime_identifier],
684 684
                 0
685 685
             );
686 686
             if ($this->debug) {
Please login to merge, or discard this patch.
core/db_classes/EE_Ticket.class.php 2 patches
Indentation   +626 added lines, -626 removed lines patch added patch discarded remove patch
@@ -61,15 +61,15 @@  discard block
 block discarded – undo
61 61
 
62 62
 
63 63
 
64
-    /**
65
-     * @param array  $props_n_values          incoming values
66
-     * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
67
-     *                                        used.)
68
-     * @param array  $date_formats            incoming date_formats in an array where the first value is the
69
-     *                                        date_format and the second value is the time format
70
-     * @return EE_Ticket
71
-     * @throws \EE_Error
72
-     */
64
+	/**
65
+	 * @param array  $props_n_values          incoming values
66
+	 * @param string $timezone                incoming timezone (if not set the timezone set for the website will be
67
+	 *                                        used.)
68
+	 * @param array  $date_formats            incoming date_formats in an array where the first value is the
69
+	 *                                        date_format and the second value is the time format
70
+	 * @return EE_Ticket
71
+	 * @throws \EE_Error
72
+	 */
73 73
 	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
74 74
 		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
75 75
 		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
@@ -77,36 +77,36 @@  discard block
 block discarded – undo
77 77
 
78 78
 
79 79
 
80
-    /**
81
-     * @param array  $props_n_values  incoming values from the database
82
-     * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
83
-     *                                the website will be used.
84
-     * @return EE_Ticket
85
-     * @throws \EE_Error
86
-     */
80
+	/**
81
+	 * @param array  $props_n_values  incoming values from the database
82
+	 * @param string $timezone        incoming timezone as set by the model.  If not set the timezone for
83
+	 *                                the website will be used.
84
+	 * @return EE_Ticket
85
+	 * @throws \EE_Error
86
+	 */
87 87
 	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
88 88
 		return new self( $props_n_values, TRUE, $timezone );
89 89
 	}
90 90
 
91 91
 
92 92
 
93
-    /**
94
-     * @return bool
95
-     * @throws \EE_Error
96
-     */
93
+	/**
94
+	 * @return bool
95
+	 * @throws \EE_Error
96
+	 */
97 97
 	public function parent() {
98 98
 		return $this->get( 'TKT_parent' );
99 99
 	}
100 100
 
101 101
 
102 102
 
103
-    /**
104
-     * return if a ticket has quantities available for purchase
105
-     *
106
-     * @param  int $DTT_ID the primary key for a particular datetime
107
-     * @return boolean
108
-     * @throws \EE_Error
109
-     */
103
+	/**
104
+	 * return if a ticket has quantities available for purchase
105
+	 *
106
+	 * @param  int $DTT_ID the primary key for a particular datetime
107
+	 * @return boolean
108
+	 * @throws \EE_Error
109
+	 */
110 110
 	public function available( $DTT_ID = 0 ) {
111 111
 		// are we checking availability for a particular datetime ?
112 112
 		if ( $DTT_ID ) {
@@ -123,14 +123,14 @@  discard block
 block discarded – undo
123 123
 
124 124
 
125 125
 
126
-    /**
127
-     * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
128
-     *
129
-     * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the relevant status const
130
-     * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save further processing
131
-     * @return mixed status int if the display string isn't requested
132
-     * @throws \EE_Error
133
-     */
126
+	/**
127
+	 * Using the start date and end date this method calculates whether the ticket is On Sale, Pending, or Expired
128
+	 *
129
+	 * @param bool        $display   true = we'll return a localized string, otherwise we just return the value of the relevant status const
130
+	 * @param bool | null $remaining if it is already known that tickets are available, then simply pass a bool to save further processing
131
+	 * @return mixed status int if the display string isn't requested
132
+	 * @throws \EE_Error
133
+	 */
134 134
 	public function ticket_status( $display = FALSE, $remaining = null ) {
135 135
 		$remaining = is_bool( $remaining ) ? $remaining : $this->is_remaining();
136 136
 		if ( ! $remaining ) {
@@ -153,14 +153,14 @@  discard block
 block discarded – undo
153 153
 
154 154
 
155 155
 
156
-    /**
157
-     * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale considering ALL the factors used for figuring that out.
158
-     *
159
-     * @access public
160
-     * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
161
-     * @return boolean         true = tickets remaining, false not.
162
-     * @throws \EE_Error
163
-     */
156
+	/**
157
+	 * The purpose of this method is to simply return a boolean for whether there are any tickets remaining for sale considering ALL the factors used for figuring that out.
158
+	 *
159
+	 * @access public
160
+	 * @param  int $DTT_ID if an int above 0 is included here then we get a specific dtt.
161
+	 * @return boolean         true = tickets remaining, false not.
162
+	 * @throws \EE_Error
163
+	 */
164 164
 	public function is_remaining( $DTT_ID = 0 ) {
165 165
 		$num_remaining = $this->remaining( $DTT_ID );
166 166
 		if ( $num_remaining === 0 ) {
@@ -174,76 +174,76 @@  discard block
 block discarded – undo
174 174
 
175 175
 
176 176
 
177
-    /**
178
-     * return the total number of tickets available for purchase
179
-     *
180
-     * @param  int $DTT_ID the primary key for a particular datetime.
181
-     *                     set to 0 for all related datetimes
182
-     * @return int
183
-     * @throws \EE_Error
184
-     */
177
+	/**
178
+	 * return the total number of tickets available for purchase
179
+	 *
180
+	 * @param  int $DTT_ID the primary key for a particular datetime.
181
+	 *                     set to 0 for all related datetimes
182
+	 * @return int
183
+	 * @throws \EE_Error
184
+	 */
185 185
 	public function remaining( $DTT_ID = 0 ) {
186 186
 		return $this->real_quantity_on_ticket('saleable', $DTT_ID );
187 187
 	}
188 188
 
189 189
 
190 190
 
191
-    /**
192
-     * Gets min
193
-     *
194
-     * @return int
195
-     * @throws \EE_Error
196
-     */
191
+	/**
192
+	 * Gets min
193
+	 *
194
+	 * @return int
195
+	 * @throws \EE_Error
196
+	 */
197 197
 	public function min() {
198 198
 		return $this->get( 'TKT_min' );
199 199
 	}
200 200
 
201 201
 
202 202
 
203
-    /**
204
-     * return if a ticket is no longer available cause its available dates have expired.
205
-     *
206
-     * @return boolean
207
-     * @throws \EE_Error
208
-     */
203
+	/**
204
+	 * return if a ticket is no longer available cause its available dates have expired.
205
+	 *
206
+	 * @return boolean
207
+	 * @throws \EE_Error
208
+	 */
209 209
 	public function is_expired() {
210 210
 		return ( $this->get_raw( 'TKT_end_date' ) < time() );
211 211
 	}
212 212
 
213 213
 
214 214
 
215
-    /**
216
-     * Return if a ticket is yet to go on sale or not
217
-     *
218
-     * @return boolean
219
-     * @throws \EE_Error
220
-     */
215
+	/**
216
+	 * Return if a ticket is yet to go on sale or not
217
+	 *
218
+	 * @return boolean
219
+	 * @throws \EE_Error
220
+	 */
221 221
 	public function is_pending() {
222 222
 		return ( $this->get_raw( 'TKT_start_date' ) > time() );
223 223
 	}
224 224
 
225 225
 
226 226
 
227
-    /**
228
-     * Return if a ticket is on sale or not
229
-     *
230
-     * @return boolean
231
-     * @throws \EE_Error
232
-     */
227
+	/**
228
+	 * Return if a ticket is on sale or not
229
+	 *
230
+	 * @return boolean
231
+	 * @throws \EE_Error
232
+	 */
233 233
 	public function is_on_sale() {
234 234
 		return ( $this->get_raw( 'TKT_start_date' ) < time() && $this->get_raw( 'TKT_end_date' ) > time() );
235 235
 	}
236 236
 
237 237
 
238 238
 
239
-    /**
240
-     * This returns the chronologically last datetime that this ticket is associated with
241
-     *
242
-     * @param string $dt_frmt
243
-     * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with the end date ie: Jan 01 "to" Dec 31
244
-     * @return string
245
-     * @throws \EE_Error
246
-     */
239
+	/**
240
+	 * This returns the chronologically last datetime that this ticket is associated with
241
+	 *
242
+	 * @param string $dt_frmt
243
+	 * @param string $conjunction - conjunction junction what's your function ? this string joins the start date with the end date ie: Jan 01 "to" Dec 31
244
+	 * @return string
245
+	 * @throws \EE_Error
246
+	 */
247 247
 	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
248 248
 		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date( $dt_frmt ) : '';
249 249
 		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date( $dt_frmt ) : '';
@@ -253,12 +253,12 @@  discard block
 block discarded – undo
253 253
 
254 254
 
255 255
 
256
-    /**
257
-     * This returns the chronologically first datetime that this ticket is associated with
258
-     *
259
-     * @return EE_Datetime
260
-     * @throws \EE_Error
261
-     */
256
+	/**
257
+	 * This returns the chronologically first datetime that this ticket is associated with
258
+	 *
259
+	 * @return EE_Datetime
260
+	 * @throws \EE_Error
261
+	 */
262 262
 	public function first_datetime() {
263 263
 		$datetimes = $this->datetimes( array( 'limit' => 1 ) );
264 264
 		return reset( $datetimes );
@@ -266,14 +266,14 @@  discard block
 block discarded – undo
266 266
 
267 267
 
268 268
 
269
-    /**
270
-     * Gets all the datetimes this ticket can be used for attending.
271
-     * Unless otherwise specified, orders datetimes by start date.
272
-     *
273
-     * @param array $query_params see EEM_Base::get_all()
274
-     * @return EE_Datetime[]|EE_Base_Class[]
275
-     * @throws \EE_Error
276
-     */
269
+	/**
270
+	 * Gets all the datetimes this ticket can be used for attending.
271
+	 * Unless otherwise specified, orders datetimes by start date.
272
+	 *
273
+	 * @param array $query_params see EEM_Base::get_all()
274
+	 * @return EE_Datetime[]|EE_Base_Class[]
275
+	 * @throws \EE_Error
276
+	 */
277 277
 	public function datetimes( $query_params = array() ) {
278 278
 		if ( ! isset( $query_params[ 'order_by' ] ) ) {
279 279
 			$query_params[ 'order_by' ][ 'DTT_order' ] = 'ASC';
@@ -283,12 +283,12 @@  discard block
 block discarded – undo
283 283
 
284 284
 
285 285
 
286
-    /**
287
-     * This returns the chronologically last datetime that this ticket is associated with
288
-     *
289
-     * @return EE_Datetime
290
-     * @throws \EE_Error
291
-     */
286
+	/**
287
+	 * This returns the chronologically last datetime that this ticket is associated with
288
+	 *
289
+	 * @return EE_Datetime
290
+	 * @throws \EE_Error
291
+	 */
292 292
 	public function last_datetime() {
293 293
 		$datetimes = $this->datetimes( array( 'limit' => 1, 'order_by' => array( 'DTT_EVT_start' => 'DESC' ) ) );
294 294
 		return end( $datetimes );
@@ -296,19 +296,19 @@  discard block
 block discarded – undo
296 296
 
297 297
 
298 298
 
299
-    /**
300
-     * This returns the total tickets sold depending on the given parameters.
301
-     *
302
-     * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
303
-     *                        'ticket' = total ticket sales for all datetimes this ticket is related to
304
-     *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
305
-     *                        'datetime' = total ticket sales in the datetime_ticket table.
306
-     *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
307
-     *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
308
-     * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
309
-     * @return mixed (array|int)          how many tickets have sold
310
-     * @throws \EE_Error
311
-     */
299
+	/**
300
+	 * This returns the total tickets sold depending on the given parameters.
301
+	 *
302
+	 * @param  string $what   Can be one of two options: 'ticket', 'datetime'.
303
+	 *                        'ticket' = total ticket sales for all datetimes this ticket is related to
304
+	 *                        'datetime' = total ticket sales for a specified datetime (required $dtt_id)
305
+	 *                        'datetime' = total ticket sales in the datetime_ticket table.
306
+	 *                        If $dtt_id is not given then we return an array of sales indexed by datetime.
307
+	 *                        If $dtt_id IS given then we return the tickets sold for that given datetime.
308
+	 * @param  int    $dtt_id [optional] include the dtt_id with $what = 'datetime'.
309
+	 * @return mixed (array|int)          how many tickets have sold
310
+	 * @throws \EE_Error
311
+	 */
312 312
 	public function tickets_sold( $what = 'ticket', $dtt_id = NULL ) {
313 313
 		$total = 0;
314 314
 		$tickets_sold = $this->_all_tickets_sold();
@@ -333,12 +333,12 @@  discard block
 block discarded – undo
333 333
 
334 334
 
335 335
 
336
-    /**
337
-     * This returns an array indexed by datetime_id for tickets sold with this ticket.
338
-     *
339
-     * @return EE_Ticket[]
340
-     * @throws \EE_Error
341
-     */
336
+	/**
337
+	 * This returns an array indexed by datetime_id for tickets sold with this ticket.
338
+	 *
339
+	 * @return EE_Ticket[]
340
+	 * @throws \EE_Error
341
+	 */
342 342
 	protected function _all_tickets_sold() {
343 343
 		$datetimes = $this->get_many_related( 'Datetime' );
344 344
 		$tickets_sold = array();
@@ -354,29 +354,29 @@  discard block
 block discarded – undo
354 354
 
355 355
 
356 356
 
357
-    /**
358
-     * This returns the base price object for the ticket.
359
-     *
360
-     * @param  bool $return_array whether to return as an array indexed by price id or just the object.
361
-     * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362
-     * @throws \EE_Error
363
-     */
357
+	/**
358
+	 * This returns the base price object for the ticket.
359
+	 *
360
+	 * @param  bool $return_array whether to return as an array indexed by price id or just the object.
361
+	 * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362
+	 * @throws \EE_Error
363
+	 */
364 364
 	public function base_price( $return_array = FALSE ) {
365 365
 		$_where = array( 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price );
366 366
 		return $return_array
367
-            ? $this->get_many_related( 'Price', array( $_where ) )
368
-            : $this->get_first_related( 'Price', array( $_where ) );
367
+			? $this->get_many_related( 'Price', array( $_where ) )
368
+			: $this->get_first_related( 'Price', array( $_where ) );
369 369
 	}
370 370
 
371 371
 
372 372
 
373
-    /**
374
-     * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
375
-     *
376
-     * @access public
377
-     * @return EE_Price[]
378
-     * @throws \EE_Error
379
-     */
373
+	/**
374
+	 * This returns ONLY the price modifiers for the ticket (i.e. no taxes or base price)
375
+	 *
376
+	 * @access public
377
+	 * @return EE_Price[]
378
+	 * @throws \EE_Error
379
+	 */
380 380
 	public function price_modifiers() {
381 381
 		$query_params = array( 0 => array( 'Price_Type.PBT_ID' => array( 'NOT IN', array( EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax ) ) ) );
382 382
 		return $this->prices( $query_params );
@@ -384,132 +384,132 @@  discard block
 block discarded – undo
384 384
 
385 385
 
386 386
 
387
-    /**
388
-     * Gets all the prices that combine to form the final price of this ticket
389
-     *
390
-     * @param array $query_params like EEM_Base::get_all
391
-     * @return EE_Price[]|EE_Base_Class[]
392
-     * @throws \EE_Error
393
-     */
387
+	/**
388
+	 * Gets all the prices that combine to form the final price of this ticket
389
+	 *
390
+	 * @param array $query_params like EEM_Base::get_all
391
+	 * @return EE_Price[]|EE_Base_Class[]
392
+	 * @throws \EE_Error
393
+	 */
394 394
 	public function prices( $query_params = array() ) {
395 395
 		return $this->get_many_related( 'Price', $query_params );
396 396
 	}
397 397
 
398 398
 
399 399
 
400
-    /**
401
-     * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
402
-     *
403
-     * @param array $query_params see EEM_Base::get_all()
404
-     * @return EE_Datetime_Ticket|EE_Base_Class[]
405
-     * @throws \EE_Error
406
-     */
400
+	/**
401
+	 * Gets all the ticket applicabilities (ie, relations between datetimes and tickets)
402
+	 *
403
+	 * @param array $query_params see EEM_Base::get_all()
404
+	 * @return EE_Datetime_Ticket|EE_Base_Class[]
405
+	 * @throws \EE_Error
406
+	 */
407 407
 	public function datetime_tickets( $query_params = array() ) {
408 408
 		return $this->get_many_related( 'Datetime_Ticket', $query_params );
409 409
 	}
410 410
 
411 411
 
412 412
 
413
-    /**
414
-     * Gets all the datetimes from the db ordered by DTT_order
415
-     *
416
-     * @param boolean $show_expired
417
-     * @param boolean $show_deleted
418
-     * @return EE_Datetime[]
419
-     * @throws \EE_Error
420
-     */
413
+	/**
414
+	 * Gets all the datetimes from the db ordered by DTT_order
415
+	 *
416
+	 * @param boolean $show_expired
417
+	 * @param boolean $show_deleted
418
+	 * @return EE_Datetime[]
419
+	 * @throws \EE_Error
420
+	 */
421 421
 	public function datetimes_ordered( $show_expired = TRUE, $show_deleted = FALSE ) {
422 422
 		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_ticket_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted );
423 423
 	}
424 424
 
425 425
 
426 426
 
427
-    /**
428
-     * Gets ID
429
-     *
430
-     * @return string
431
-     * @throws \EE_Error
432
-     */
427
+	/**
428
+	 * Gets ID
429
+	 *
430
+	 * @return string
431
+	 * @throws \EE_Error
432
+	 */
433 433
 	public function ID() {
434 434
 		return $this->get( 'TKT_ID' );
435 435
 	}
436 436
 
437 437
 
438 438
 
439
-    /**
440
-     * get the author of the ticket.
441
-     *
442
-     * @since 4.5.0
443
-     * @return int
444
-     * @throws \EE_Error
445
-     */
439
+	/**
440
+	 * get the author of the ticket.
441
+	 *
442
+	 * @since 4.5.0
443
+	 * @return int
444
+	 * @throws \EE_Error
445
+	 */
446 446
 	public function wp_user() {
447 447
 		return $this->get('TKT_wp_user');
448 448
 	}
449 449
 
450 450
 
451 451
 
452
-    /**
453
-     * Gets the template for the ticket
454
-     *
455
-     * @return EE_Ticket_Template|EE_Base_Class
456
-     * @throws \EE_Error
457
-     */
452
+	/**
453
+	 * Gets the template for the ticket
454
+	 *
455
+	 * @return EE_Ticket_Template|EE_Base_Class
456
+	 * @throws \EE_Error
457
+	 */
458 458
 	public function template() {
459 459
 		return $this->get_first_related( 'Ticket_Template' );
460 460
 	}
461 461
 
462 462
 
463 463
 
464
-    /**
465
-     * Simply returns an array of EE_Price objects that are taxes.
466
-     *
467
-     * @return EE_Price[]
468
-     * @throws \EE_Error
469
-     */
464
+	/**
465
+	 * Simply returns an array of EE_Price objects that are taxes.
466
+	 *
467
+	 * @return EE_Price[]
468
+	 * @throws \EE_Error
469
+	 */
470 470
 	public function get_ticket_taxes_for_admin() {
471 471
 		return EE_Taxes::get_taxes_for_admin();
472 472
 	}
473 473
 
474 474
 
475 475
 
476
-    /**
477
-     * @return float
478
-     * @throws \EE_Error
479
-     */
476
+	/**
477
+	 * @return float
478
+	 * @throws \EE_Error
479
+	 */
480 480
 	public function ticket_price() {
481 481
 		return $this->get( 'TKT_price' );
482 482
 	}
483 483
 
484 484
 
485 485
 
486
-    /**
487
-     * @return mixed
488
-     * @throws \EE_Error
489
-     */
486
+	/**
487
+	 * @return mixed
488
+	 * @throws \EE_Error
489
+	 */
490 490
 	public function pretty_price() {
491 491
 		return $this->get_pretty( 'TKT_price' );
492 492
 	}
493 493
 
494 494
 
495 495
 
496
-    /**
497
-     * @return bool
498
-     * @throws \EE_Error
499
-     */
496
+	/**
497
+	 * @return bool
498
+	 * @throws \EE_Error
499
+	 */
500 500
 	public function is_free() {
501 501
 		return $this->get_ticket_total_with_taxes() === (float) 0;
502 502
 	}
503 503
 
504 504
 
505 505
 
506
-    /**
507
-     * get_ticket_total_with_taxes
508
-     *
509
-     * @param bool $no_cache
510
-     * @return float
511
-     * @throws \EE_Error
512
-     */
506
+	/**
507
+	 * get_ticket_total_with_taxes
508
+	 *
509
+	 * @param bool $no_cache
510
+	 * @return float
511
+	 * @throws \EE_Error
512
+	 */
513 513
 	public function get_ticket_total_with_taxes( $no_cache = FALSE ) {
514 514
 		if ($this->_ticket_total_with_taxes === null || $no_cache ) {
515 515
 			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
@@ -526,201 +526,201 @@  discard block
 block discarded – undo
526 526
 
527 527
 
528 528
 
529
-    /**
530
-     * @return float
531
-     * @throws \EE_Error
532
-     */
529
+	/**
530
+	 * @return float
531
+	 * @throws \EE_Error
532
+	 */
533 533
 	public function get_ticket_subtotal() {
534 534
 		return EE_Taxes::get_subtotal_for_admin( $this );
535 535
 	}
536 536
 
537 537
 
538 538
 
539
-    /**
540
-     * Returns the total taxes applied to this ticket
541
-     *
542
-     * @return float
543
-     * @throws \EE_Error
544
-     */
539
+	/**
540
+	 * Returns the total taxes applied to this ticket
541
+	 *
542
+	 * @return float
543
+	 * @throws \EE_Error
544
+	 */
545 545
 	public function get_ticket_taxes_total_for_admin() {
546 546
 		return EE_Taxes::get_total_taxes_for_admin( $this );
547 547
 	}
548 548
 
549 549
 
550 550
 
551
-    /**
552
-     * Sets name
553
-     *
554
-     * @param string $name
555
-     * @throws \EE_Error
556
-     */
551
+	/**
552
+	 * Sets name
553
+	 *
554
+	 * @param string $name
555
+	 * @throws \EE_Error
556
+	 */
557 557
 	public function set_name( $name ) {
558 558
 		$this->set( 'TKT_name', $name );
559 559
 	}
560 560
 
561 561
 
562 562
 
563
-    /**
564
-     * Gets description
565
-     *
566
-     * @return string
567
-     * @throws \EE_Error
568
-     */
563
+	/**
564
+	 * Gets description
565
+	 *
566
+	 * @return string
567
+	 * @throws \EE_Error
568
+	 */
569 569
 	public function description() {
570 570
 		return $this->get( 'TKT_description' );
571 571
 	}
572 572
 
573 573
 
574 574
 
575
-    /**
576
-     * Sets description
577
-     *
578
-     * @param string $description
579
-     * @throws \EE_Error
580
-     */
575
+	/**
576
+	 * Sets description
577
+	 *
578
+	 * @param string $description
579
+	 * @throws \EE_Error
580
+	 */
581 581
 	public function set_description( $description ) {
582 582
 		$this->set( 'TKT_description', $description );
583 583
 	}
584 584
 
585 585
 
586 586
 
587
-    /**
588
-     * Gets start_date
589
-     *
590
-     * @param string $dt_frmt
591
-     * @param string $tm_frmt
592
-     * @return string
593
-     * @throws \EE_Error
594
-     */
587
+	/**
588
+	 * Gets start_date
589
+	 *
590
+	 * @param string $dt_frmt
591
+	 * @param string $tm_frmt
592
+	 * @return string
593
+	 * @throws \EE_Error
594
+	 */
595 595
 	public function start_date( $dt_frmt = '', $tm_frmt = '' ) {
596 596
 		return $this->_get_datetime( 'TKT_start_date', $dt_frmt, $tm_frmt );
597 597
 	}
598 598
 
599 599
 
600 600
 
601
-    /**
602
-     * Sets start_date
603
-     *
604
-     * @param string $start_date
605
-     * @return void
606
-     * @throws \EE_Error
607
-     */
601
+	/**
602
+	 * Sets start_date
603
+	 *
604
+	 * @param string $start_date
605
+	 * @return void
606
+	 * @throws \EE_Error
607
+	 */
608 608
 	public function set_start_date( $start_date ) {
609 609
 		$this->_set_date_time( 'B', $start_date, 'TKT_start_date' );
610 610
 	}
611 611
 
612 612
 
613 613
 
614
-    /**
615
-     * Gets end_date
616
-     *
617
-     * @param string $dt_frmt
618
-     * @param string $tm_frmt
619
-     * @return string
620
-     * @throws \EE_Error
621
-     */
614
+	/**
615
+	 * Gets end_date
616
+	 *
617
+	 * @param string $dt_frmt
618
+	 * @param string $tm_frmt
619
+	 * @return string
620
+	 * @throws \EE_Error
621
+	 */
622 622
 	public function end_date( $dt_frmt = '', $tm_frmt = '' ) {
623 623
 		return $this->_get_datetime( 'TKT_end_date', $dt_frmt, $tm_frmt );
624 624
 	}
625 625
 
626 626
 
627 627
 
628
-    /**
629
-     * Sets end_date
630
-     *
631
-     * @param string $end_date
632
-     * @return void
633
-     * @throws \EE_Error
634
-     */
628
+	/**
629
+	 * Sets end_date
630
+	 *
631
+	 * @param string $end_date
632
+	 * @return void
633
+	 * @throws \EE_Error
634
+	 */
635 635
 	public function set_end_date( $end_date ) {
636 636
 		$this->_set_date_time( 'B', $end_date, 'TKT_end_date' );
637 637
 	}
638 638
 
639 639
 
640 640
 
641
-    /**
642
-     * Sets sell until time
643
-     *
644
-     * @since 4.5.0
645
-     * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646
-     * @throws \EE_Error
647
-     */
641
+	/**
642
+	 * Sets sell until time
643
+	 *
644
+	 * @since 4.5.0
645
+	 * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646
+	 * @throws \EE_Error
647
+	 */
648 648
 	public function set_end_time( $time ) {
649 649
 		$this->_set_time_for( $time, 'TKT_end_date' );
650 650
 	}
651 651
 
652 652
 
653 653
 
654
-    /**
655
-     * Sets min
656
-     *
657
-     * @param int $min
658
-     * @return void
659
-     * @throws \EE_Error
660
-     */
654
+	/**
655
+	 * Sets min
656
+	 *
657
+	 * @param int $min
658
+	 * @return void
659
+	 * @throws \EE_Error
660
+	 */
661 661
 	public function set_min( $min ) {
662 662
 		$this->set( 'TKT_min', $min );
663 663
 	}
664 664
 
665 665
 
666 666
 
667
-    /**
668
-     * Gets max
669
-     *
670
-     * @return int
671
-     * @throws \EE_Error
672
-     */
667
+	/**
668
+	 * Gets max
669
+	 *
670
+	 * @return int
671
+	 * @throws \EE_Error
672
+	 */
673 673
 	public function max() {
674 674
 		return $this->get( 'TKT_max' );
675 675
 	}
676 676
 
677 677
 
678 678
 
679
-    /**
680
-     * Sets max
681
-     *
682
-     * @param int $max
683
-     * @return void
684
-     * @throws \EE_Error
685
-     */
679
+	/**
680
+	 * Sets max
681
+	 *
682
+	 * @param int $max
683
+	 * @return void
684
+	 * @throws \EE_Error
685
+	 */
686 686
 	public function set_max( $max ) {
687 687
 		$this->set( 'TKT_max', $max );
688 688
 	}
689 689
 
690 690
 
691 691
 
692
-    /**
693
-     * Sets price
694
-     *
695
-     * @param float $price
696
-     * @return void
697
-     * @throws \EE_Error
698
-     */
692
+	/**
693
+	 * Sets price
694
+	 *
695
+	 * @param float $price
696
+	 * @return void
697
+	 * @throws \EE_Error
698
+	 */
699 699
 	public function set_price( $price ) {
700 700
 		$this->set( 'TKT_price', $price );
701 701
 	}
702 702
 
703 703
 
704 704
 
705
-    /**
706
-     * Gets sold
707
-     *
708
-     * @return int
709
-     * @throws \EE_Error
710
-     */
705
+	/**
706
+	 * Gets sold
707
+	 *
708
+	 * @return int
709
+	 * @throws \EE_Error
710
+	 */
711 711
 	public function sold() {
712 712
 		return $this->get_raw( 'TKT_sold' );
713 713
 	}
714 714
 
715 715
 
716 716
 
717
-    /**
718
-     * Sets sold
719
-     *
720
-     * @param int $sold
721
-     * @return void
722
-     * @throws \EE_Error
723
-     */
717
+	/**
718
+	 * Sets sold
719
+	 *
720
+	 * @param int $sold
721
+	 * @return void
722
+	 * @throws \EE_Error
723
+	 */
724 724
 	public function set_sold( $sold ) {
725 725
 		// sold can not go below zero
726 726
 		$sold = max( 0, $sold );
@@ -729,13 +729,13 @@  discard block
 block discarded – undo
729 729
 
730 730
 
731 731
 
732
-    /**
733
-     * increments sold by amount passed by $qty
734
-     *
735
-     * @param int $qty
736
-     * @return void
737
-     * @throws \EE_Error
738
-     */
732
+	/**
733
+	 * increments sold by amount passed by $qty
734
+	 *
735
+	 * @param int $qty
736
+	 * @return void
737
+	 * @throws \EE_Error
738
+	 */
739 739
 	public function increase_sold( $qty = 1 ) {
740 740
 		$sold = $this->sold() + $qty;
741 741
 		// remove ticket reservation, but don't adjust datetime reservations,  because that will happen
@@ -744,22 +744,22 @@  discard block
 block discarded – undo
744 744
 		$this->_increase_sold_for_datetimes( $qty );
745 745
 		$this->set_sold( $sold );
746 746
 		do_action(
747
-		    'AHEE__EE_Ticket__increase_sold',
748
-            $this,
749
-            $qty,
750
-            $sold
751
-        );
747
+			'AHEE__EE_Ticket__increase_sold',
748
+			$this,
749
+			$qty,
750
+			$sold
751
+		);
752 752
 	}
753 753
 
754 754
 
755 755
 
756
-    /**
757
-     * Increases sold on related datetimes
758
-     *
759
-     * @param int $qty
760
-     * @return void
761
-     * @throws \EE_Error
762
-     */
756
+	/**
757
+	 * Increases sold on related datetimes
758
+	 *
759
+	 * @param int $qty
760
+	 * @return void
761
+	 * @throws \EE_Error
762
+	 */
763 763
 	protected function _increase_sold_for_datetimes( $qty = 1 ) {
764 764
 		$datetimes = $this->datetimes();
765 765
 		if ( is_array( $datetimes ) ) {
@@ -774,34 +774,34 @@  discard block
 block discarded – undo
774 774
 
775 775
 
776 776
 
777
-    /**
778
-     * decrements (subtracts) sold by amount passed by $qty
779
-     *
780
-     * @param int $qty
781
-     * @return void
782
-     * @throws \EE_Error
783
-     */
777
+	/**
778
+	 * decrements (subtracts) sold by amount passed by $qty
779
+	 *
780
+	 * @param int $qty
781
+	 * @return void
782
+	 * @throws \EE_Error
783
+	 */
784 784
 	public function decrease_sold( $qty = 1 ) {
785 785
 		$sold = $this->sold() - $qty;
786 786
 		$this->_decrease_sold_for_datetimes( $qty );
787 787
 		$this->set_sold( $sold );
788
-        do_action(
789
-            'AHEE__EE_Ticket__decrease_sold',
790
-            $this,
791
-            $qty,
792
-            $sold
793
-        );
794
-    }
795
-
796
-
797
-
798
-    /**
799
-     * Decreases sold on related datetimes
800
-     *
801
-     * @param int $qty
802
-     * @return void
803
-     * @throws \EE_Error
804
-     */
788
+		do_action(
789
+			'AHEE__EE_Ticket__decrease_sold',
790
+			$this,
791
+			$qty,
792
+			$sold
793
+		);
794
+	}
795
+
796
+
797
+
798
+	/**
799
+	 * Decreases sold on related datetimes
800
+	 *
801
+	 * @param int $qty
802
+	 * @return void
803
+	 * @throws \EE_Error
804
+	 */
805 805
 	protected function _decrease_sold_for_datetimes( $qty = 1 ) {
806 806
 		$datetimes = $this->datetimes();
807 807
 		if ( is_array( $datetimes ) ) {
@@ -816,25 +816,25 @@  discard block
 block discarded – undo
816 816
 
817 817
 
818 818
 
819
-    /**
820
-     * Gets qty of reserved tickets
821
-     *
822
-     * @return int
823
-     * @throws \EE_Error
824
-     */
819
+	/**
820
+	 * Gets qty of reserved tickets
821
+	 *
822
+	 * @return int
823
+	 * @throws \EE_Error
824
+	 */
825 825
 	public function reserved() {
826 826
 		return $this->get_raw( 'TKT_reserved' );
827 827
 	}
828 828
 
829 829
 
830 830
 
831
-    /**
832
-     * Sets reserved
833
-     *
834
-     * @param int $reserved
835
-     * @return void
836
-     * @throws \EE_Error
837
-     */
831
+	/**
832
+	 * Sets reserved
833
+	 *
834
+	 * @param int $reserved
835
+	 * @return void
836
+	 * @throws \EE_Error
837
+	 */
838 838
 	public function set_reserved( $reserved ) {
839 839
 		// reserved can not go below zero
840 840
 		$reserved = max( 0, (int) $reserved );
@@ -843,35 +843,35 @@  discard block
 block discarded – undo
843 843
 
844 844
 
845 845
 
846
-    /**
847
-     * increments reserved by amount passed by $qty
848
-     *
849
-     * @param int $qty
850
-     * @return void
851
-     * @throws \EE_Error
852
-     */
846
+	/**
847
+	 * increments reserved by amount passed by $qty
848
+	 *
849
+	 * @param int $qty
850
+	 * @return void
851
+	 * @throws \EE_Error
852
+	 */
853 853
 	public function increase_reserved( $qty = 1 ) {
854 854
 		$qty = absint( $qty );
855 855
 		$reserved = $this->reserved() + $qty;
856 856
 		$this->_increase_reserved_for_datetimes( $qty );
857 857
 		$this->set_reserved( $reserved );
858
-        do_action(
859
-            'AHEE__EE_Ticket__increase_reserved',
860
-            $this,
861
-            $qty,
862
-            $reserved
863
-        );
864
-    }
865
-
866
-
867
-
868
-    /**
869
-     * Increases sold on related datetimes
870
-     *
871
-     * @param int $qty
872
-     * @return void
873
-     * @throws \EE_Error
874
-     */
858
+		do_action(
859
+			'AHEE__EE_Ticket__increase_reserved',
860
+			$this,
861
+			$qty,
862
+			$reserved
863
+		);
864
+	}
865
+
866
+
867
+
868
+	/**
869
+	 * Increases sold on related datetimes
870
+	 *
871
+	 * @param int $qty
872
+	 * @return void
873
+	 * @throws \EE_Error
874
+	 */
875 875
 	protected function _increase_reserved_for_datetimes( $qty = 1 ) {
876 876
 		$datetimes = $this->datetimes();
877 877
 		if ( is_array( $datetimes ) ) {
@@ -886,37 +886,37 @@  discard block
 block discarded – undo
886 886
 
887 887
 
888 888
 
889
-    /**
890
-     * decrements (subtracts) reserved by amount passed by $qty
891
-     *
892
-     * @param int  $qty
893
-     * @param bool $adjust_datetimes
894
-     * @return void
895
-     * @throws \EE_Error
896
-     */
889
+	/**
890
+	 * decrements (subtracts) reserved by amount passed by $qty
891
+	 *
892
+	 * @param int  $qty
893
+	 * @param bool $adjust_datetimes
894
+	 * @return void
895
+	 * @throws \EE_Error
896
+	 */
897 897
 	public function decrease_reserved( $qty = 1, $adjust_datetimes = true ) {
898 898
 		$reserved = $this->reserved() - absint( $qty );
899 899
 		if ( $adjust_datetimes ) {
900 900
 			$this->_decrease_reserved_for_datetimes( $qty );
901 901
 		}
902 902
 		$this->set_reserved( $reserved );
903
-        do_action(
904
-            'AHEE__EE_Ticket__decrease_reserved',
905
-            $this,
906
-            $qty,
907
-            $reserved
908
-        );
909
-    }
910
-
911
-
912
-
913
-    /**
914
-     * Increases sold on related datetimes
915
-     *
916
-     * @param int $qty
917
-     * @return void
918
-     * @throws \EE_Error
919
-     */
903
+		do_action(
904
+			'AHEE__EE_Ticket__decrease_reserved',
905
+			$this,
906
+			$qty,
907
+			$reserved
908
+		);
909
+	}
910
+
911
+
912
+
913
+	/**
914
+	 * Increases sold on related datetimes
915
+	 *
916
+	 * @param int $qty
917
+	 * @return void
918
+	 * @throws \EE_Error
919
+	 */
920 920
 	protected function _decrease_reserved_for_datetimes( $qty = 1 ) {
921 921
 		$datetimes = $this->datetimes();
922 922
 		if ( is_array( $datetimes ) ) {
@@ -931,18 +931,18 @@  discard block
 block discarded – undo
931 931
 
932 932
 
933 933
 
934
-    /**
935
-     * Gets ticket quantity
936
-     *
937
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
938
-     *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
939
-     *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
940
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
941
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
942
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
943
-     * @return int
944
-     * @throws \EE_Error
945
-     */
934
+	/**
935
+	 * Gets ticket quantity
936
+	 *
937
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
938
+	 *                            therefore $context can be one of three values: '', 'reg_limit', or 'saleable'
939
+	 *                            '' (default) quantity is the actual db value for TKT_qty, unaffected by other objects
940
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
941
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
942
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
943
+	 * @return int
944
+	 * @throws \EE_Error
945
+	 */
946 946
 	public function qty( $context = '' ) {
947 947
 		switch ( $context ) {
948 948
 			case 'reg_limit' :
@@ -956,19 +956,19 @@  discard block
 block discarded – undo
956 956
 
957 957
 
958 958
 
959
-    /**
960
-     * Gets ticket quantity
961
-     *
962
-     * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
963
-     *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
964
-     *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
965
-     *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
966
-     *                            is therefore the truest measure of tickets that can be purchased at the moment
967
-     * @param  int   $DTT_ID      the primary key for a particular datetime.
968
-     *                            set to 0 for all related datetimes
969
-     * @return int
970
-     * @throws \EE_Error
971
-     */
959
+	/**
960
+	 * Gets ticket quantity
961
+	 *
962
+	 * @param string $context     ticket quantity is somewhat subjective depending on the exact information sought
963
+	 *                            therefore $context can be one of two values: 'reg_limit', or 'saleable'
964
+	 *                            REG LIMIT: caps qty based on DTT_reg_limit for ALL related datetimes
965
+	 *                            SALEABLE: also considers datetime sold and returns zero if ANY DTT is sold out, and
966
+	 *                            is therefore the truest measure of tickets that can be purchased at the moment
967
+	 * @param  int   $DTT_ID      the primary key for a particular datetime.
968
+	 *                            set to 0 for all related datetimes
969
+	 * @return int
970
+	 * @throws \EE_Error
971
+	 */
972 972
 	public function real_quantity_on_ticket( $context = 'reg_limit', $DTT_ID = 0 ) {
973 973
 		$raw = $this->get_raw( 'TKT_qty' );
974 974
 		// return immediately if it's zero
@@ -1051,212 +1051,212 @@  discard block
 block discarded – undo
1051 1051
 
1052 1052
 
1053 1053
 
1054
-    /**
1055
-     * Gets uses
1056
-     *
1057
-     * @return int
1058
-     * @throws \EE_Error
1059
-     */
1054
+	/**
1055
+	 * Gets uses
1056
+	 *
1057
+	 * @return int
1058
+	 * @throws \EE_Error
1059
+	 */
1060 1060
 	public function uses() {
1061 1061
 		return $this->get( 'TKT_uses' );
1062 1062
 	}
1063 1063
 
1064 1064
 
1065 1065
 
1066
-    /**
1067
-     * Sets uses
1068
-     *
1069
-     * @param int $uses
1070
-     * @return void
1071
-     * @throws \EE_Error
1072
-     */
1066
+	/**
1067
+	 * Sets uses
1068
+	 *
1069
+	 * @param int $uses
1070
+	 * @return void
1071
+	 * @throws \EE_Error
1072
+	 */
1073 1073
 	public function set_uses( $uses ) {
1074 1074
 		$this->set( 'TKT_uses', $uses );
1075 1075
 	}
1076 1076
 
1077 1077
 
1078 1078
 
1079
-    /**
1080
-     * returns whether ticket is required or not.
1081
-     *
1082
-     * @return boolean
1083
-     * @throws \EE_Error
1084
-     */
1079
+	/**
1080
+	 * returns whether ticket is required or not.
1081
+	 *
1082
+	 * @return boolean
1083
+	 * @throws \EE_Error
1084
+	 */
1085 1085
 	public function required() {
1086 1086
 		return $this->get( 'TKT_required' );
1087 1087
 	}
1088 1088
 
1089 1089
 
1090 1090
 
1091
-    /**
1092
-     * sets the TKT_required property
1093
-     *
1094
-     * @param boolean $required
1095
-     * @return void
1096
-     * @throws \EE_Error
1097
-     */
1091
+	/**
1092
+	 * sets the TKT_required property
1093
+	 *
1094
+	 * @param boolean $required
1095
+	 * @return void
1096
+	 * @throws \EE_Error
1097
+	 */
1098 1098
 	public function set_required( $required ) {
1099 1099
 		$this->set( 'TKT_required', $required );
1100 1100
 	}
1101 1101
 
1102 1102
 
1103 1103
 
1104
-    /**
1105
-     * Gets taxable
1106
-     *
1107
-     * @return boolean
1108
-     * @throws \EE_Error
1109
-     */
1104
+	/**
1105
+	 * Gets taxable
1106
+	 *
1107
+	 * @return boolean
1108
+	 * @throws \EE_Error
1109
+	 */
1110 1110
 	public function taxable() {
1111 1111
 		return $this->get( 'TKT_taxable' );
1112 1112
 	}
1113 1113
 
1114 1114
 
1115 1115
 
1116
-    /**
1117
-     * Sets taxable
1118
-     *
1119
-     * @param boolean $taxable
1120
-     * @return void
1121
-     * @throws \EE_Error
1122
-     */
1116
+	/**
1117
+	 * Sets taxable
1118
+	 *
1119
+	 * @param boolean $taxable
1120
+	 * @return void
1121
+	 * @throws \EE_Error
1122
+	 */
1123 1123
 	public function set_taxable( $taxable ) {
1124 1124
 		$this->set( 'TKT_taxable', $taxable );
1125 1125
 	}
1126 1126
 
1127 1127
 
1128 1128
 
1129
-    /**
1130
-     * Gets is_default
1131
-     *
1132
-     * @return boolean
1133
-     * @throws \EE_Error
1134
-     */
1129
+	/**
1130
+	 * Gets is_default
1131
+	 *
1132
+	 * @return boolean
1133
+	 * @throws \EE_Error
1134
+	 */
1135 1135
 	public function is_default() {
1136 1136
 		return $this->get( 'TKT_is_default' );
1137 1137
 	}
1138 1138
 
1139 1139
 
1140 1140
 
1141
-    /**
1142
-     * Sets is_default
1143
-     *
1144
-     * @param boolean $is_default
1145
-     * @return void
1146
-     * @throws \EE_Error
1147
-     */
1141
+	/**
1142
+	 * Sets is_default
1143
+	 *
1144
+	 * @param boolean $is_default
1145
+	 * @return void
1146
+	 * @throws \EE_Error
1147
+	 */
1148 1148
 	public function set_is_default( $is_default ) {
1149 1149
 		$this->set( 'TKT_is_default', $is_default );
1150 1150
 	}
1151 1151
 
1152 1152
 
1153 1153
 
1154
-    /**
1155
-     * Gets order
1156
-     *
1157
-     * @return int
1158
-     * @throws \EE_Error
1159
-     */
1154
+	/**
1155
+	 * Gets order
1156
+	 *
1157
+	 * @return int
1158
+	 * @throws \EE_Error
1159
+	 */
1160 1160
 	public function order() {
1161 1161
 		return $this->get( 'TKT_order' );
1162 1162
 	}
1163 1163
 
1164 1164
 
1165 1165
 
1166
-    /**
1167
-     * Sets order
1168
-     *
1169
-     * @param int $order
1170
-     * @return void
1171
-     * @throws \EE_Error
1172
-     */
1166
+	/**
1167
+	 * Sets order
1168
+	 *
1169
+	 * @param int $order
1170
+	 * @return void
1171
+	 * @throws \EE_Error
1172
+	 */
1173 1173
 	public function set_order( $order ) {
1174 1174
 		$this->set( 'TKT_order', $order );
1175 1175
 	}
1176 1176
 
1177 1177
 
1178 1178
 
1179
-    /**
1180
-     * Gets row
1181
-     *
1182
-     * @return int
1183
-     * @throws \EE_Error
1184
-     */
1179
+	/**
1180
+	 * Gets row
1181
+	 *
1182
+	 * @return int
1183
+	 * @throws \EE_Error
1184
+	 */
1185 1185
 	public function row() {
1186 1186
 		return $this->get( 'TKT_row' );
1187 1187
 	}
1188 1188
 
1189 1189
 
1190 1190
 
1191
-    /**
1192
-     * Sets row
1193
-     *
1194
-     * @param int $row
1195
-     * @return void
1196
-     * @throws \EE_Error
1197
-     */
1191
+	/**
1192
+	 * Sets row
1193
+	 *
1194
+	 * @param int $row
1195
+	 * @return void
1196
+	 * @throws \EE_Error
1197
+	 */
1198 1198
 	public function set_row( $row ) {
1199 1199
 		$this->set( 'TKT_row', $row );
1200 1200
 	}
1201 1201
 
1202 1202
 
1203 1203
 
1204
-    /**
1205
-     * Gets deleted
1206
-     *
1207
-     * @return boolean
1208
-     * @throws \EE_Error
1209
-     */
1204
+	/**
1205
+	 * Gets deleted
1206
+	 *
1207
+	 * @return boolean
1208
+	 * @throws \EE_Error
1209
+	 */
1210 1210
 	public function deleted() {
1211 1211
 		return $this->get( 'TKT_deleted' );
1212 1212
 	}
1213 1213
 
1214 1214
 
1215 1215
 
1216
-    /**
1217
-     * Sets deleted
1218
-     *
1219
-     * @param boolean $deleted
1220
-     * @return void
1221
-     * @throws \EE_Error
1222
-     */
1216
+	/**
1217
+	 * Sets deleted
1218
+	 *
1219
+	 * @param boolean $deleted
1220
+	 * @return void
1221
+	 * @throws \EE_Error
1222
+	 */
1223 1223
 	public function set_deleted( $deleted ) {
1224 1224
 		$this->set( 'TKT_deleted', $deleted );
1225 1225
 	}
1226 1226
 
1227 1227
 
1228 1228
 
1229
-    /**
1230
-     * Gets parent
1231
-     *
1232
-     * @return int
1233
-     * @throws \EE_Error
1234
-     */
1229
+	/**
1230
+	 * Gets parent
1231
+	 *
1232
+	 * @return int
1233
+	 * @throws \EE_Error
1234
+	 */
1235 1235
 	public function parent_ID() {
1236 1236
 		return $this->get( 'TKT_parent' );
1237 1237
 	}
1238 1238
 
1239 1239
 
1240 1240
 
1241
-    /**
1242
-     * Sets parent
1243
-     *
1244
-     * @param int $parent
1245
-     * @return void
1246
-     * @throws \EE_Error
1247
-     */
1241
+	/**
1242
+	 * Sets parent
1243
+	 *
1244
+	 * @param int $parent
1245
+	 * @return void
1246
+	 * @throws \EE_Error
1247
+	 */
1248 1248
 	public function set_parent_ID( $parent ) {
1249 1249
 		$this->set( 'TKT_parent', $parent );
1250 1250
 	}
1251 1251
 
1252 1252
 
1253 1253
 
1254
-    /**
1255
-     * Gets a string which is handy for showing in gateways etc that describes the ticket.
1256
-     *
1257
-     * @return string
1258
-     * @throws \EE_Error
1259
-     */
1254
+	/**
1255
+	 * Gets a string which is handy for showing in gateways etc that describes the ticket.
1256
+	 *
1257
+	 * @return string
1258
+	 * @throws \EE_Error
1259
+	 */
1260 1260
 	public function name_and_info() {
1261 1261
 		$times = array();
1262 1262
 		foreach ( $this->datetimes() as $datetime ) {
@@ -1267,67 +1267,67 @@  discard block
 block discarded – undo
1267 1267
 
1268 1268
 
1269 1269
 
1270
-    /**
1271
-     * Gets name
1272
-     *
1273
-     * @return string
1274
-     * @throws \EE_Error
1275
-     */
1270
+	/**
1271
+	 * Gets name
1272
+	 *
1273
+	 * @return string
1274
+	 * @throws \EE_Error
1275
+	 */
1276 1276
 	public function name() {
1277 1277
 		return $this->get( 'TKT_name' );
1278 1278
 	}
1279 1279
 
1280 1280
 
1281 1281
 
1282
-    /**
1283
-     * Gets price
1284
-     *
1285
-     * @return float
1286
-     * @throws \EE_Error
1287
-     */
1282
+	/**
1283
+	 * Gets price
1284
+	 *
1285
+	 * @return float
1286
+	 * @throws \EE_Error
1287
+	 */
1288 1288
 	public function price() {
1289 1289
 		return $this->get( 'TKT_price' );
1290 1290
 	}
1291 1291
 
1292 1292
 
1293 1293
 
1294
-    /**
1295
-     * Gets all the registrations for this ticket
1296
-     *
1297
-     * @param array $query_params like EEM_Base::get_all's
1298
-     * @return EE_Registration[]|EE_Base_Class[]
1299
-     * @throws \EE_Error
1300
-     */
1294
+	/**
1295
+	 * Gets all the registrations for this ticket
1296
+	 *
1297
+	 * @param array $query_params like EEM_Base::get_all's
1298
+	 * @return EE_Registration[]|EE_Base_Class[]
1299
+	 * @throws \EE_Error
1300
+	 */
1301 1301
 	public function registrations( $query_params = array() ) {
1302 1302
 		return $this->get_many_related( 'Registration', $query_params );
1303 1303
 	}
1304 1304
 
1305 1305
 
1306 1306
 
1307
-    /**
1308
-     * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1309
-     * into account
1310
-     *
1311
-     * @return int
1312
-     * @throws \EE_Error
1313
-     */
1307
+	/**
1308
+	 * Updates the TKT_sold attribute (and saves) based on the number of APPROVED registrations for this ticket.
1309
+	 * into account
1310
+	 *
1311
+	 * @return int
1312
+	 * @throws \EE_Error
1313
+	 */
1314 1314
 	public function update_tickets_sold() {
1315
-        $count_regs_for_this_ticket = $this->count_registrations(
1316
-            array(
1317
-                array(
1318
-                    'STS_ID'      => EEM_Registration::status_id_approved,
1319
-                    'REG_deleted' => 0,
1320
-                ),
1321
-            )
1322
-        );
1323
-        $sold = $this->sold();
1324
-        if ($count_regs_for_this_ticket > $sold) {
1325
-            $this->increase_sold($count_regs_for_this_ticket - $sold);
1326
-            $this->save();
1327
-        } else if ($count_regs_for_this_ticket < $sold) {
1328
-            $this->decrease_sold($count_regs_for_this_ticket - $sold);
1329
-            $this->save();
1330
-        }
1315
+		$count_regs_for_this_ticket = $this->count_registrations(
1316
+			array(
1317
+				array(
1318
+					'STS_ID'      => EEM_Registration::status_id_approved,
1319
+					'REG_deleted' => 0,
1320
+				),
1321
+			)
1322
+		);
1323
+		$sold = $this->sold();
1324
+		if ($count_regs_for_this_ticket > $sold) {
1325
+			$this->increase_sold($count_regs_for_this_ticket - $sold);
1326
+			$this->save();
1327
+		} else if ($count_regs_for_this_ticket < $sold) {
1328
+			$this->decrease_sold($count_regs_for_this_ticket - $sold);
1329
+			$this->save();
1330
+		}
1331 1331
 		return $count_regs_for_this_ticket;
1332 1332
 	}
1333 1333
 
@@ -1355,21 +1355,21 @@  discard block
 block discarded – undo
1355 1355
 
1356 1356
 
1357 1357
 
1358
-    /**
1359
-     * Implementation of the EEI_Event_Relation interface method
1360
-     *
1361
-     * @see EEI_Event_Relation for comments
1362
-     * @return EE_Event
1363
-     * @throws \EE_Error
1364
-     * @throws UnexpectedEntityException
1365
-     */
1358
+	/**
1359
+	 * Implementation of the EEI_Event_Relation interface method
1360
+	 *
1361
+	 * @see EEI_Event_Relation for comments
1362
+	 * @return EE_Event
1363
+	 * @throws \EE_Error
1364
+	 * @throws UnexpectedEntityException
1365
+	 */
1366 1366
 	public function get_related_event() {
1367 1367
 		//get one datetime to use for getting the event
1368 1368
 		$datetime = $this->first_datetime();
1369 1369
 		if ( ! $datetime instanceof \EE_Datetime ) {
1370 1370
 			throw new UnexpectedEntityException(
1371 1371
 				$datetime,
1372
-                'EE_Datetime',
1372
+				'EE_Datetime',
1373 1373
 				sprintf(
1374 1374
 					__( 'The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1375 1375
 					$this->name()
@@ -1380,7 +1380,7 @@  discard block
 block discarded – undo
1380 1380
 		if ( ! $event instanceof \EE_Event ) {
1381 1381
 			throw new UnexpectedEntityException(
1382 1382
 				$event,
1383
-                'EE_Event',
1383
+				'EE_Event',
1384 1384
 				sprintf(
1385 1385
 					__( 'The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1386 1386
 					$this->name()
@@ -1392,14 +1392,14 @@  discard block
 block discarded – undo
1392 1392
 
1393 1393
 
1394 1394
 
1395
-    /**
1396
-     * Implementation of the EEI_Event_Relation interface method
1397
-     *
1398
-     * @see EEI_Event_Relation for comments
1399
-     * @return string
1400
-     * @throws UnexpectedEntityException
1401
-     * @throws \EE_Error
1402
-     */
1395
+	/**
1396
+	 * Implementation of the EEI_Event_Relation interface method
1397
+	 *
1398
+	 * @see EEI_Event_Relation for comments
1399
+	 * @return string
1400
+	 * @throws UnexpectedEntityException
1401
+	 * @throws \EE_Error
1402
+	 */
1403 1403
 	public function get_event_name() {
1404 1404
 		$event = $this->get_related_event();
1405 1405
 		return $event instanceof EE_Event ? $event->name() : '';
@@ -1407,28 +1407,28 @@  discard block
 block discarded – undo
1407 1407
 
1408 1408
 
1409 1409
 
1410
-    /**
1411
-     * Implementation of the EEI_Event_Relation interface method
1412
-     *
1413
-     * @see EEI_Event_Relation for comments
1414
-     * @return int
1415
-     * @throws UnexpectedEntityException
1416
-     * @throws \EE_Error
1417
-     */
1410
+	/**
1411
+	 * Implementation of the EEI_Event_Relation interface method
1412
+	 *
1413
+	 * @see EEI_Event_Relation for comments
1414
+	 * @return int
1415
+	 * @throws UnexpectedEntityException
1416
+	 * @throws \EE_Error
1417
+	 */
1418 1418
 	public function get_event_ID() {
1419 1419
 		$event = $this->get_related_event();
1420 1420
 		return $event instanceof EE_Event ? $event->ID() : 0;
1421 1421
 	}
1422 1422
 
1423 1423
 
1424
-    /**
1425
-     * This simply returns whether a ticket can be permanently deleted or not.
1426
-     * The criteria for determining this is whether the ticket has any related registrations.
1427
-     * If there are none then it can be permanently deleted.
1428
-     *
1429
-     * @return bool
1430
-     */
1424
+	/**
1425
+	 * This simply returns whether a ticket can be permanently deleted or not.
1426
+	 * The criteria for determining this is whether the ticket has any related registrations.
1427
+	 * If there are none then it can be permanently deleted.
1428
+	 *
1429
+	 * @return bool
1430
+	 */
1431 1431
 	public function is_permanently_deleteable() {
1432
-	    return $this->count_registrations() === 0;
1433
-    }
1432
+		return $this->count_registrations() === 0;
1433
+	}
1434 1434
 } //end EE_Ticket class
Please login to merge, or discard this patch.
Spacing   +203 added lines, -203 removed lines patch added patch discarded remove patch
@@ -1,7 +1,7 @@  discard block
 block discarded – undo
1 1
 <?php use EventEspresso\core\exceptions\UnexpectedEntityException;
2 2
 
3
-if ( !defined( 'EVENT_ESPRESSO_VERSION' ) ) {
4
-	exit( 'No direct script access allowed' );
3
+if ( ! defined('EVENT_ESPRESSO_VERSION')) {
4
+	exit('No direct script access allowed');
5 5
 }
6 6
 /**
7 7
  * Event Espresso
@@ -70,9 +70,9 @@  discard block
 block discarded – undo
70 70
      * @return EE_Ticket
71 71
      * @throws \EE_Error
72 72
      */
73
-	public static function new_instance( $props_n_values = array(), $timezone = null, $date_formats = array() ) {
74
-		$has_object = parent::_check_for_object( $props_n_values, __CLASS__, $timezone, $date_formats );
75
-		return $has_object ? $has_object : new self( $props_n_values, false, $timezone, $date_formats );
73
+	public static function new_instance($props_n_values = array(), $timezone = null, $date_formats = array()) {
74
+		$has_object = parent::_check_for_object($props_n_values, __CLASS__, $timezone, $date_formats);
75
+		return $has_object ? $has_object : new self($props_n_values, false, $timezone, $date_formats);
76 76
 	}
77 77
 
78 78
 
@@ -84,8 +84,8 @@  discard block
 block discarded – undo
84 84
      * @return EE_Ticket
85 85
      * @throws \EE_Error
86 86
      */
87
-	public static function new_instance_from_db( $props_n_values = array(), $timezone = null ) {
88
-		return new self( $props_n_values, TRUE, $timezone );
87
+	public static function new_instance_from_db($props_n_values = array(), $timezone = null) {
88
+		return new self($props_n_values, TRUE, $timezone);
89 89
 	}
90 90
 
91 91
 
@@ -95,7 +95,7 @@  discard block
 block discarded – undo
95 95
      * @throws \EE_Error
96 96
      */
97 97
 	public function parent() {
98
-		return $this->get( 'TKT_parent' );
98
+		return $this->get('TKT_parent');
99 99
 	}
100 100
 
101 101
 
@@ -107,13 +107,13 @@  discard block
 block discarded – undo
107 107
      * @return boolean
108 108
      * @throws \EE_Error
109 109
      */
110
-	public function available( $DTT_ID = 0 ) {
110
+	public function available($DTT_ID = 0) {
111 111
 		// are we checking availability for a particular datetime ?
112
-		if ( $DTT_ID ) {
112
+		if ($DTT_ID) {
113 113
 			// get that datetime object
114
-			$datetime = $this->get_first_related( 'Datetime', array( array( 'DTT_ID' => $DTT_ID ) ) );
114
+			$datetime = $this->get_first_related('Datetime', array(array('DTT_ID' => $DTT_ID)));
115 115
 			// if  ticket sales for this datetime have exceeded the reg limit...
116
-			if ( $datetime instanceof EE_Datetime && $datetime->sold_out() ) {
116
+			if ($datetime instanceof EE_Datetime && $datetime->sold_out()) {
117 117
 				return FALSE;
118 118
 			}
119 119
 		}
@@ -131,22 +131,22 @@  discard block
 block discarded – undo
131 131
      * @return mixed status int if the display string isn't requested
132 132
      * @throws \EE_Error
133 133
      */
134
-	public function ticket_status( $display = FALSE, $remaining = null ) {
135
-		$remaining = is_bool( $remaining ) ? $remaining : $this->is_remaining();
136
-		if ( ! $remaining ) {
137
-			return $display ? EEH_Template::pretty_status( EE_Ticket::sold_out, FALSE, 'sentence' ) : EE_Ticket::sold_out;
134
+	public function ticket_status($display = FALSE, $remaining = null) {
135
+		$remaining = is_bool($remaining) ? $remaining : $this->is_remaining();
136
+		if ( ! $remaining) {
137
+			return $display ? EEH_Template::pretty_status(EE_Ticket::sold_out, FALSE, 'sentence') : EE_Ticket::sold_out;
138 138
 		}
139
-		if ( $this->get( 'TKT_deleted' ) ) {
140
-			return $display ? EEH_Template::pretty_status( EE_Ticket::archived, FALSE, 'sentence' ) : EE_Ticket::archived;
139
+		if ($this->get('TKT_deleted')) {
140
+			return $display ? EEH_Template::pretty_status(EE_Ticket::archived, FALSE, 'sentence') : EE_Ticket::archived;
141 141
 		}
142
-		if ( $this->is_expired() ) {
143
-			return $display ? EEH_Template::pretty_status( EE_Ticket::expired, FALSE, 'sentence' ) : EE_Ticket::expired;
142
+		if ($this->is_expired()) {
143
+			return $display ? EEH_Template::pretty_status(EE_Ticket::expired, FALSE, 'sentence') : EE_Ticket::expired;
144 144
 		}
145
-		if ( $this->is_pending() ) {
146
-			return $display ? EEH_Template::pretty_status( EE_Ticket::pending, FALSE, 'sentence' ) : EE_Ticket::pending;
145
+		if ($this->is_pending()) {
146
+			return $display ? EEH_Template::pretty_status(EE_Ticket::pending, FALSE, 'sentence') : EE_Ticket::pending;
147 147
 		}
148
-		if ( $this->is_on_sale() ) {
149
-			return $display ? EEH_Template::pretty_status( EE_Ticket::onsale, FALSE, 'sentence' ) : EE_Ticket::onsale;
148
+		if ($this->is_on_sale()) {
149
+			return $display ? EEH_Template::pretty_status(EE_Ticket::onsale, FALSE, 'sentence') : EE_Ticket::onsale;
150 150
 		}
151 151
 		return '';
152 152
 	}
@@ -161,12 +161,12 @@  discard block
 block discarded – undo
161 161
      * @return boolean         true = tickets remaining, false not.
162 162
      * @throws \EE_Error
163 163
      */
164
-	public function is_remaining( $DTT_ID = 0 ) {
165
-		$num_remaining = $this->remaining( $DTT_ID );
166
-		if ( $num_remaining === 0 ) {
164
+	public function is_remaining($DTT_ID = 0) {
165
+		$num_remaining = $this->remaining($DTT_ID);
166
+		if ($num_remaining === 0) {
167 167
 			return FALSE;
168 168
 		}
169
-		if ( $num_remaining > 0 && $num_remaining < $this->min() ) {
169
+		if ($num_remaining > 0 && $num_remaining < $this->min()) {
170 170
 			return FALSE;
171 171
 		}
172 172
 		return TRUE;
@@ -182,8 +182,8 @@  discard block
 block discarded – undo
182 182
      * @return int
183 183
      * @throws \EE_Error
184 184
      */
185
-	public function remaining( $DTT_ID = 0 ) {
186
-		return $this->real_quantity_on_ticket('saleable', $DTT_ID );
185
+	public function remaining($DTT_ID = 0) {
186
+		return $this->real_quantity_on_ticket('saleable', $DTT_ID);
187 187
 	}
188 188
 
189 189
 
@@ -195,7 +195,7 @@  discard block
 block discarded – undo
195 195
      * @throws \EE_Error
196 196
      */
197 197
 	public function min() {
198
-		return $this->get( 'TKT_min' );
198
+		return $this->get('TKT_min');
199 199
 	}
200 200
 
201 201
 
@@ -207,7 +207,7 @@  discard block
 block discarded – undo
207 207
      * @throws \EE_Error
208 208
      */
209 209
 	public function is_expired() {
210
-		return ( $this->get_raw( 'TKT_end_date' ) < time() );
210
+		return ($this->get_raw('TKT_end_date') < time());
211 211
 	}
212 212
 
213 213
 
@@ -219,7 +219,7 @@  discard block
 block discarded – undo
219 219
      * @throws \EE_Error
220 220
      */
221 221
 	public function is_pending() {
222
-		return ( $this->get_raw( 'TKT_start_date' ) > time() );
222
+		return ($this->get_raw('TKT_start_date') > time());
223 223
 	}
224 224
 
225 225
 
@@ -231,7 +231,7 @@  discard block
 block discarded – undo
231 231
      * @throws \EE_Error
232 232
      */
233 233
 	public function is_on_sale() {
234
-		return ( $this->get_raw( 'TKT_start_date' ) < time() && $this->get_raw( 'TKT_end_date' ) > time() );
234
+		return ($this->get_raw('TKT_start_date') < time() && $this->get_raw('TKT_end_date') > time());
235 235
 	}
236 236
 
237 237
 
@@ -244,11 +244,11 @@  discard block
 block discarded – undo
244 244
      * @return string
245 245
      * @throws \EE_Error
246 246
      */
247
-	public function date_range( $dt_frmt = '', $conjunction = ' - ' ) {
248
-		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date( $dt_frmt ) : '';
249
-		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date( $dt_frmt ) : '';
247
+	public function date_range($dt_frmt = '', $conjunction = ' - ') {
248
+		$first_date = $this->first_datetime() instanceof EE_Datetime ? $this->first_datetime()->start_date($dt_frmt) : '';
249
+		$last_date = $this->last_datetime() instanceof EE_Datetime ? $this->last_datetime()->end_date($dt_frmt) : '';
250 250
 
251
-		return $first_date && $last_date ? $first_date . $conjunction  . $last_date : '';
251
+		return $first_date && $last_date ? $first_date.$conjunction.$last_date : '';
252 252
 	}
253 253
 
254 254
 
@@ -260,8 +260,8 @@  discard block
 block discarded – undo
260 260
      * @throws \EE_Error
261 261
      */
262 262
 	public function first_datetime() {
263
-		$datetimes = $this->datetimes( array( 'limit' => 1 ) );
264
-		return reset( $datetimes );
263
+		$datetimes = $this->datetimes(array('limit' => 1));
264
+		return reset($datetimes);
265 265
 	}
266 266
 
267 267
 
@@ -274,11 +274,11 @@  discard block
 block discarded – undo
274 274
      * @return EE_Datetime[]|EE_Base_Class[]
275 275
      * @throws \EE_Error
276 276
      */
277
-	public function datetimes( $query_params = array() ) {
278
-		if ( ! isset( $query_params[ 'order_by' ] ) ) {
279
-			$query_params[ 'order_by' ][ 'DTT_order' ] = 'ASC';
277
+	public function datetimes($query_params = array()) {
278
+		if ( ! isset($query_params['order_by'])) {
279
+			$query_params['order_by']['DTT_order'] = 'ASC';
280 280
 		}
281
-		return $this->get_many_related( 'Datetime', $query_params );
281
+		return $this->get_many_related('Datetime', $query_params);
282 282
 	}
283 283
 
284 284
 
@@ -290,8 +290,8 @@  discard block
 block discarded – undo
290 290
      * @throws \EE_Error
291 291
      */
292 292
 	public function last_datetime() {
293
-		$datetimes = $this->datetimes( array( 'limit' => 1, 'order_by' => array( 'DTT_EVT_start' => 'DESC' ) ) );
294
-		return end( $datetimes );
293
+		$datetimes = $this->datetimes(array('limit' => 1, 'order_by' => array('DTT_EVT_start' => 'DESC')));
294
+		return end($datetimes);
295 295
 	}
296 296
 
297 297
 
@@ -309,22 +309,22 @@  discard block
 block discarded – undo
309 309
      * @return mixed (array|int)          how many tickets have sold
310 310
      * @throws \EE_Error
311 311
      */
312
-	public function tickets_sold( $what = 'ticket', $dtt_id = NULL ) {
312
+	public function tickets_sold($what = 'ticket', $dtt_id = NULL) {
313 313
 		$total = 0;
314 314
 		$tickets_sold = $this->_all_tickets_sold();
315
-		switch ( $what ) {
315
+		switch ($what) {
316 316
 			case 'ticket' :
317
-				return $tickets_sold[ 'ticket' ];
317
+				return $tickets_sold['ticket'];
318 318
 				break;
319 319
 			case 'datetime' :
320
-				if ( empty( $tickets_sold[ 'datetime' ] ) ) {
320
+				if (empty($tickets_sold['datetime'])) {
321 321
 					return $total;
322 322
 				}
323
-				if ( ! empty( $dtt_id ) && ! isset( $tickets_sold[ 'datetime' ][ $dtt_id ] ) ) {
324
-					EE_Error::add_error( __( 'You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?', 'event_espresso' ), __FILE__, __FUNCTION__, __LINE__ );
323
+				if ( ! empty($dtt_id) && ! isset($tickets_sold['datetime'][$dtt_id])) {
324
+					EE_Error::add_error(__('You\'ve requested the amount of tickets sold for a given ticket and datetime, however there are no records for the datetime id you included.  Are you SURE that is a datetime related to this ticket?', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
325 325
 					return $total;
326 326
 				}
327
-				return empty( $dtt_id ) ? $tickets_sold[ 'datetime' ] : $tickets_sold[ 'datetime' ][ $dtt_id ];
327
+				return empty($dtt_id) ? $tickets_sold['datetime'] : $tickets_sold['datetime'][$dtt_id];
328 328
 				break;
329 329
 			default:
330 330
 				return $total;
@@ -340,15 +340,15 @@  discard block
 block discarded – undo
340 340
      * @throws \EE_Error
341 341
      */
342 342
 	protected function _all_tickets_sold() {
343
-		$datetimes = $this->get_many_related( 'Datetime' );
343
+		$datetimes = $this->get_many_related('Datetime');
344 344
 		$tickets_sold = array();
345
-		if ( ! empty( $datetimes ) ) {
346
-			foreach ( $datetimes as $datetime ) {
347
-				$tickets_sold[ 'datetime' ][ $datetime->ID() ] = $datetime->get( 'DTT_sold' );
345
+		if ( ! empty($datetimes)) {
346
+			foreach ($datetimes as $datetime) {
347
+				$tickets_sold['datetime'][$datetime->ID()] = $datetime->get('DTT_sold');
348 348
 			}
349 349
 		}
350 350
 		//Tickets sold
351
-		$tickets_sold[ 'ticket' ] = $this->sold();
351
+		$tickets_sold['ticket'] = $this->sold();
352 352
 		return $tickets_sold;
353 353
 	}
354 354
 
@@ -361,11 +361,11 @@  discard block
 block discarded – undo
361 361
      * @return EE_Price|EE_Base_Class|EE_Price[]|EE_Base_Class[]
362 362
      * @throws \EE_Error
363 363
      */
364
-	public function base_price( $return_array = FALSE ) {
365
-		$_where = array( 'Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price );
364
+	public function base_price($return_array = FALSE) {
365
+		$_where = array('Price_Type.PBT_ID' => EEM_Price_Type::base_type_base_price);
366 366
 		return $return_array
367
-            ? $this->get_many_related( 'Price', array( $_where ) )
368
-            : $this->get_first_related( 'Price', array( $_where ) );
367
+            ? $this->get_many_related('Price', array($_where))
368
+            : $this->get_first_related('Price', array($_where));
369 369
 	}
370 370
 
371 371
 
@@ -378,8 +378,8 @@  discard block
 block discarded – undo
378 378
      * @throws \EE_Error
379 379
      */
380 380
 	public function price_modifiers() {
381
-		$query_params = array( 0 => array( 'Price_Type.PBT_ID' => array( 'NOT IN', array( EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax ) ) ) );
382
-		return $this->prices( $query_params );
381
+		$query_params = array(0 => array('Price_Type.PBT_ID' => array('NOT IN', array(EEM_Price_Type::base_type_base_price, EEM_Price_Type::base_type_tax))));
382
+		return $this->prices($query_params);
383 383
 	}
384 384
 
385 385
 
@@ -391,8 +391,8 @@  discard block
 block discarded – undo
391 391
      * @return EE_Price[]|EE_Base_Class[]
392 392
      * @throws \EE_Error
393 393
      */
394
-	public function prices( $query_params = array() ) {
395
-		return $this->get_many_related( 'Price', $query_params );
394
+	public function prices($query_params = array()) {
395
+		return $this->get_many_related('Price', $query_params);
396 396
 	}
397 397
 
398 398
 
@@ -404,8 +404,8 @@  discard block
 block discarded – undo
404 404
      * @return EE_Datetime_Ticket|EE_Base_Class[]
405 405
      * @throws \EE_Error
406 406
      */
407
-	public function datetime_tickets( $query_params = array() ) {
408
-		return $this->get_many_related( 'Datetime_Ticket', $query_params );
407
+	public function datetime_tickets($query_params = array()) {
408
+		return $this->get_many_related('Datetime_Ticket', $query_params);
409 409
 	}
410 410
 
411 411
 
@@ -418,8 +418,8 @@  discard block
 block discarded – undo
418 418
      * @return EE_Datetime[]
419 419
      * @throws \EE_Error
420 420
      */
421
-	public function datetimes_ordered( $show_expired = TRUE, $show_deleted = FALSE ) {
422
-		return EEM_Datetime::instance( $this->_timezone )->get_datetimes_for_ticket_ordered_by_DTT_order( $this->ID(), $show_expired, $show_deleted );
421
+	public function datetimes_ordered($show_expired = TRUE, $show_deleted = FALSE) {
422
+		return EEM_Datetime::instance($this->_timezone)->get_datetimes_for_ticket_ordered_by_DTT_order($this->ID(), $show_expired, $show_deleted);
423 423
 	}
424 424
 
425 425
 
@@ -431,7 +431,7 @@  discard block
 block discarded – undo
431 431
      * @throws \EE_Error
432 432
      */
433 433
 	public function ID() {
434
-		return $this->get( 'TKT_ID' );
434
+		return $this->get('TKT_ID');
435 435
 	}
436 436
 
437 437
 
@@ -456,7 +456,7 @@  discard block
 block discarded – undo
456 456
      * @throws \EE_Error
457 457
      */
458 458
 	public function template() {
459
-		return $this->get_first_related( 'Ticket_Template' );
459
+		return $this->get_first_related('Ticket_Template');
460 460
 	}
461 461
 
462 462
 
@@ -478,7 +478,7 @@  discard block
 block discarded – undo
478 478
      * @throws \EE_Error
479 479
      */
480 480
 	public function ticket_price() {
481
-		return $this->get( 'TKT_price' );
481
+		return $this->get('TKT_price');
482 482
 	}
483 483
 
484 484
 
@@ -488,7 +488,7 @@  discard block
 block discarded – undo
488 488
      * @throws \EE_Error
489 489
      */
490 490
 	public function pretty_price() {
491
-		return $this->get_pretty( 'TKT_price' );
491
+		return $this->get_pretty('TKT_price');
492 492
 	}
493 493
 
494 494
 
@@ -510,8 +510,8 @@  discard block
 block discarded – undo
510 510
      * @return float
511 511
      * @throws \EE_Error
512 512
      */
513
-	public function get_ticket_total_with_taxes( $no_cache = FALSE ) {
514
-		if ($this->_ticket_total_with_taxes === null || $no_cache ) {
513
+	public function get_ticket_total_with_taxes($no_cache = FALSE) {
514
+		if ($this->_ticket_total_with_taxes === null || $no_cache) {
515 515
 			$this->_ticket_total_with_taxes = $this->get_ticket_subtotal() + $this->get_ticket_taxes_total_for_admin();
516 516
 		}
517 517
 		return (float) $this->_ticket_total_with_taxes;
@@ -520,7 +520,7 @@  discard block
 block discarded – undo
520 520
 
521 521
 
522 522
 	public function ensure_TKT_Price_correct() {
523
-		$this->set( 'TKT_price', EE_Taxes::get_subtotal_for_admin( $this ) );
523
+		$this->set('TKT_price', EE_Taxes::get_subtotal_for_admin($this));
524 524
 		$this->save();
525 525
 	}
526 526
 
@@ -531,7 +531,7 @@  discard block
 block discarded – undo
531 531
      * @throws \EE_Error
532 532
      */
533 533
 	public function get_ticket_subtotal() {
534
-		return EE_Taxes::get_subtotal_for_admin( $this );
534
+		return EE_Taxes::get_subtotal_for_admin($this);
535 535
 	}
536 536
 
537 537
 
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
      * @throws \EE_Error
544 544
      */
545 545
 	public function get_ticket_taxes_total_for_admin() {
546
-		return EE_Taxes::get_total_taxes_for_admin( $this );
546
+		return EE_Taxes::get_total_taxes_for_admin($this);
547 547
 	}
548 548
 
549 549
 
@@ -554,8 +554,8 @@  discard block
 block discarded – undo
554 554
      * @param string $name
555 555
      * @throws \EE_Error
556 556
      */
557
-	public function set_name( $name ) {
558
-		$this->set( 'TKT_name', $name );
557
+	public function set_name($name) {
558
+		$this->set('TKT_name', $name);
559 559
 	}
560 560
 
561 561
 
@@ -567,7 +567,7 @@  discard block
 block discarded – undo
567 567
      * @throws \EE_Error
568 568
      */
569 569
 	public function description() {
570
-		return $this->get( 'TKT_description' );
570
+		return $this->get('TKT_description');
571 571
 	}
572 572
 
573 573
 
@@ -578,8 +578,8 @@  discard block
 block discarded – undo
578 578
      * @param string $description
579 579
      * @throws \EE_Error
580 580
      */
581
-	public function set_description( $description ) {
582
-		$this->set( 'TKT_description', $description );
581
+	public function set_description($description) {
582
+		$this->set('TKT_description', $description);
583 583
 	}
584 584
 
585 585
 
@@ -592,8 +592,8 @@  discard block
 block discarded – undo
592 592
      * @return string
593 593
      * @throws \EE_Error
594 594
      */
595
-	public function start_date( $dt_frmt = '', $tm_frmt = '' ) {
596
-		return $this->_get_datetime( 'TKT_start_date', $dt_frmt, $tm_frmt );
595
+	public function start_date($dt_frmt = '', $tm_frmt = '') {
596
+		return $this->_get_datetime('TKT_start_date', $dt_frmt, $tm_frmt);
597 597
 	}
598 598
 
599 599
 
@@ -605,8 +605,8 @@  discard block
 block discarded – undo
605 605
      * @return void
606 606
      * @throws \EE_Error
607 607
      */
608
-	public function set_start_date( $start_date ) {
609
-		$this->_set_date_time( 'B', $start_date, 'TKT_start_date' );
608
+	public function set_start_date($start_date) {
609
+		$this->_set_date_time('B', $start_date, 'TKT_start_date');
610 610
 	}
611 611
 
612 612
 
@@ -619,8 +619,8 @@  discard block
 block discarded – undo
619 619
      * @return string
620 620
      * @throws \EE_Error
621 621
      */
622
-	public function end_date( $dt_frmt = '', $tm_frmt = '' ) {
623
-		return $this->_get_datetime( 'TKT_end_date', $dt_frmt, $tm_frmt );
622
+	public function end_date($dt_frmt = '', $tm_frmt = '') {
623
+		return $this->_get_datetime('TKT_end_date', $dt_frmt, $tm_frmt);
624 624
 	}
625 625
 
626 626
 
@@ -632,8 +632,8 @@  discard block
 block discarded – undo
632 632
      * @return void
633 633
      * @throws \EE_Error
634 634
      */
635
-	public function set_end_date( $end_date ) {
636
-		$this->_set_date_time( 'B', $end_date, 'TKT_end_date' );
635
+	public function set_end_date($end_date) {
636
+		$this->_set_date_time('B', $end_date, 'TKT_end_date');
637 637
 	}
638 638
 
639 639
 
@@ -645,8 +645,8 @@  discard block
 block discarded – undo
645 645
      * @param string $time a string representation of the sell until time (ex 9am or 7:30pm)
646 646
      * @throws \EE_Error
647 647
      */
648
-	public function set_end_time( $time ) {
649
-		$this->_set_time_for( $time, 'TKT_end_date' );
648
+	public function set_end_time($time) {
649
+		$this->_set_time_for($time, 'TKT_end_date');
650 650
 	}
651 651
 
652 652
 
@@ -658,8 +658,8 @@  discard block
 block discarded – undo
658 658
      * @return void
659 659
      * @throws \EE_Error
660 660
      */
661
-	public function set_min( $min ) {
662
-		$this->set( 'TKT_min', $min );
661
+	public function set_min($min) {
662
+		$this->set('TKT_min', $min);
663 663
 	}
664 664
 
665 665
 
@@ -671,7 +671,7 @@  discard block
 block discarded – undo
671 671
      * @throws \EE_Error
672 672
      */
673 673
 	public function max() {
674
-		return $this->get( 'TKT_max' );
674
+		return $this->get('TKT_max');
675 675
 	}
676 676
 
677 677
 
@@ -683,8 +683,8 @@  discard block
 block discarded – undo
683 683
      * @return void
684 684
      * @throws \EE_Error
685 685
      */
686
-	public function set_max( $max ) {
687
-		$this->set( 'TKT_max', $max );
686
+	public function set_max($max) {
687
+		$this->set('TKT_max', $max);
688 688
 	}
689 689
 
690 690
 
@@ -696,8 +696,8 @@  discard block
 block discarded – undo
696 696
      * @return void
697 697
      * @throws \EE_Error
698 698
      */
699
-	public function set_price( $price ) {
700
-		$this->set( 'TKT_price', $price );
699
+	public function set_price($price) {
700
+		$this->set('TKT_price', $price);
701 701
 	}
702 702
 
703 703
 
@@ -709,7 +709,7 @@  discard block
 block discarded – undo
709 709
      * @throws \EE_Error
710 710
      */
711 711
 	public function sold() {
712
-		return $this->get_raw( 'TKT_sold' );
712
+		return $this->get_raw('TKT_sold');
713 713
 	}
714 714
 
715 715
 
@@ -721,10 +721,10 @@  discard block
 block discarded – undo
721 721
      * @return void
722 722
      * @throws \EE_Error
723 723
      */
724
-	public function set_sold( $sold ) {
724
+	public function set_sold($sold) {
725 725
 		// sold can not go below zero
726
-		$sold = max( 0, $sold );
727
-		$this->set( 'TKT_sold', $sold );
726
+		$sold = max(0, $sold);
727
+		$this->set('TKT_sold', $sold);
728 728
 	}
729 729
 
730 730
 
@@ -736,13 +736,13 @@  discard block
 block discarded – undo
736 736
      * @return void
737 737
      * @throws \EE_Error
738 738
      */
739
-	public function increase_sold( $qty = 1 ) {
739
+	public function increase_sold($qty = 1) {
740 740
 		$sold = $this->sold() + $qty;
741 741
 		// remove ticket reservation, but don't adjust datetime reservations,  because that will happen
742 742
 		// via \EE_Datetime::increase_sold() when \EE_Ticket::_increase_sold_for_datetimes() is called
743
-		$this->decrease_reserved( $qty, false );
744
-		$this->_increase_sold_for_datetimes( $qty );
745
-		$this->set_sold( $sold );
743
+		$this->decrease_reserved($qty, false);
744
+		$this->_increase_sold_for_datetimes($qty);
745
+		$this->set_sold($sold);
746 746
 		do_action(
747 747
 		    'AHEE__EE_Ticket__increase_sold',
748 748
             $this,
@@ -760,12 +760,12 @@  discard block
 block discarded – undo
760 760
      * @return void
761 761
      * @throws \EE_Error
762 762
      */
763
-	protected function _increase_sold_for_datetimes( $qty = 1 ) {
763
+	protected function _increase_sold_for_datetimes($qty = 1) {
764 764
 		$datetimes = $this->datetimes();
765
-		if ( is_array( $datetimes ) ) {
766
-			foreach ( $datetimes as $datetime ) {
767
-				if ( $datetime instanceof EE_Datetime ) {
768
-					$datetime->increase_sold( $qty );
765
+		if (is_array($datetimes)) {
766
+			foreach ($datetimes as $datetime) {
767
+				if ($datetime instanceof EE_Datetime) {
768
+					$datetime->increase_sold($qty);
769 769
 					$datetime->save();
770 770
 				}
771 771
 			}
@@ -781,10 +781,10 @@  discard block
 block discarded – undo
781 781
      * @return void
782 782
      * @throws \EE_Error
783 783
      */
784
-	public function decrease_sold( $qty = 1 ) {
784
+	public function decrease_sold($qty = 1) {
785 785
 		$sold = $this->sold() - $qty;
786
-		$this->_decrease_sold_for_datetimes( $qty );
787
-		$this->set_sold( $sold );
786
+		$this->_decrease_sold_for_datetimes($qty);
787
+		$this->set_sold($sold);
788 788
         do_action(
789 789
             'AHEE__EE_Ticket__decrease_sold',
790 790
             $this,
@@ -802,12 +802,12 @@  discard block
 block discarded – undo
802 802
      * @return void
803 803
      * @throws \EE_Error
804 804
      */
805
-	protected function _decrease_sold_for_datetimes( $qty = 1 ) {
805
+	protected function _decrease_sold_for_datetimes($qty = 1) {
806 806
 		$datetimes = $this->datetimes();
807
-		if ( is_array( $datetimes ) ) {
808
-			foreach ( $datetimes as $datetime ) {
809
-				if ( $datetime instanceof EE_Datetime ) {
810
-					$datetime->decrease_sold( $qty );
807
+		if (is_array($datetimes)) {
808
+			foreach ($datetimes as $datetime) {
809
+				if ($datetime instanceof EE_Datetime) {
810
+					$datetime->decrease_sold($qty);
811 811
 					$datetime->save();
812 812
 				}
813 813
 			}
@@ -823,7 +823,7 @@  discard block
 block discarded – undo
823 823
      * @throws \EE_Error
824 824
      */
825 825
 	public function reserved() {
826
-		return $this->get_raw( 'TKT_reserved' );
826
+		return $this->get_raw('TKT_reserved');
827 827
 	}
828 828
 
829 829
 
@@ -835,10 +835,10 @@  discard block
 block discarded – undo
835 835
      * @return void
836 836
      * @throws \EE_Error
837 837
      */
838
-	public function set_reserved( $reserved ) {
838
+	public function set_reserved($reserved) {
839 839
 		// reserved can not go below zero
840
-		$reserved = max( 0, (int) $reserved );
841
-		$this->set( 'TKT_reserved', $reserved );
840
+		$reserved = max(0, (int) $reserved);
841
+		$this->set('TKT_reserved', $reserved);
842 842
 	}
843 843
 
844 844
 
@@ -850,11 +850,11 @@  discard block
 block discarded – undo
850 850
      * @return void
851 851
      * @throws \EE_Error
852 852
      */
853
-	public function increase_reserved( $qty = 1 ) {
854
-		$qty = absint( $qty );
853
+	public function increase_reserved($qty = 1) {
854
+		$qty = absint($qty);
855 855
 		$reserved = $this->reserved() + $qty;
856
-		$this->_increase_reserved_for_datetimes( $qty );
857
-		$this->set_reserved( $reserved );
856
+		$this->_increase_reserved_for_datetimes($qty);
857
+		$this->set_reserved($reserved);
858 858
         do_action(
859 859
             'AHEE__EE_Ticket__increase_reserved',
860 860
             $this,
@@ -872,12 +872,12 @@  discard block
 block discarded – undo
872 872
      * @return void
873 873
      * @throws \EE_Error
874 874
      */
875
-	protected function _increase_reserved_for_datetimes( $qty = 1 ) {
875
+	protected function _increase_reserved_for_datetimes($qty = 1) {
876 876
 		$datetimes = $this->datetimes();
877
-		if ( is_array( $datetimes ) ) {
878
-			foreach ( $datetimes as $datetime ) {
879
-				if ( $datetime instanceof EE_Datetime ) {
880
-					$datetime->increase_reserved( $qty );
877
+		if (is_array($datetimes)) {
878
+			foreach ($datetimes as $datetime) {
879
+				if ($datetime instanceof EE_Datetime) {
880
+					$datetime->increase_reserved($qty);
881 881
 					$datetime->save();
882 882
 				}
883 883
 			}
@@ -894,12 +894,12 @@  discard block
 block discarded – undo
894 894
      * @return void
895 895
      * @throws \EE_Error
896 896
      */
897
-	public function decrease_reserved( $qty = 1, $adjust_datetimes = true ) {
898
-		$reserved = $this->reserved() - absint( $qty );
899
-		if ( $adjust_datetimes ) {
900
-			$this->_decrease_reserved_for_datetimes( $qty );
897
+	public function decrease_reserved($qty = 1, $adjust_datetimes = true) {
898
+		$reserved = $this->reserved() - absint($qty);
899
+		if ($adjust_datetimes) {
900
+			$this->_decrease_reserved_for_datetimes($qty);
901 901
 		}
902
-		$this->set_reserved( $reserved );
902
+		$this->set_reserved($reserved);
903 903
         do_action(
904 904
             'AHEE__EE_Ticket__decrease_reserved',
905 905
             $this,
@@ -917,12 +917,12 @@  discard block
 block discarded – undo
917 917
      * @return void
918 918
      * @throws \EE_Error
919 919
      */
920
-	protected function _decrease_reserved_for_datetimes( $qty = 1 ) {
920
+	protected function _decrease_reserved_for_datetimes($qty = 1) {
921 921
 		$datetimes = $this->datetimes();
922
-		if ( is_array( $datetimes ) ) {
923
-			foreach ( $datetimes as $datetime ) {
924
-				if ( $datetime instanceof EE_Datetime ) {
925
-					$datetime->decrease_reserved( $qty );
922
+		if (is_array($datetimes)) {
923
+			foreach ($datetimes as $datetime) {
924
+				if ($datetime instanceof EE_Datetime) {
925
+					$datetime->decrease_reserved($qty);
926 926
 					$datetime->save();
927 927
 				}
928 928
 			}
@@ -943,14 +943,14 @@  discard block
 block discarded – undo
943 943
      * @return int
944 944
      * @throws \EE_Error
945 945
      */
946
-	public function qty( $context = '' ) {
947
-		switch ( $context ) {
946
+	public function qty($context = '') {
947
+		switch ($context) {
948 948
 			case 'reg_limit' :
949 949
 				return $this->real_quantity_on_ticket();
950 950
 			case 'saleable' :
951
-				return $this->real_quantity_on_ticket( 'saleable' );
951
+				return $this->real_quantity_on_ticket('saleable');
952 952
 			default:
953
-				return $this->get_raw( 'TKT_qty' );
953
+				return $this->get_raw('TKT_qty');
954 954
 		}
955 955
 	}
956 956
 
@@ -969,15 +969,15 @@  discard block
 block discarded – undo
969 969
      * @return int
970 970
      * @throws \EE_Error
971 971
      */
972
-	public function real_quantity_on_ticket( $context = 'reg_limit', $DTT_ID = 0 ) {
973
-		$raw = $this->get_raw( 'TKT_qty' );
972
+	public function real_quantity_on_ticket($context = 'reg_limit', $DTT_ID = 0) {
973
+		$raw = $this->get_raw('TKT_qty');
974 974
 		// return immediately if it's zero
975
-		if ( $raw === 0 ) {
975
+		if ($raw === 0) {
976 976
 			return $raw;
977 977
 		}
978 978
 		//echo "\n\n<br />Ticket: " . $this->name() . '<br />';
979 979
 		// ensure qty doesn't exceed raw value for THIS ticket
980
-		$qty = min( EE_INF, $raw );
980
+		$qty = min(EE_INF, $raw);
981 981
 		//echo "\n . qty: " . $qty . '<br />';
982 982
 		// calculate this ticket's total sales and reservations
983 983
 		$sold_and_reserved_for_this_ticket = $this->sold() + $this->reserved();
@@ -986,23 +986,23 @@  discard block
 block discarded – undo
986 986
 		//echo "\n . sold_and_reserved_for_this_ticket: " . $sold_and_reserved_for_this_ticket . '<br />';
987 987
 		// first we need to calculate the maximum number of tickets available for the datetime
988 988
 		// do we want data for one datetime or all of them ?
989
-		$query_params = $DTT_ID ? array( array( 'DTT_ID' => $DTT_ID ) ) : array();
990
-		$datetimes = $this->datetimes( $query_params );
991
-		if ( is_array( $datetimes ) && ! empty( $datetimes ) ) {
992
-			foreach ( $datetimes as $datetime ) {
993
-				if ( $datetime instanceof EE_Datetime ) {
989
+		$query_params = $DTT_ID ? array(array('DTT_ID' => $DTT_ID)) : array();
990
+		$datetimes = $this->datetimes($query_params);
991
+		if (is_array($datetimes) && ! empty($datetimes)) {
992
+			foreach ($datetimes as $datetime) {
993
+				if ($datetime instanceof EE_Datetime) {
994 994
 					$datetime->refresh_from_db();
995 995
 					//echo "\n . . datetime name: " . $datetime->name() . '<br />';
996 996
 					//echo "\n . . datetime ID: " . $datetime->ID() . '<br />';
997 997
 					// initialize with no restrictions for each datetime
998 998
 					// but adjust datetime qty based on datetime reg limit
999
-					$datetime_qty = min( EE_INF, $datetime->reg_limit() );
999
+					$datetime_qty = min(EE_INF, $datetime->reg_limit());
1000 1000
 					//echo "\n . . . datetime reg_limit: " . $datetime->reg_limit() . '<br />';
1001 1001
 					//echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1002 1002
 					// if we want the actual saleable amount, then we need to consider OTHER ticket sales
1003 1003
 					// and reservations for this datetime, that do NOT include sales and reservations
1004 1004
 					// for this ticket (so we add $this->sold() and $this->reserved() back in)
1005
-					if ( $context === 'saleable' ) {
1005
+					if ($context === 'saleable') {
1006 1006
 						$datetime_qty = max(
1007 1007
 							$datetime_qty - $datetime->sold_and_reserved() + $sold_and_reserved_for_this_ticket,
1008 1008
 							0
@@ -1014,16 +1014,16 @@  discard block
 block discarded – undo
1014 1014
 						$datetime_qty = ! $datetime->sold_out() ? $datetime_qty : 0;
1015 1015
 						//echo "\n . . . datetime_qty: " . $datetime_qty . '<br />';
1016 1016
 					}
1017
-					$qty = min( $datetime_qty, $qty );
1017
+					$qty = min($datetime_qty, $qty);
1018 1018
 					//echo "\n . . qty: " . $qty . '<br />';
1019 1019
 				}
1020 1020
 			}
1021 1021
 		}
1022 1022
 		// NOW that we know the  maximum number of tickets available for the datetime
1023 1023
 		// we can finally factor in the details for this specific ticket
1024
-		if ( $qty > 0 && $context === 'saleable' ) {
1024
+		if ($qty > 0 && $context === 'saleable') {
1025 1025
 			// and subtract the sales for THIS ticket
1026
-			$qty = max( $qty - $sold_and_reserved_for_this_ticket, 0 );
1026
+			$qty = max($qty - $sold_and_reserved_for_this_ticket, 0);
1027 1027
 			//echo "\n . qty: " . $qty . '<br />';
1028 1028
 		}
1029 1029
 		//echo "\nFINAL QTY: " . $qty . "<br /><br />";
@@ -1039,14 +1039,14 @@  discard block
 block discarded – undo
1039 1039
 	 * @return void
1040 1040
 	 * @throws \EE_Error
1041 1041
 	 */
1042
-	public function set_qty( $qty ) {
1042
+	public function set_qty($qty) {
1043 1043
 		$datetimes = $this->datetimes();
1044
-		foreach ( $datetimes as $datetime ) {
1045
-			if ( $datetime instanceof EE_Datetime ) {
1046
-				$qty = min( $qty, $datetime->reg_limit() );
1044
+		foreach ($datetimes as $datetime) {
1045
+			if ($datetime instanceof EE_Datetime) {
1046
+				$qty = min($qty, $datetime->reg_limit());
1047 1047
 			}
1048 1048
 		}
1049
-		$this->set( 'TKT_qty', $qty );
1049
+		$this->set('TKT_qty', $qty);
1050 1050
 	}
1051 1051
 
1052 1052
 
@@ -1058,7 +1058,7 @@  discard block
 block discarded – undo
1058 1058
      * @throws \EE_Error
1059 1059
      */
1060 1060
 	public function uses() {
1061
-		return $this->get( 'TKT_uses' );
1061
+		return $this->get('TKT_uses');
1062 1062
 	}
1063 1063
 
1064 1064
 
@@ -1070,8 +1070,8 @@  discard block
 block discarded – undo
1070 1070
      * @return void
1071 1071
      * @throws \EE_Error
1072 1072
      */
1073
-	public function set_uses( $uses ) {
1074
-		$this->set( 'TKT_uses', $uses );
1073
+	public function set_uses($uses) {
1074
+		$this->set('TKT_uses', $uses);
1075 1075
 	}
1076 1076
 
1077 1077
 
@@ -1083,7 +1083,7 @@  discard block
 block discarded – undo
1083 1083
      * @throws \EE_Error
1084 1084
      */
1085 1085
 	public function required() {
1086
-		return $this->get( 'TKT_required' );
1086
+		return $this->get('TKT_required');
1087 1087
 	}
1088 1088
 
1089 1089
 
@@ -1095,8 +1095,8 @@  discard block
 block discarded – undo
1095 1095
      * @return void
1096 1096
      * @throws \EE_Error
1097 1097
      */
1098
-	public function set_required( $required ) {
1099
-		$this->set( 'TKT_required', $required );
1098
+	public function set_required($required) {
1099
+		$this->set('TKT_required', $required);
1100 1100
 	}
1101 1101
 
1102 1102
 
@@ -1108,7 +1108,7 @@  discard block
 block discarded – undo
1108 1108
      * @throws \EE_Error
1109 1109
      */
1110 1110
 	public function taxable() {
1111
-		return $this->get( 'TKT_taxable' );
1111
+		return $this->get('TKT_taxable');
1112 1112
 	}
1113 1113
 
1114 1114
 
@@ -1120,8 +1120,8 @@  discard block
 block discarded – undo
1120 1120
      * @return void
1121 1121
      * @throws \EE_Error
1122 1122
      */
1123
-	public function set_taxable( $taxable ) {
1124
-		$this->set( 'TKT_taxable', $taxable );
1123
+	public function set_taxable($taxable) {
1124
+		$this->set('TKT_taxable', $taxable);
1125 1125
 	}
1126 1126
 
1127 1127
 
@@ -1133,7 +1133,7 @@  discard block
 block discarded – undo
1133 1133
      * @throws \EE_Error
1134 1134
      */
1135 1135
 	public function is_default() {
1136
-		return $this->get( 'TKT_is_default' );
1136
+		return $this->get('TKT_is_default');
1137 1137
 	}
1138 1138
 
1139 1139
 
@@ -1145,8 +1145,8 @@  discard block
 block discarded – undo
1145 1145
      * @return void
1146 1146
      * @throws \EE_Error
1147 1147
      */
1148
-	public function set_is_default( $is_default ) {
1149
-		$this->set( 'TKT_is_default', $is_default );
1148
+	public function set_is_default($is_default) {
1149
+		$this->set('TKT_is_default', $is_default);
1150 1150
 	}
1151 1151
 
1152 1152
 
@@ -1158,7 +1158,7 @@  discard block
 block discarded – undo
1158 1158
      * @throws \EE_Error
1159 1159
      */
1160 1160
 	public function order() {
1161
-		return $this->get( 'TKT_order' );
1161
+		return $this->get('TKT_order');
1162 1162
 	}
1163 1163
 
1164 1164
 
@@ -1170,8 +1170,8 @@  discard block
 block discarded – undo
1170 1170
      * @return void
1171 1171
      * @throws \EE_Error
1172 1172
      */
1173
-	public function set_order( $order ) {
1174
-		$this->set( 'TKT_order', $order );
1173
+	public function set_order($order) {
1174
+		$this->set('TKT_order', $order);
1175 1175
 	}
1176 1176
 
1177 1177
 
@@ -1183,7 +1183,7 @@  discard block
 block discarded – undo
1183 1183
      * @throws \EE_Error
1184 1184
      */
1185 1185
 	public function row() {
1186
-		return $this->get( 'TKT_row' );
1186
+		return $this->get('TKT_row');
1187 1187
 	}
1188 1188
 
1189 1189
 
@@ -1195,8 +1195,8 @@  discard block
 block discarded – undo
1195 1195
      * @return void
1196 1196
      * @throws \EE_Error
1197 1197
      */
1198
-	public function set_row( $row ) {
1199
-		$this->set( 'TKT_row', $row );
1198
+	public function set_row($row) {
1199
+		$this->set('TKT_row', $row);
1200 1200
 	}
1201 1201
 
1202 1202
 
@@ -1208,7 +1208,7 @@  discard block
 block discarded – undo
1208 1208
      * @throws \EE_Error
1209 1209
      */
1210 1210
 	public function deleted() {
1211
-		return $this->get( 'TKT_deleted' );
1211
+		return $this->get('TKT_deleted');
1212 1212
 	}
1213 1213
 
1214 1214
 
@@ -1220,8 +1220,8 @@  discard block
 block discarded – undo
1220 1220
      * @return void
1221 1221
      * @throws \EE_Error
1222 1222
      */
1223
-	public function set_deleted( $deleted ) {
1224
-		$this->set( 'TKT_deleted', $deleted );
1223
+	public function set_deleted($deleted) {
1224
+		$this->set('TKT_deleted', $deleted);
1225 1225
 	}
1226 1226
 
1227 1227
 
@@ -1233,7 +1233,7 @@  discard block
 block discarded – undo
1233 1233
      * @throws \EE_Error
1234 1234
      */
1235 1235
 	public function parent_ID() {
1236
-		return $this->get( 'TKT_parent' );
1236
+		return $this->get('TKT_parent');
1237 1237
 	}
1238 1238
 
1239 1239
 
@@ -1245,8 +1245,8 @@  discard block
 block discarded – undo
1245 1245
      * @return void
1246 1246
      * @throws \EE_Error
1247 1247
      */
1248
-	public function set_parent_ID( $parent ) {
1249
-		$this->set( 'TKT_parent', $parent );
1248
+	public function set_parent_ID($parent) {
1249
+		$this->set('TKT_parent', $parent);
1250 1250
 	}
1251 1251
 
1252 1252
 
@@ -1259,10 +1259,10 @@  discard block
 block discarded – undo
1259 1259
      */
1260 1260
 	public function name_and_info() {
1261 1261
 		$times = array();
1262
-		foreach ( $this->datetimes() as $datetime ) {
1262
+		foreach ($this->datetimes() as $datetime) {
1263 1263
 			$times[] = $datetime->start_date_and_time();
1264 1264
 		}
1265
-		return $this->name() . ' @ ' . implode( ', ', $times ) . ' for ' . $this->pretty_price();
1265
+		return $this->name().' @ '.implode(', ', $times).' for '.$this->pretty_price();
1266 1266
 	}
1267 1267
 
1268 1268
 
@@ -1274,7 +1274,7 @@  discard block
 block discarded – undo
1274 1274
      * @throws \EE_Error
1275 1275
      */
1276 1276
 	public function name() {
1277
-		return $this->get( 'TKT_name' );
1277
+		return $this->get('TKT_name');
1278 1278
 	}
1279 1279
 
1280 1280
 
@@ -1286,7 +1286,7 @@  discard block
 block discarded – undo
1286 1286
      * @throws \EE_Error
1287 1287
      */
1288 1288
 	public function price() {
1289
-		return $this->get( 'TKT_price' );
1289
+		return $this->get('TKT_price');
1290 1290
 	}
1291 1291
 
1292 1292
 
@@ -1298,8 +1298,8 @@  discard block
 block discarded – undo
1298 1298
      * @return EE_Registration[]|EE_Base_Class[]
1299 1299
      * @throws \EE_Error
1300 1300
      */
1301
-	public function registrations( $query_params = array() ) {
1302
-		return $this->get_many_related( 'Registration', $query_params );
1301
+	public function registrations($query_params = array()) {
1302
+		return $this->get_many_related('Registration', $query_params);
1303 1303
 	}
1304 1304
 
1305 1305
 
@@ -1338,7 +1338,7 @@  discard block
 block discarded – undo
1338 1338
 	 * @param array $query_params like EEM_Base::get_all's
1339 1339
 	 * @return int
1340 1340
 	 */
1341
-	public function count_registrations( $query_params = array() ) {
1341
+	public function count_registrations($query_params = array()) {
1342 1342
 		return $this->count_related('Registration', $query_params);
1343 1343
 	}
1344 1344
 
@@ -1366,23 +1366,23 @@  discard block
 block discarded – undo
1366 1366
 	public function get_related_event() {
1367 1367
 		//get one datetime to use for getting the event
1368 1368
 		$datetime = $this->first_datetime();
1369
-		if ( ! $datetime instanceof \EE_Datetime ) {
1369
+		if ( ! $datetime instanceof \EE_Datetime) {
1370 1370
 			throw new UnexpectedEntityException(
1371 1371
 				$datetime,
1372 1372
                 'EE_Datetime',
1373 1373
 				sprintf(
1374
-					__( 'The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1374
+					__('The ticket (%s) is not associated with any valid datetimes.', 'event_espresso'),
1375 1375
 					$this->name()
1376 1376
 				)
1377 1377
 			);
1378 1378
 		}
1379 1379
 		$event = $datetime->event();
1380
-		if ( ! $event instanceof \EE_Event ) {
1380
+		if ( ! $event instanceof \EE_Event) {
1381 1381
 			throw new UnexpectedEntityException(
1382 1382
 				$event,
1383 1383
                 'EE_Event',
1384 1384
 				sprintf(
1385
-					__( 'The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1385
+					__('The ticket (%s) is not associated with a valid event.', 'event_espresso'),
1386 1386
 					$this->name()
1387 1387
 				)
1388 1388
 			);
Please login to merge, or discard this patch.