Completed
Branch BUG/11268/session-ticket-relea... (393c4a)
by
unknown
40:56 queued 25:34
created
core/admin/EE_Admin_Page_CPT.core.php 2 patches
Indentation   +1444 added lines, -1444 removed lines patch added patch discarded remove patch
@@ -6,7 +6,7 @@  discard block
 block discarded – undo
6 6
 use EventEspresso\core\services\request\middleware\RecommendedVersions;
7 7
 
8 8
 if ( ! defined('EVENT_ESPRESSO_VERSION')) {
9
-    exit('No direct script access allowed');
9
+	exit('No direct script access allowed');
10 10
 }
11 11
 
12 12
 /**
@@ -31,475 +31,475 @@  discard block
 block discarded – undo
31 31
 {
32 32
 
33 33
 
34
-    /**
35
-     * This gets set in _setup_cpt
36
-     * It will contain the object for the custom post type.
37
-     *
38
-     * @var EE_CPT_Base
39
-     */
40
-    protected $_cpt_object;
41
-
42
-
43
-
44
-    /**
45
-     * a boolean flag to set whether the current route is a cpt route or not.
46
-     *
47
-     * @var bool
48
-     */
49
-    protected $_cpt_route = false;
50
-
51
-
52
-
53
-    /**
54
-     * This property allows cpt classes to define multiple routes as cpt routes.
55
-     * //in this array we define what the custom post type for this route is.
56
-     * array(
57
-     * 'route_name' => 'custom_post_type_slug'
58
-     * )
59
-     *
60
-     * @var array
61
-     */
62
-    protected $_cpt_routes = array();
63
-
34
+	/**
35
+	 * This gets set in _setup_cpt
36
+	 * It will contain the object for the custom post type.
37
+	 *
38
+	 * @var EE_CPT_Base
39
+	 */
40
+	protected $_cpt_object;
41
+
42
+
43
+
44
+	/**
45
+	 * a boolean flag to set whether the current route is a cpt route or not.
46
+	 *
47
+	 * @var bool
48
+	 */
49
+	protected $_cpt_route = false;
50
+
51
+
52
+
53
+	/**
54
+	 * This property allows cpt classes to define multiple routes as cpt routes.
55
+	 * //in this array we define what the custom post type for this route is.
56
+	 * array(
57
+	 * 'route_name' => 'custom_post_type_slug'
58
+	 * )
59
+	 *
60
+	 * @var array
61
+	 */
62
+	protected $_cpt_routes = array();
63
+
64 64
 
65 65
 
66
-    /**
67
-     * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
68
-     * in this format:
69
-     * array(
70
-     * 'post_type_slug' => 'edit_route'
71
-     * )
72
-     *
73
-     * @var array
74
-     */
75
-    protected $_cpt_edit_routes = array();
76
-
77
-
78
-
79
-    /**
80
-     * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
81
-     * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
82
-     * _cpt_model_names property should be in the following format: array(
83
-     * 'route_defined_by_action_param' => 'Model_Name')
84
-     *
85
-     * @var array $_cpt_model_names
86
-     */
87
-    protected $_cpt_model_names = array();
88
-
89
-
90
-    /**
91
-     * @var EE_CPT_Base
92
-     */
93
-    protected $_cpt_model_obj = false;
94
-
95
-
96
-
97
-    /**
98
-     * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
99
-     * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
100
-     * the _register_autosave_containers() method so that we don't override any other containers already registered.
101
-     * Registration of containers should be done before load_page_dependencies() is run.
102
-     *
103
-     * @var array()
104
-     */
105
-    protected $_autosave_containers = array();
106
-    protected $_autosave_fields = array();
107
-
108
-    /**
109
-     * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
110
-     * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
111
-     *
112
-     * @var array
113
-     */
114
-    protected $_pagenow_map;
115
-
116
-
117
-
118
-    /**
119
-     * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
120
-     * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
121
-     * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
122
-     * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
123
-     * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
124
-     *
125
-     * @access protected
126
-     * @abstract
127
-     * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
128
-     * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
129
-     * @return void
130
-     */
131
-    abstract protected function _insert_update_cpt_item($post_id, $post);
132
-
133
-
134
-
135
-    /**
136
-     * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
137
-     *
138
-     * @abstract
139
-     * @access public
140
-     * @param  string $post_id The ID of the cpt that was trashed
141
-     * @return void
142
-     */
143
-    abstract public function trash_cpt_item($post_id);
144
-
145
-
146
-
147
-    /**
148
-     * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
149
-     *
150
-     * @param  string $post_id theID of the cpt that was untrashed
151
-     * @return void
152
-     */
153
-    abstract public function restore_cpt_item($post_id);
154
-
155
-
156
-
157
-    /**
158
-     * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
159
-     * from the db
160
-     *
161
-     * @param  string $post_id the ID of the cpt that was deleted
162
-     * @return void
163
-     */
164
-    abstract public function delete_cpt_item($post_id);
165
-
166
-
167
-
168
-    /**
169
-     * Just utilizing the method EE_Admin exposes for doing things before page setup.
170
-     *
171
-     * @access protected
172
-     * @return void
173
-     */
174
-    protected function _before_page_setup()
175
-    {
176
-        $page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
177
-        $this->_cpt_routes = array_merge(array(
178
-            'create_new' => $this->page_slug,
179
-            'edit'       => $this->page_slug,
180
-            'trash'      => $this->page_slug,
181
-        ), $this->_cpt_routes);
182
-        //let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
183
-        $this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[$this->_req_data['action']])
184
-            ? get_post_type_object($this->_cpt_routes[$this->_req_data['action']])
185
-            : get_post_type_object($page);
186
-        //tweak pagenow for page loading.
187
-        if ( ! $this->_pagenow_map) {
188
-            $this->_pagenow_map = array(
189
-                'create_new' => 'post-new.php',
190
-                'edit'       => 'post.php',
191
-                'trash'      => 'post.php',
192
-            );
193
-        }
194
-        add_action('current_screen', array($this, 'modify_pagenow'));
195
-        //TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
196
-        //get current page from autosave
197
-        $current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
198
-            ? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
199
-            : null;
200
-        $this->_current_page = isset($this->_req_data['current_page'])
201
-            ? $this->_req_data['current_page']
202
-            : $current_page;
203
-        //autosave... make sure its only for the correct page
204
-        //if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
205
-            //setup autosave ajax hook
206
-            //add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
207
-        //}
208
-    }
209
-
210
-
211
-
212
-    /**
213
-     * Simply ensure that we simulate the correct post route for cpt screens
214
-     *
215
-     * @param WP_Screen $current_screen
216
-     * @return void
217
-     */
218
-    public function modify_pagenow($current_screen)
219
-    {
220
-        global $pagenow, $hook_suffix;
221
-        //possibly reset pagenow.
222
-        if ( ! empty($this->_req_data['page'])
223
-             && $this->_req_data['page'] == $this->page_slug
224
-             && ! empty($this->_req_data['action'])
225
-             && isset($this->_pagenow_map[$this->_req_data['action']])
226
-        ) {
227
-            $pagenow = $this->_pagenow_map[$this->_req_data['action']];
228
-            $hook_suffix = $pagenow;
229
-        }
230
-    }
231
-
232
-
233
-
234
-    /**
235
-     * This method is used to register additional autosave containers to the _autosave_containers property.
236
-     *
237
-     * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
238
-     *       automatically register the id for the post metabox as a container.
239
-     * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
240
-     *                    you would send along the id of a metabox container.
241
-     * @return void
242
-     */
243
-    protected function _register_autosave_containers($ids)
244
-    {
245
-        $this->_autosave_containers = array_merge($this->_autosave_fields, (array)$ids);
246
-    }
247
-
248
-
249
-
250
-    /**
251
-     * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
252
-     * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
253
-     */
254
-    protected function _set_autosave_containers()
255
-    {
256
-        global $wp_meta_boxes;
257
-        $containers = array();
258
-        if (empty($wp_meta_boxes)) {
259
-            return;
260
-        }
261
-        $current_metaboxes = isset($wp_meta_boxes[$this->page_slug]) ? $wp_meta_boxes[$this->page_slug] : array();
262
-        foreach ($current_metaboxes as $box_context) {
263
-            foreach ($box_context as $box_details) {
264
-                foreach ($box_details as $box) {
265
-                    if (
266
-                        is_array($box['callback'])
267
-                        && (
268
-                            $box['callback'][0] instanceof EE_Admin_Page
269
-                            || $box['callback'][0] instanceof EE_Admin_Hooks
270
-                        )
271
-                    ) {
272
-                        $containers[] = $box['id'];
273
-                    }
274
-                }
275
-            }
276
-        }
277
-        $this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
278
-        //add hidden inputs container
279
-        $this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
280
-    }
281
-
282
-
283
-
284
-    protected function _load_autosave_scripts_styles()
285
-    {
286
-        /*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
66
+	/**
67
+	 * This simply defines what the corresponding routes WP will be redirected to after completing a post save/update.
68
+	 * in this format:
69
+	 * array(
70
+	 * 'post_type_slug' => 'edit_route'
71
+	 * )
72
+	 *
73
+	 * @var array
74
+	 */
75
+	protected $_cpt_edit_routes = array();
76
+
77
+
78
+
79
+	/**
80
+	 * If child classes set the name of their main model via the $_cpt_obj_models property, EE_Admin_Page_CPT will
81
+	 * attempt to retrieve the related object model for the edit pages and assign it to _cpt_page_object. the
82
+	 * _cpt_model_names property should be in the following format: array(
83
+	 * 'route_defined_by_action_param' => 'Model_Name')
84
+	 *
85
+	 * @var array $_cpt_model_names
86
+	 */
87
+	protected $_cpt_model_names = array();
88
+
89
+
90
+	/**
91
+	 * @var EE_CPT_Base
92
+	 */
93
+	protected $_cpt_model_obj = false;
94
+
95
+
96
+
97
+	/**
98
+	 * This will hold an array of autosave containers that will be used to obtain input values and hook into the WP
99
+	 * autosave so we can save our inputs on the save_post hook!  Children classes should add to this array by using
100
+	 * the _register_autosave_containers() method so that we don't override any other containers already registered.
101
+	 * Registration of containers should be done before load_page_dependencies() is run.
102
+	 *
103
+	 * @var array()
104
+	 */
105
+	protected $_autosave_containers = array();
106
+	protected $_autosave_fields = array();
107
+
108
+	/**
109
+	 * Array mapping from admin actions to their equivalent wp core pages for custom post types. So when a user visits
110
+	 * a page for an action, it will appear as if they were visiting the wp core page for that custom post type
111
+	 *
112
+	 * @var array
113
+	 */
114
+	protected $_pagenow_map;
115
+
116
+
117
+
118
+	/**
119
+	 * This is hooked into the WordPress do_action('save_post') hook and runs after the custom post type has been
120
+	 * saved.  Child classes are required to declare this method.  Typically you would use this to save any additional
121
+	 * data. Keep in mind also that "save_post" runs on EVERY post update to the database. ALSO very important.  When a
122
+	 * post transitions from scheduled to published, the save_post action is fired but you will NOT have any _POST data
123
+	 * containing any extra info you may have from other meta saves.  So MAKE sure that you handle this accordingly.
124
+	 *
125
+	 * @access protected
126
+	 * @abstract
127
+	 * @param  string $post_id The ID of the cpt that was saved (so you can link relationally)
128
+	 * @param  EE_CPT_Base $post    The post object of the cpt that was saved.
129
+	 * @return void
130
+	 */
131
+	abstract protected function _insert_update_cpt_item($post_id, $post);
132
+
133
+
134
+
135
+	/**
136
+	 * This is hooked into the WordPress do_action('trashed_post') hook and runs after a cpt has been trashed.
137
+	 *
138
+	 * @abstract
139
+	 * @access public
140
+	 * @param  string $post_id The ID of the cpt that was trashed
141
+	 * @return void
142
+	 */
143
+	abstract public function trash_cpt_item($post_id);
144
+
145
+
146
+
147
+	/**
148
+	 * This is hooked into the WordPress do_action('untrashed_post') hook and runs after a cpt has been untrashed
149
+	 *
150
+	 * @param  string $post_id theID of the cpt that was untrashed
151
+	 * @return void
152
+	 */
153
+	abstract public function restore_cpt_item($post_id);
154
+
155
+
156
+
157
+	/**
158
+	 * This is hooked into the WordPress do_action('delete_cpt_item') hook and runs after a cpt has been fully deleted
159
+	 * from the db
160
+	 *
161
+	 * @param  string $post_id the ID of the cpt that was deleted
162
+	 * @return void
163
+	 */
164
+	abstract public function delete_cpt_item($post_id);
165
+
166
+
167
+
168
+	/**
169
+	 * Just utilizing the method EE_Admin exposes for doing things before page setup.
170
+	 *
171
+	 * @access protected
172
+	 * @return void
173
+	 */
174
+	protected function _before_page_setup()
175
+	{
176
+		$page = isset($this->_req_data['page']) ? $this->_req_data['page'] : $this->page_slug;
177
+		$this->_cpt_routes = array_merge(array(
178
+			'create_new' => $this->page_slug,
179
+			'edit'       => $this->page_slug,
180
+			'trash'      => $this->page_slug,
181
+		), $this->_cpt_routes);
182
+		//let's see if the current route has a value for cpt_object_slug if it does we use that instead of the page
183
+		$this->_cpt_object = isset($this->_req_data['action']) && isset($this->_cpt_routes[$this->_req_data['action']])
184
+			? get_post_type_object($this->_cpt_routes[$this->_req_data['action']])
185
+			: get_post_type_object($page);
186
+		//tweak pagenow for page loading.
187
+		if ( ! $this->_pagenow_map) {
188
+			$this->_pagenow_map = array(
189
+				'create_new' => 'post-new.php',
190
+				'edit'       => 'post.php',
191
+				'trash'      => 'post.php',
192
+			);
193
+		}
194
+		add_action('current_screen', array($this, 'modify_pagenow'));
195
+		//TODO the below will need to be reworked to account for the cpt routes that are NOT based off of page but action param.
196
+		//get current page from autosave
197
+		$current_page = isset($this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page'])
198
+			? $this->_req_data['ee_autosave_data']['ee-cpt-hidden-inputs']['current_page']
199
+			: null;
200
+		$this->_current_page = isset($this->_req_data['current_page'])
201
+			? $this->_req_data['current_page']
202
+			: $current_page;
203
+		//autosave... make sure its only for the correct page
204
+		//if ( ! empty($this->_current_page) && $this->_current_page == $this->page_slug) {
205
+			//setup autosave ajax hook
206
+			//add_action('wp_ajax_ee-autosave', array( $this, 'do_extra_autosave_stuff' ), 10 ); //TODO reactivate when 4.2 autosave is implemented
207
+		//}
208
+	}
209
+
210
+
211
+
212
+	/**
213
+	 * Simply ensure that we simulate the correct post route for cpt screens
214
+	 *
215
+	 * @param WP_Screen $current_screen
216
+	 * @return void
217
+	 */
218
+	public function modify_pagenow($current_screen)
219
+	{
220
+		global $pagenow, $hook_suffix;
221
+		//possibly reset pagenow.
222
+		if ( ! empty($this->_req_data['page'])
223
+			 && $this->_req_data['page'] == $this->page_slug
224
+			 && ! empty($this->_req_data['action'])
225
+			 && isset($this->_pagenow_map[$this->_req_data['action']])
226
+		) {
227
+			$pagenow = $this->_pagenow_map[$this->_req_data['action']];
228
+			$hook_suffix = $pagenow;
229
+		}
230
+	}
231
+
232
+
233
+
234
+	/**
235
+	 * This method is used to register additional autosave containers to the _autosave_containers property.
236
+	 *
237
+	 * @todo We should automate this at some point by creating a wrapper for add_post_metabox and in our wrapper we
238
+	 *       automatically register the id for the post metabox as a container.
239
+	 * @param  array $ids an array of ids for containers that hold form inputs we want autosave to pickup.  Typically
240
+	 *                    you would send along the id of a metabox container.
241
+	 * @return void
242
+	 */
243
+	protected function _register_autosave_containers($ids)
244
+	{
245
+		$this->_autosave_containers = array_merge($this->_autosave_fields, (array)$ids);
246
+	}
247
+
248
+
249
+
250
+	/**
251
+	 * Something nifty.  We're going to loop through all the registered metaboxes and if the CALLBACK is an instance of
252
+	 * EE_Admin_Page OR EE_Admin_Hooks, then we'll add the id to our _autosave_containers array.
253
+	 */
254
+	protected function _set_autosave_containers()
255
+	{
256
+		global $wp_meta_boxes;
257
+		$containers = array();
258
+		if (empty($wp_meta_boxes)) {
259
+			return;
260
+		}
261
+		$current_metaboxes = isset($wp_meta_boxes[$this->page_slug]) ? $wp_meta_boxes[$this->page_slug] : array();
262
+		foreach ($current_metaboxes as $box_context) {
263
+			foreach ($box_context as $box_details) {
264
+				foreach ($box_details as $box) {
265
+					if (
266
+						is_array($box['callback'])
267
+						&& (
268
+							$box['callback'][0] instanceof EE_Admin_Page
269
+							|| $box['callback'][0] instanceof EE_Admin_Hooks
270
+						)
271
+					) {
272
+						$containers[] = $box['id'];
273
+					}
274
+				}
275
+			}
276
+		}
277
+		$this->_autosave_containers = array_merge($this->_autosave_containers, $containers);
278
+		//add hidden inputs container
279
+		$this->_autosave_containers[] = 'ee-cpt-hidden-inputs';
280
+	}
281
+
282
+
283
+
284
+	protected function _load_autosave_scripts_styles()
285
+	{
286
+		/*wp_register_script('cpt-autosave', EE_ADMIN_URL . 'assets/ee-cpt-autosave.js', array('ee-serialize-full-array', 'event_editor_js'), EVENT_ESPRESSO_VERSION, TRUE );
287 287
         wp_enqueue_script('cpt-autosave');/**/ //todo re-enable when we start doing autosave again in 4.2
288 288
 
289
-        //filter _autosave_containers
290
-        $containers = apply_filters('FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
291
-            $this->_autosave_containers, $this);
292
-        $containers = apply_filters('FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
293
-            $containers, $this);
294
-
295
-        wp_localize_script('event_editor_js', 'EE_AUTOSAVE_IDS',
296
-            $containers); //todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
297
-
298
-        $unsaved_data_msg = array(
299
-            'eventmsg'     => sprintf(__("The changes you made to this %s will be lost if you navigate away from this page.",
300
-                'event_espresso'), $this->_cpt_object->labels->singular_name),
301
-            'inputChanged' => 0,
302
-        );
303
-        wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
304
-    }
305
-
306
-
307
-
308
-    public function load_page_dependencies()
309
-    {
310
-        try {
311
-            $this->_load_page_dependencies();
312
-        } catch (EE_Error $e) {
313
-            $e->get_error();
314
-        }
315
-    }
316
-
317
-
318
-
319
-    /**
320
-     * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
321
-     *
322
-     * @access protected
323
-     * @return void
324
-     */
325
-    protected function _load_page_dependencies()
326
-    {
327
-        //we only add stuff if this is a cpt_route!
328
-        if ( ! $this->_cpt_route) {
329
-            parent::_load_page_dependencies();
330
-            return;
331
-        }
332
-        // now let's do some automatic filters into the wp_system
333
-        // and we'll check to make sure the CHILD class
334
-        // automatically has the required methods in place.
335
-        // the following filters are for setting all the redirects
336
-        // on DEFAULT WP custom post type actions
337
-        // let's add a hidden input to the post-edit form
338
-        // so we know when we have to trigger our custom redirects!
339
-        // Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
340
-        add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
341
-        // inject our Admin page nav tabs...
342
-        // let's make sure the nav tabs are set if they aren't already
343
-        // if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
344
-        add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
345
-        // modify the post_updated messages array
346
-        add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
347
-        // add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
348
-        // cpts use the same format for shortlinks as posts!
349
-        add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
350
-        // This basically allows us to change the title of the "publish" metabox area
351
-        // on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
352
-        if ( ! empty($this->_labels['publishbox'])) {
353
-            $box_label = is_array($this->_labels['publishbox'])
354
-                         && isset($this->_labels['publishbox'][$this->_req_action])
355
-                    ? $this->_labels['publishbox'][$this->_req_action]
356
-                    : $this->_labels['publishbox'];
357
-            add_meta_box(
358
-                'submitdiv',
359
-                $box_label,
360
-                'post_submit_meta_box',
361
-                $this->_cpt_routes[$this->_req_action],
362
-                'side',
363
-                'core'
364
-            );
365
-        }
366
-        //let's add page_templates metabox if this cpt added support for it.
367
-        if ($this->_supports_page_templates($this->_cpt_object->name)) {
368
-            add_meta_box(
369
-                'page_templates',
370
-                __('Page Template', 'event_espresso'),
371
-                array($this, 'page_template_meta_box'),
372
-                $this->_cpt_routes[$this->_req_action],
373
-                'side',
374
-                'default'
375
-            );
376
-        }
377
-        //this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
378
-        if (method_exists($this, 'extra_permalink_field_buttons')) {
379
-            add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
380
-        }
381
-        //add preview button
382
-        add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
383
-        //insert our own post_stati dropdown
384
-        add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
385
-        //This allows adding additional information to the publish post submitbox on the wp post edit form
386
-        if (method_exists($this, 'extra_misc_actions_publish_box')) {
387
-            add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
388
-        }
389
-        // This allows for adding additional stuff after the title field on the wp post edit form.
390
-        // This is also before the wp_editor for post description field.
391
-        if (method_exists($this, 'edit_form_after_title')) {
392
-            add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
393
-        }
394
-        /**
395
-         * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
396
-         */
397
-        add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
398
-        parent::_load_page_dependencies();
399
-        // notice we are ALSO going to load the pagenow hook set for this route
400
-        // (see _before_page_setup for the reset of the pagenow global ).
401
-        // This is for any plugins that are doing things properly
402
-        // and hooking into the load page hook for core wp cpt routes.
403
-        global $pagenow;
404
-        do_action('load-' . $pagenow);
405
-        $this->modify_current_screen();
406
-        add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
407
-        //we route REALLY early.
408
-        try {
409
-            $this->_route_admin_request();
410
-        } catch (EE_Error $e) {
411
-            $e->get_error();
412
-        }
413
-    }
414
-
415
-
416
-
417
-    /**
418
-     * Since we don't want users going to default core wp routes, this will check any wp urls run through the
419
-     * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
420
-     * route instead.
421
-     *
422
-     * @param string $good_protocol_url The escaped url.
423
-     * @param string $original_url      The original url.
424
-     * @param string $_context          The context sent to the esc_url method.
425
-     * @return string possibly a new url for our route.
426
-     */
427
-    public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
428
-    {
429
-        $routes_to_match = array(
430
-            0 => array(
431
-                'edit.php?post_type=espresso_attendees',
432
-                'admin.php?page=espresso_registrations&action=contact_list',
433
-            ),
434
-            1 => array(
435
-                'edit.php?post_type=' . $this->_cpt_object->name,
436
-                'admin.php?page=' . $this->_cpt_object->name,
437
-            ),
438
-        );
439
-        foreach ($routes_to_match as $route_matches) {
440
-            if (strpos($good_protocol_url, $route_matches[0]) !== false) {
441
-                return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
442
-            }
443
-        }
444
-        return $good_protocol_url;
445
-    }
446
-
447
-
448
-    /**
449
-     * Determine whether the current cpt supports page templates or not.
450
-     *
451
-     * @since %VER%
452
-     * @param string $cpt_name The cpt slug we're checking on.
453
-     * @return bool True supported, false not.
454
-     * @throws InvalidArgumentException
455
-     * @throws InvalidDataTypeException
456
-     * @throws InvalidInterfaceException
457
-     */
458
-    private function _supports_page_templates($cpt_name)
459
-    {
460
-        /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
461
-        $custom_post_types = LoaderFactory::getLoader()->getShared(
462
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
463
-        );
464
-        $cpt_args = $custom_post_types->getDefinitions();
465
-        $cpt_args = isset($cpt_args[$cpt_name]) ? $cpt_args[$cpt_name]['args'] : array();
466
-        $cpt_has_support = ! empty($cpt_args['page_templates']);
467
-
468
-        //if the installed version of WP is > 4.7 we do some additional checks.
469
-        if (RecommendedVersions::compareWordPressVersion('4.7','>=')) {
470
-            $post_templates = wp_get_theme()->get_post_templates();
471
-            //if there are $post_templates for this cpt, then we return false for this method because
472
-            //that means we aren't going to load our page template manager and leave that up to the native
473
-            //cpt template manager.
474
-            $cpt_has_support = ! isset($post_templates[$cpt_name]) ? $cpt_has_support : false;
475
-        }
476
-
477
-        return $cpt_has_support;
478
-    }
479
-
480
-
481
-    /**
482
-     * Callback for the page_templates metabox selector.
483
-     *
484
-     * @since %VER%
485
-     * @return void
486
-     */
487
-    public function page_template_meta_box()
488
-    {
489
-        global $post;
490
-        $template = '';
491
-
492
-        if (RecommendedVersions::compareWordPressVersion('4.7','>=')) {
493
-            $page_template_count = count(get_page_templates());
494
-        } else {
495
-            $page_template_count = count(get_page_templates($post));
496
-        };
497
-
498
-        if ($page_template_count) {
499
-            $page_template = get_post_meta($post->ID, '_wp_page_template', true);
500
-            $template      = ! empty($page_template) ? $page_template : '';
501
-        }
502
-        ?>
289
+		//filter _autosave_containers
290
+		$containers = apply_filters('FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
291
+			$this->_autosave_containers, $this);
292
+		$containers = apply_filters('FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
293
+			$containers, $this);
294
+
295
+		wp_localize_script('event_editor_js', 'EE_AUTOSAVE_IDS',
296
+			$containers); //todo once we enable autosaves, this needs to be switched to localize with "cpt-autosave"
297
+
298
+		$unsaved_data_msg = array(
299
+			'eventmsg'     => sprintf(__("The changes you made to this %s will be lost if you navigate away from this page.",
300
+				'event_espresso'), $this->_cpt_object->labels->singular_name),
301
+			'inputChanged' => 0,
302
+		);
303
+		wp_localize_script('event_editor_js', 'UNSAVED_DATA_MSG', $unsaved_data_msg);
304
+	}
305
+
306
+
307
+
308
+	public function load_page_dependencies()
309
+	{
310
+		try {
311
+			$this->_load_page_dependencies();
312
+		} catch (EE_Error $e) {
313
+			$e->get_error();
314
+		}
315
+	}
316
+
317
+
318
+
319
+	/**
320
+	 * overloading the EE_Admin_Page parent load_page_dependencies so we can get the cpt stuff added in appropriately
321
+	 *
322
+	 * @access protected
323
+	 * @return void
324
+	 */
325
+	protected function _load_page_dependencies()
326
+	{
327
+		//we only add stuff if this is a cpt_route!
328
+		if ( ! $this->_cpt_route) {
329
+			parent::_load_page_dependencies();
330
+			return;
331
+		}
332
+		// now let's do some automatic filters into the wp_system
333
+		// and we'll check to make sure the CHILD class
334
+		// automatically has the required methods in place.
335
+		// the following filters are for setting all the redirects
336
+		// on DEFAULT WP custom post type actions
337
+		// let's add a hidden input to the post-edit form
338
+		// so we know when we have to trigger our custom redirects!
339
+		// Otherwise the redirects will happen on ALL post saves which wouldn't be good of course!
340
+		add_action('edit_form_after_title', array($this, 'cpt_post_form_hidden_input'));
341
+		// inject our Admin page nav tabs...
342
+		// let's make sure the nav tabs are set if they aren't already
343
+		// if ( empty( $this->_nav_tabs ) ) $this->_set_nav_tabs();
344
+		add_action('post_edit_form_tag', array($this, 'inject_nav_tabs'));
345
+		// modify the post_updated messages array
346
+		add_action('post_updated_messages', array($this, 'post_update_messages'), 10);
347
+		// add shortlink button to cpt edit screens.  We can do this as a universal thing BECAUSE,
348
+		// cpts use the same format for shortlinks as posts!
349
+		add_filter('pre_get_shortlink', array($this, 'add_shortlink_button_to_editor'), 10, 4);
350
+		// This basically allows us to change the title of the "publish" metabox area
351
+		// on CPT pages by setting a 'publishbox' value in the $_labels property array in the child class.
352
+		if ( ! empty($this->_labels['publishbox'])) {
353
+			$box_label = is_array($this->_labels['publishbox'])
354
+						 && isset($this->_labels['publishbox'][$this->_req_action])
355
+					? $this->_labels['publishbox'][$this->_req_action]
356
+					: $this->_labels['publishbox'];
357
+			add_meta_box(
358
+				'submitdiv',
359
+				$box_label,
360
+				'post_submit_meta_box',
361
+				$this->_cpt_routes[$this->_req_action],
362
+				'side',
363
+				'core'
364
+			);
365
+		}
366
+		//let's add page_templates metabox if this cpt added support for it.
367
+		if ($this->_supports_page_templates($this->_cpt_object->name)) {
368
+			add_meta_box(
369
+				'page_templates',
370
+				__('Page Template', 'event_espresso'),
371
+				array($this, 'page_template_meta_box'),
372
+				$this->_cpt_routes[$this->_req_action],
373
+				'side',
374
+				'default'
375
+			);
376
+		}
377
+		//this is a filter that allows the addition of extra html after the permalink field on the wp post edit-form
378
+		if (method_exists($this, 'extra_permalink_field_buttons')) {
379
+			add_filter('get_sample_permalink_html', array($this, 'extra_permalink_field_buttons'), 10, 4);
380
+		}
381
+		//add preview button
382
+		add_filter('get_sample_permalink_html', array($this, 'preview_button_html'), 5, 4);
383
+		//insert our own post_stati dropdown
384
+		add_action('post_submitbox_misc_actions', array($this, 'custom_post_stati_dropdown'), 10);
385
+		//This allows adding additional information to the publish post submitbox on the wp post edit form
386
+		if (method_exists($this, 'extra_misc_actions_publish_box')) {
387
+			add_action('post_submitbox_misc_actions', array($this, 'extra_misc_actions_publish_box'), 10);
388
+		}
389
+		// This allows for adding additional stuff after the title field on the wp post edit form.
390
+		// This is also before the wp_editor for post description field.
391
+		if (method_exists($this, 'edit_form_after_title')) {
392
+			add_action('edit_form_after_title', array($this, 'edit_form_after_title'), 10);
393
+		}
394
+		/**
395
+		 * Filtering WP's esc_url to capture urls pointing to core wp routes so they point to our route.
396
+		 */
397
+		add_filter('clean_url', array($this, 'switch_core_wp_urls_with_ours'), 10, 3);
398
+		parent::_load_page_dependencies();
399
+		// notice we are ALSO going to load the pagenow hook set for this route
400
+		// (see _before_page_setup for the reset of the pagenow global ).
401
+		// This is for any plugins that are doing things properly
402
+		// and hooking into the load page hook for core wp cpt routes.
403
+		global $pagenow;
404
+		do_action('load-' . $pagenow);
405
+		$this->modify_current_screen();
406
+		add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
407
+		//we route REALLY early.
408
+		try {
409
+			$this->_route_admin_request();
410
+		} catch (EE_Error $e) {
411
+			$e->get_error();
412
+		}
413
+	}
414
+
415
+
416
+
417
+	/**
418
+	 * Since we don't want users going to default core wp routes, this will check any wp urls run through the
419
+	 * esc_url() method and if we see a url matching a pattern for our routes, we'll modify it to point to OUR
420
+	 * route instead.
421
+	 *
422
+	 * @param string $good_protocol_url The escaped url.
423
+	 * @param string $original_url      The original url.
424
+	 * @param string $_context          The context sent to the esc_url method.
425
+	 * @return string possibly a new url for our route.
426
+	 */
427
+	public function switch_core_wp_urls_with_ours($good_protocol_url, $original_url, $_context)
428
+	{
429
+		$routes_to_match = array(
430
+			0 => array(
431
+				'edit.php?post_type=espresso_attendees',
432
+				'admin.php?page=espresso_registrations&action=contact_list',
433
+			),
434
+			1 => array(
435
+				'edit.php?post_type=' . $this->_cpt_object->name,
436
+				'admin.php?page=' . $this->_cpt_object->name,
437
+			),
438
+		);
439
+		foreach ($routes_to_match as $route_matches) {
440
+			if (strpos($good_protocol_url, $route_matches[0]) !== false) {
441
+				return str_replace($route_matches[0], $route_matches[1], $good_protocol_url);
442
+			}
443
+		}
444
+		return $good_protocol_url;
445
+	}
446
+
447
+
448
+	/**
449
+	 * Determine whether the current cpt supports page templates or not.
450
+	 *
451
+	 * @since %VER%
452
+	 * @param string $cpt_name The cpt slug we're checking on.
453
+	 * @return bool True supported, false not.
454
+	 * @throws InvalidArgumentException
455
+	 * @throws InvalidDataTypeException
456
+	 * @throws InvalidInterfaceException
457
+	 */
458
+	private function _supports_page_templates($cpt_name)
459
+	{
460
+		/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
461
+		$custom_post_types = LoaderFactory::getLoader()->getShared(
462
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
463
+		);
464
+		$cpt_args = $custom_post_types->getDefinitions();
465
+		$cpt_args = isset($cpt_args[$cpt_name]) ? $cpt_args[$cpt_name]['args'] : array();
466
+		$cpt_has_support = ! empty($cpt_args['page_templates']);
467
+
468
+		//if the installed version of WP is > 4.7 we do some additional checks.
469
+		if (RecommendedVersions::compareWordPressVersion('4.7','>=')) {
470
+			$post_templates = wp_get_theme()->get_post_templates();
471
+			//if there are $post_templates for this cpt, then we return false for this method because
472
+			//that means we aren't going to load our page template manager and leave that up to the native
473
+			//cpt template manager.
474
+			$cpt_has_support = ! isset($post_templates[$cpt_name]) ? $cpt_has_support : false;
475
+		}
476
+
477
+		return $cpt_has_support;
478
+	}
479
+
480
+
481
+	/**
482
+	 * Callback for the page_templates metabox selector.
483
+	 *
484
+	 * @since %VER%
485
+	 * @return void
486
+	 */
487
+	public function page_template_meta_box()
488
+	{
489
+		global $post;
490
+		$template = '';
491
+
492
+		if (RecommendedVersions::compareWordPressVersion('4.7','>=')) {
493
+			$page_template_count = count(get_page_templates());
494
+		} else {
495
+			$page_template_count = count(get_page_templates($post));
496
+		};
497
+
498
+		if ($page_template_count) {
499
+			$page_template = get_post_meta($post->ID, '_wp_page_template', true);
500
+			$template      = ! empty($page_template) ? $page_template : '';
501
+		}
502
+		?>
503 503
         <p><strong><?php _e('Template') ?></strong></p>
504 504
         <label class="screen-reader-text" for="page_template"><?php _e('Page Template') ?></label><select
505 505
             name="page_template" id="page_template">
@@ -507,457 +507,457 @@  discard block
 block discarded – undo
507 507
         <?php page_template_dropdown($template); ?>
508 508
     </select>
509 509
         <?php
510
-    }
511
-
512
-
513
-
514
-    /**
515
-     * if this post is a draft or scheduled post then we provide a preview button for user to click
516
-     * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
517
-     *
518
-     * @param  string $return    the current html
519
-     * @param  int    $id        the post id for the page
520
-     * @param  string $new_title What the title is
521
-     * @param  string $new_slug  what the slug is
522
-     * @return string            The new html string for the permalink area
523
-     */
524
-    public function preview_button_html($return, $id, $new_title, $new_slug)
525
-    {
526
-        $post = get_post($id);
527
-        if ('publish' !== get_post_status($post)) {
528
-            //include shims for the `get_preview_post_link` function
529
-            require_once( EE_CORE . 'wordpress-shims.php' );
530
-            $return .= '<span_id="view-post-btn"><a target="_blank" href="'
531
-                       . get_preview_post_link($id)
532
-                       . '" class="button button-small">'
533
-                       . __('Preview', 'event_espresso')
534
-                       . '</a></span>'
535
-                       . "\n";
536
-        }
537
-        return $return;
538
-    }
539
-
540
-
541
-
542
-    /**
543
-     * add our custom post stati dropdown on the wp post page for this cpt
544
-     *
545
-     * @return void
546
-     */
547
-    public function custom_post_stati_dropdown()
548
-    {
549
-
550
-        $statuses         = $this->_cpt_model_obj->get_custom_post_statuses();
551
-        $cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
552
-            ? $statuses[$this->_cpt_model_obj->status()]
553
-            : '';
554
-        $template_args    = array(
555
-            'cur_status'            => $this->_cpt_model_obj->status(),
556
-            'statuses'              => $statuses,
557
-            'cur_status_label'      => $cur_status_label,
558
-            'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
559
-        );
560
-        //we'll add a trash post status (WP doesn't add one for some reason)
561
-        if ($this->_cpt_model_obj->status() === 'trash') {
562
-            $template_args['cur_status_label'] = __('Trashed', 'event_espresso');
563
-            $statuses['trash']                 = __('Trashed', 'event_espresso');
564
-            $template_args['statuses']         = $statuses;
565
-        }
566
-
567
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
568
-        EEH_Template::display_template($template, $template_args);
569
-    }
570
-
571
-
572
-
573
-    public function setup_autosave_hooks()
574
-    {
575
-        $this->_set_autosave_containers();
576
-        $this->_load_autosave_scripts_styles();
577
-    }
578
-
579
-
580
-
581
-    /**
582
-     * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
583
-     * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
584
-     * for the nonce in here, but then this method looks for two things:
585
-     * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
586
-     * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
587
-     * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
588
-     * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
589
-     * template args.
590
-     *    1. $template_args['error'] = IF there is an error you can add the message in here.
591
-     *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
592
-     *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
593
-     *    $this->_template_args['data']['items'] = array(
594
-     *        'event-datetime-ids' => '1,2,3';
595
-     *    );
596
-     *    Keep in mind the following things:
597
-     *    - "where" index is for the input with the id as that string.
598
-     *    - "what" index is what will be used for the value of that input.
599
-     *
600
-     * @return void
601
-     */
602
-    public function do_extra_autosave_stuff()
603
-    {
604
-        //next let's check for the autosave nonce (we'll use _verify_nonce )
605
-        $nonce = isset($this->_req_data['autosavenonce'])
606
-                ? $this->_req_data['autosavenonce']
607
-                : null;
608
-        $this->_verify_nonce($nonce, 'autosave');
609
-        //make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
610
-        if ( ! defined('DOING_AUTOSAVE')) {
611
-            define('DOING_AUTOSAVE', true);
612
-        }
613
-        //if we made it here then the nonce checked out.  Let's run our methods and actions
614
-        $autosave = "_ee_autosave_{$this->_current_view}";
615
-        if (method_exists($this, $autosave)) {
616
-            $this->$autosave();
617
-        } else {
618
-            $this->_template_args['success'] = true;
619
-        }
620
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
621
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
622
-        //now let's return json
623
-        $this->_return_json();
624
-    }
625
-
626
-
627
-
628
-    /**
629
-     * This takes care of setting up default routes and pages that utilize the core WP admin pages.
630
-     * Child classes can override the defaults (in cases for adding metaboxes etc.)
631
-     * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
632
-     *
633
-     * @access protected
634
-     * @throws EE_Error
635
-     * @return void
636
-     */
637
-    protected function _extend_page_config_for_cpt()
638
-    {
639
-        //before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
640
-        if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
641
-            return;
642
-        }
643
-        //set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
644
-        if ( ! empty($this->_cpt_object)) {
645
-            $this->_page_routes = array_merge(array(
646
-                'create_new' => '_create_new_cpt_item',
647
-                'edit'       => '_edit_cpt_item',
648
-            ), $this->_page_routes);
649
-            $this->_page_config = array_merge(array(
650
-                'create_new' => array(
651
-                    'nav'           => array(
652
-                        'label' => $this->_cpt_object->labels->add_new_item,
653
-                        'order' => 5,
654
-                    ),
655
-                    'require_nonce' => false,
656
-                ),
657
-                'edit'       => array(
658
-                    'nav'           => array(
659
-                        'label'      => $this->_cpt_object->labels->edit_item,
660
-                        'order'      => 5,
661
-                        'persistent' => false,
662
-                        'url'        => '',
663
-                    ),
664
-                    'require_nonce' => false,
665
-                ),
666
-            ),
667
-                $this->_page_config
668
-            );
669
-        }
670
-        //load the next section only if this is a matching cpt route as set in the cpt routes array.
671
-        if ( ! isset($this->_cpt_routes[$this->_req_action])) {
672
-            return;
673
-        }
674
-        $this->_cpt_route = isset($this->_cpt_routes[$this->_req_action]) ? true : false;
675
-        //add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
676
-        if (empty($this->_cpt_object)) {
677
-            $msg = sprintf(__('This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).'),
678
-                $this->page_slug, $this->_req_action, get_class($this));
679
-            throw new EE_Error($msg);
680
-        }
681
-        if ($this->_cpt_route) {
682
-            $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
683
-            $this->_set_model_object($id);
684
-        }
685
-    }
686
-
687
-
688
-    /**
689
-     * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
690
-     *
691
-     * @access protected
692
-     * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
693
-     * @param bool   $ignore_route_check
694
-     * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
695
-     * @throws EE_Error
696
-     * @throws InvalidArgumentException
697
-     * @throws InvalidDataTypeException
698
-     * @throws InvalidInterfaceException
699
-     * @throws ReflectionException
700
-     */
701
-    protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
702
-    {
703
-        $model = null;
704
-        if (
705
-            empty($this->_cpt_model_names)
706
-            || (
707
-                ! $ignore_route_check
708
-                && ! isset($this->_cpt_routes[$this->_req_action])
709
-            ) || (
710
-                $this->_cpt_model_obj instanceof EE_CPT_Base
711
-                && $this->_cpt_model_obj->ID() === $id
712
-            )
713
-        ) {
714
-            //get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
715
-            return;
716
-        }
717
-        // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
718
-        if ($ignore_route_check) {
719
-            $post_type   = get_post_type($id);
720
-            /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
721
-            $custom_post_types = LoaderFactory::getLoader()->getShared(
722
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
723
-            );
724
-            $model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
725
-            if (isset($model_names[$post_type])) {
726
-                $model = EE_Registry::instance()->load_model($model_names[$post_type]);
727
-            }
728
-        } else {
729
-            $model = EE_Registry::instance()->load_model($this->_cpt_model_names[$this->_req_action]);
730
-        }
731
-        if ($model instanceof EEM_Base) {
732
-            $this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
733
-        }
734
-        do_action(
735
-            'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
736
-            $this->_cpt_model_obj,
737
-            $req_type
738
-        );
739
-    }
740
-
741
-
742
-
743
-    /**
744
-     * admin_init_global
745
-     * This runs all the code that we want executed within the WP admin_init hook.
746
-     * This method executes for ALL EE Admin pages.
747
-     *
748
-     * @access public
749
-     * @return void
750
-     */
751
-    public function admin_init_global()
752
-    {
753
-        $post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
754
-        //its possible this is a new save so let's catch that instead
755
-        $post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
756
-        $post_type = $post ? $post->post_type : false;
757
-        $current_route = isset($this->_req_data['current_route'])
758
-            ? $this->_req_data['current_route']
759
-            : 'shouldneverwork';
760
-        $route_to_check = $post_type && isset($this->_cpt_routes[$current_route])
761
-            ? $this->_cpt_routes[$current_route]
762
-            : '';
763
-        add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
764
-        add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
765
-        if ($post_type === $route_to_check) {
766
-            add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
767
-        }
768
-        //now let's filter redirect if we're on a revision page and the revision is for an event CPT.
769
-        $revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
770
-        if ( ! empty($revision)) {
771
-            $action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
772
-            //doing a restore?
773
-            if ( ! empty($action) && $action === 'restore') {
774
-                //get post for revision
775
-                $rev_post = get_post($revision);
776
-                $rev_parent = get_post($rev_post->post_parent);
777
-                //only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
778
-                if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
779
-                    add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
780
-                    //restores of revisions
781
-                    add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
782
-                }
783
-            }
784
-        }
785
-        //NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
786
-        if ($post_type && $post_type === $route_to_check) {
787
-            //$post_id, $post
788
-            add_action('save_post', array($this, 'insert_update'), 10, 3);
789
-            //$post_id
790
-            add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
791
-            add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
792
-            add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
793
-            add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
794
-        }
795
-    }
796
-
797
-
798
-
799
-    /**
800
-     * Callback for the WordPress trashed_post hook.
801
-     * Execute some basic checks before calling the trash_cpt_item declared in the child class.
802
-     *
803
-     * @param int $post_id
804
-     * @throws \EE_Error
805
-     */
806
-    public function before_trash_cpt_item($post_id)
807
-    {
808
-        $this->_set_model_object($post_id, true, 'trash');
809
-        //if our cpt object isn't existent then get out immediately.
810
-        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
811
-            return;
812
-        }
813
-        $this->trash_cpt_item($post_id);
814
-    }
815
-
816
-
817
-
818
-    /**
819
-     * Callback for the WordPress untrashed_post hook.
820
-     * Execute some basic checks before calling the restore_cpt_method in the child class.
821
-     *
822
-     * @param $post_id
823
-     * @throws \EE_Error
824
-     */
825
-    public function before_restore_cpt_item($post_id)
826
-    {
827
-        $this->_set_model_object($post_id, true, 'restore');
828
-        //if our cpt object isn't existent then get out immediately.
829
-        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
830
-            return;
831
-        }
832
-        $this->restore_cpt_item($post_id);
833
-    }
834
-
835
-
836
-
837
-    /**
838
-     * Callback for the WordPress after_delete_post hook.
839
-     * Execute some basic checks before calling the delete_cpt_item method in the child class.
840
-     *
841
-     * @param $post_id
842
-     * @throws \EE_Error
843
-     */
844
-    public function before_delete_cpt_item($post_id)
845
-    {
846
-        $this->_set_model_object($post_id, true, 'delete');
847
-        //if our cpt object isn't existent then get out immediately.
848
-        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
849
-            return;
850
-        }
851
-        $this->delete_cpt_item($post_id);
852
-    }
853
-
854
-
855
-
856
-    /**
857
-     * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
858
-     * accordingly.
859
-     *
860
-     * @access public
861
-     * @throws EE_Error
862
-     * @return void
863
-     */
864
-    public function verify_cpt_object()
865
-    {
866
-        $label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
867
-        // verify event object
868
-        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
869
-            throw new EE_Error(sprintf(__('Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
870
-                    'event_espresso'), $label));
871
-        }
872
-        //if auto-draft then throw an error
873
-        if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
874
-            EE_Error::overwrite_errors();
875
-            EE_Error::add_error(sprintf(__('This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.'),
876
-                    $label), __FILE__, __FUNCTION__, __LINE__);
877
-        }
878
-    }
879
-
880
-
881
-
882
-    /**
883
-     * admin_footer_scripts_global
884
-     * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
885
-     * will apply on ALL EE_Admin pages.
886
-     *
887
-     * @access public
888
-     * @return void
889
-     */
890
-    public function admin_footer_scripts_global()
891
-    {
892
-        $this->_add_admin_page_ajax_loading_img();
893
-        $this->_add_admin_page_overlay();
894
-    }
895
-
896
-
897
-
898
-    /**
899
-     * add in any global scripts for cpt routes
900
-     *
901
-     * @return void
902
-     */
903
-    public function load_global_scripts_styles()
904
-    {
905
-        parent::load_global_scripts_styles();
906
-        if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
907
-            //setup custom post status object for localize script but only if we've got a cpt object
908
-            $statuses = $this->_cpt_model_obj->get_custom_post_statuses();
909
-            if ( ! empty($statuses)) {
910
-                //get ALL statuses!
911
-                $statuses = $this->_cpt_model_obj->get_all_post_statuses();
912
-                //setup object
913
-                $ee_cpt_statuses = array();
914
-                foreach ($statuses as $status => $label) {
915
-                    $ee_cpt_statuses[$status] = array(
916
-                        'label'      => $label,
917
-                        'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
918
-                    );
919
-                }
920
-                wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
921
-            }
922
-        }
923
-    }
924
-
925
-
926
-
927
-    /**
928
-     * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
929
-     * insert/updates
930
-     *
931
-     * @param  int     $post_id ID of post being updated
932
-     * @param  WP_Post $post    Post object from WP
933
-     * @param  bool    $update  Whether this is an update or a new save.
934
-     * @return void
935
-     * @throws \EE_Error
936
-     */
937
-    public function insert_update($post_id, $post, $update)
938
-    {
939
-        //make sure that if this is a revision OR trash action that we don't do any updates!
940
-        if (
941
-            isset($this->_req_data['action'])
942
-            && (
943
-                $this->_req_data['action'] === 'restore'
944
-                || $this->_req_data['action'] === 'trash'
945
-            )
946
-        ) {
947
-            return;
948
-        }
949
-        $this->_set_model_object($post_id, true, 'insert_update');
950
-        //if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
951
-        if ($update
952
-            && (
953
-                ! $this->_cpt_model_obj instanceof EE_CPT_Base
954
-                || $this->_cpt_model_obj->ID() !== $post_id
955
-            )
956
-        ) {
957
-            return;
958
-        }
959
-        //check for autosave and update our req_data property accordingly.
960
-        /*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
510
+	}
511
+
512
+
513
+
514
+	/**
515
+	 * if this post is a draft or scheduled post then we provide a preview button for user to click
516
+	 * Method is called from parent and is hooked into the wp 'get_sample_permalink_html' filter.
517
+	 *
518
+	 * @param  string $return    the current html
519
+	 * @param  int    $id        the post id for the page
520
+	 * @param  string $new_title What the title is
521
+	 * @param  string $new_slug  what the slug is
522
+	 * @return string            The new html string for the permalink area
523
+	 */
524
+	public function preview_button_html($return, $id, $new_title, $new_slug)
525
+	{
526
+		$post = get_post($id);
527
+		if ('publish' !== get_post_status($post)) {
528
+			//include shims for the `get_preview_post_link` function
529
+			require_once( EE_CORE . 'wordpress-shims.php' );
530
+			$return .= '<span_id="view-post-btn"><a target="_blank" href="'
531
+					   . get_preview_post_link($id)
532
+					   . '" class="button button-small">'
533
+					   . __('Preview', 'event_espresso')
534
+					   . '</a></span>'
535
+					   . "\n";
536
+		}
537
+		return $return;
538
+	}
539
+
540
+
541
+
542
+	/**
543
+	 * add our custom post stati dropdown on the wp post page for this cpt
544
+	 *
545
+	 * @return void
546
+	 */
547
+	public function custom_post_stati_dropdown()
548
+	{
549
+
550
+		$statuses         = $this->_cpt_model_obj->get_custom_post_statuses();
551
+		$cur_status_label = array_key_exists($this->_cpt_model_obj->status(), $statuses)
552
+			? $statuses[$this->_cpt_model_obj->status()]
553
+			: '';
554
+		$template_args    = array(
555
+			'cur_status'            => $this->_cpt_model_obj->status(),
556
+			'statuses'              => $statuses,
557
+			'cur_status_label'      => $cur_status_label,
558
+			'localized_status_save' => sprintf(__('Save %s', 'event_espresso'), $cur_status_label),
559
+		);
560
+		//we'll add a trash post status (WP doesn't add one for some reason)
561
+		if ($this->_cpt_model_obj->status() === 'trash') {
562
+			$template_args['cur_status_label'] = __('Trashed', 'event_espresso');
563
+			$statuses['trash']                 = __('Trashed', 'event_espresso');
564
+			$template_args['statuses']         = $statuses;
565
+		}
566
+
567
+		$template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
568
+		EEH_Template::display_template($template, $template_args);
569
+	}
570
+
571
+
572
+
573
+	public function setup_autosave_hooks()
574
+	{
575
+		$this->_set_autosave_containers();
576
+		$this->_load_autosave_scripts_styles();
577
+	}
578
+
579
+
580
+
581
+	/**
582
+	 * This is run on all WordPress autosaves AFTER the autosave is complete and sends along a $_POST object (available
583
+	 * in $this->_req_data) containing: post_ID of the saved post autosavenonce for the saved post We'll do the check
584
+	 * for the nonce in here, but then this method looks for two things:
585
+	 * 1. Execute a method (if exists) matching 'ee_autosave_' and appended with the given route. OR
586
+	 * 2. do_actions() for global or class specific actions that have been registered (for plugins/addons not in an
587
+	 * EE_Admin_Page class. PLEASE NOTE: Data will be returned using the _return_json() object and so the
588
+	 * $_template_args property should be used to hold the $data array.  We're expecting the following things set in
589
+	 * template args.
590
+	 *    1. $template_args['error'] = IF there is an error you can add the message in here.
591
+	 *    2. $template_args['data']['items'] = an array of items that are setup in key index pairs of 'where_values_go'
592
+	 *    => 'values_to_add'.  In other words, for the datetime metabox we'll have something like
593
+	 *    $this->_template_args['data']['items'] = array(
594
+	 *        'event-datetime-ids' => '1,2,3';
595
+	 *    );
596
+	 *    Keep in mind the following things:
597
+	 *    - "where" index is for the input with the id as that string.
598
+	 *    - "what" index is what will be used for the value of that input.
599
+	 *
600
+	 * @return void
601
+	 */
602
+	public function do_extra_autosave_stuff()
603
+	{
604
+		//next let's check for the autosave nonce (we'll use _verify_nonce )
605
+		$nonce = isset($this->_req_data['autosavenonce'])
606
+				? $this->_req_data['autosavenonce']
607
+				: null;
608
+		$this->_verify_nonce($nonce, 'autosave');
609
+		//make sure we define doing autosave (cause WP isn't triggering this we want to make sure we define it)
610
+		if ( ! defined('DOING_AUTOSAVE')) {
611
+			define('DOING_AUTOSAVE', true);
612
+		}
613
+		//if we made it here then the nonce checked out.  Let's run our methods and actions
614
+		$autosave = "_ee_autosave_{$this->_current_view}";
615
+		if (method_exists($this, $autosave)) {
616
+			$this->$autosave();
617
+		} else {
618
+			$this->_template_args['success'] = true;
619
+		}
620
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
621
+		do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
622
+		//now let's return json
623
+		$this->_return_json();
624
+	}
625
+
626
+
627
+
628
+	/**
629
+	 * This takes care of setting up default routes and pages that utilize the core WP admin pages.
630
+	 * Child classes can override the defaults (in cases for adding metaboxes etc.)
631
+	 * but take care that you include the defaults here otherwise your core WP admin pages for the cpt won't work!
632
+	 *
633
+	 * @access protected
634
+	 * @throws EE_Error
635
+	 * @return void
636
+	 */
637
+	protected function _extend_page_config_for_cpt()
638
+	{
639
+		//before doing anything we need to make sure this runs ONLY when the loaded page matches the set page_slug
640
+		if (isset($this->_req_data['page']) && $this->_req_data['page'] !== $this->page_slug) {
641
+			return;
642
+		}
643
+		//set page routes and page config but ONLY if we're not viewing a custom setup cpt route as defined in _cpt_routes
644
+		if ( ! empty($this->_cpt_object)) {
645
+			$this->_page_routes = array_merge(array(
646
+				'create_new' => '_create_new_cpt_item',
647
+				'edit'       => '_edit_cpt_item',
648
+			), $this->_page_routes);
649
+			$this->_page_config = array_merge(array(
650
+				'create_new' => array(
651
+					'nav'           => array(
652
+						'label' => $this->_cpt_object->labels->add_new_item,
653
+						'order' => 5,
654
+					),
655
+					'require_nonce' => false,
656
+				),
657
+				'edit'       => array(
658
+					'nav'           => array(
659
+						'label'      => $this->_cpt_object->labels->edit_item,
660
+						'order'      => 5,
661
+						'persistent' => false,
662
+						'url'        => '',
663
+					),
664
+					'require_nonce' => false,
665
+				),
666
+			),
667
+				$this->_page_config
668
+			);
669
+		}
670
+		//load the next section only if this is a matching cpt route as set in the cpt routes array.
671
+		if ( ! isset($this->_cpt_routes[$this->_req_action])) {
672
+			return;
673
+		}
674
+		$this->_cpt_route = isset($this->_cpt_routes[$this->_req_action]) ? true : false;
675
+		//add_action('FHEE__EE_Admin_Page___load_page_dependencies__after_load', array( $this, 'modify_current_screen') );
676
+		if (empty($this->_cpt_object)) {
677
+			$msg = sprintf(__('This page has been set as being related to a registered custom post type, however, the custom post type object could not be retrieved. There are two possible reasons for this:  1. The "%s" does not match a registered post type. or 2. The custom post type is not registered for the "%s" action as indexed in the "$_cpt_routes" property on this class (%s).'),
678
+				$this->page_slug, $this->_req_action, get_class($this));
679
+			throw new EE_Error($msg);
680
+		}
681
+		if ($this->_cpt_route) {
682
+			$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
683
+			$this->_set_model_object($id);
684
+		}
685
+	}
686
+
687
+
688
+	/**
689
+	 * Sets the _cpt_model_object property using what has been set for the _cpt_model_name and a given id.
690
+	 *
691
+	 * @access protected
692
+	 * @param int    $id       The id to retrieve the model object for. If empty we set a default object.
693
+	 * @param bool   $ignore_route_check
694
+	 * @param string $req_type whether the current route is for inserting, updating, or deleting the CPT
695
+	 * @throws EE_Error
696
+	 * @throws InvalidArgumentException
697
+	 * @throws InvalidDataTypeException
698
+	 * @throws InvalidInterfaceException
699
+	 * @throws ReflectionException
700
+	 */
701
+	protected function _set_model_object($id = null, $ignore_route_check = false, $req_type = '')
702
+	{
703
+		$model = null;
704
+		if (
705
+			empty($this->_cpt_model_names)
706
+			|| (
707
+				! $ignore_route_check
708
+				&& ! isset($this->_cpt_routes[$this->_req_action])
709
+			) || (
710
+				$this->_cpt_model_obj instanceof EE_CPT_Base
711
+				&& $this->_cpt_model_obj->ID() === $id
712
+			)
713
+		) {
714
+			//get out cuz we either don't have a model name OR the object has already been set and it has the same id as what has been sent.
715
+			return;
716
+		}
717
+		// if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
718
+		if ($ignore_route_check) {
719
+			$post_type   = get_post_type($id);
720
+			/** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
721
+			$custom_post_types = LoaderFactory::getLoader()->getShared(
722
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
723
+			);
724
+			$model_names = $custom_post_types->getCustomPostTypeModelNames($post_type);
725
+			if (isset($model_names[$post_type])) {
726
+				$model = EE_Registry::instance()->load_model($model_names[$post_type]);
727
+			}
728
+		} else {
729
+			$model = EE_Registry::instance()->load_model($this->_cpt_model_names[$this->_req_action]);
730
+		}
731
+		if ($model instanceof EEM_Base) {
732
+			$this->_cpt_model_obj = ! empty($id) ? $model->get_one_by_ID($id) : $model->create_default_object();
733
+		}
734
+		do_action(
735
+			'AHEE__EE_Admin_Page_CPT__set_model_object__after_set_object',
736
+			$this->_cpt_model_obj,
737
+			$req_type
738
+		);
739
+	}
740
+
741
+
742
+
743
+	/**
744
+	 * admin_init_global
745
+	 * This runs all the code that we want executed within the WP admin_init hook.
746
+	 * This method executes for ALL EE Admin pages.
747
+	 *
748
+	 * @access public
749
+	 * @return void
750
+	 */
751
+	public function admin_init_global()
752
+	{
753
+		$post = isset($this->_req_data['post']) ? get_post($this->_req_data['post']) : null;
754
+		//its possible this is a new save so let's catch that instead
755
+		$post = isset($this->_req_data['post_ID']) ? get_post($this->_req_data['post_ID']) : $post;
756
+		$post_type = $post ? $post->post_type : false;
757
+		$current_route = isset($this->_req_data['current_route'])
758
+			? $this->_req_data['current_route']
759
+			: 'shouldneverwork';
760
+		$route_to_check = $post_type && isset($this->_cpt_routes[$current_route])
761
+			? $this->_cpt_routes[$current_route]
762
+			: '';
763
+		add_filter('get_delete_post_link', array($this, 'modify_delete_post_link'), 10, 3);
764
+		add_filter('get_edit_post_link', array($this, 'modify_edit_post_link'), 10, 3);
765
+		if ($post_type === $route_to_check) {
766
+			add_filter('redirect_post_location', array($this, 'cpt_post_location_redirect'), 10, 2);
767
+		}
768
+		//now let's filter redirect if we're on a revision page and the revision is for an event CPT.
769
+		$revision = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
770
+		if ( ! empty($revision)) {
771
+			$action = isset($this->_req_data['action']) ? $this->_req_data['action'] : null;
772
+			//doing a restore?
773
+			if ( ! empty($action) && $action === 'restore') {
774
+				//get post for revision
775
+				$rev_post = get_post($revision);
776
+				$rev_parent = get_post($rev_post->post_parent);
777
+				//only do our redirect filter AND our restore revision action if the post_type for the parent is one of our cpts.
778
+				if ($rev_parent && $rev_parent->post_type === $this->page_slug) {
779
+					add_filter('wp_redirect', array($this, 'revision_redirect'), 10, 2);
780
+					//restores of revisions
781
+					add_action('wp_restore_post_revision', array($this, 'restore_revision'), 10, 2);
782
+				}
783
+			}
784
+		}
785
+		//NOTE we ONLY want to run these hooks if we're on the right class for the given post type.  Otherwise we could see some really freaky things happen!
786
+		if ($post_type && $post_type === $route_to_check) {
787
+			//$post_id, $post
788
+			add_action('save_post', array($this, 'insert_update'), 10, 3);
789
+			//$post_id
790
+			add_action('trashed_post', array($this, 'before_trash_cpt_item'), 10);
791
+			add_action('trashed_post', array($this, 'dont_permanently_delete_ee_cpts'), 10);
792
+			add_action('untrashed_post', array($this, 'before_restore_cpt_item'), 10);
793
+			add_action('after_delete_post', array($this, 'before_delete_cpt_item'), 10);
794
+		}
795
+	}
796
+
797
+
798
+
799
+	/**
800
+	 * Callback for the WordPress trashed_post hook.
801
+	 * Execute some basic checks before calling the trash_cpt_item declared in the child class.
802
+	 *
803
+	 * @param int $post_id
804
+	 * @throws \EE_Error
805
+	 */
806
+	public function before_trash_cpt_item($post_id)
807
+	{
808
+		$this->_set_model_object($post_id, true, 'trash');
809
+		//if our cpt object isn't existent then get out immediately.
810
+		if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
811
+			return;
812
+		}
813
+		$this->trash_cpt_item($post_id);
814
+	}
815
+
816
+
817
+
818
+	/**
819
+	 * Callback for the WordPress untrashed_post hook.
820
+	 * Execute some basic checks before calling the restore_cpt_method in the child class.
821
+	 *
822
+	 * @param $post_id
823
+	 * @throws \EE_Error
824
+	 */
825
+	public function before_restore_cpt_item($post_id)
826
+	{
827
+		$this->_set_model_object($post_id, true, 'restore');
828
+		//if our cpt object isn't existent then get out immediately.
829
+		if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
830
+			return;
831
+		}
832
+		$this->restore_cpt_item($post_id);
833
+	}
834
+
835
+
836
+
837
+	/**
838
+	 * Callback for the WordPress after_delete_post hook.
839
+	 * Execute some basic checks before calling the delete_cpt_item method in the child class.
840
+	 *
841
+	 * @param $post_id
842
+	 * @throws \EE_Error
843
+	 */
844
+	public function before_delete_cpt_item($post_id)
845
+	{
846
+		$this->_set_model_object($post_id, true, 'delete');
847
+		//if our cpt object isn't existent then get out immediately.
848
+		if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base || $this->_cpt_model_obj->ID() !== $post_id) {
849
+			return;
850
+		}
851
+		$this->delete_cpt_item($post_id);
852
+	}
853
+
854
+
855
+
856
+	/**
857
+	 * This simply verifies if the cpt_model_object is instantiated for the given page and throws an error message
858
+	 * accordingly.
859
+	 *
860
+	 * @access public
861
+	 * @throws EE_Error
862
+	 * @return void
863
+	 */
864
+	public function verify_cpt_object()
865
+	{
866
+		$label = ! empty($this->_cpt_object) ? $this->_cpt_object->labels->singular_name : $this->page_label;
867
+		// verify event object
868
+		if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
869
+			throw new EE_Error(sprintf(__('Something has gone wrong with the page load because we are unable to set up the object for the %1$s.  This usually happens when the given id for the page route is NOT for the correct custom post type for this page',
870
+					'event_espresso'), $label));
871
+		}
872
+		//if auto-draft then throw an error
873
+		if ($this->_cpt_model_obj->get('status') === 'auto-draft') {
874
+			EE_Error::overwrite_errors();
875
+			EE_Error::add_error(sprintf(__('This %1$s was saved without a title, description, or excerpt which means that none of the extra details you added were saved properly.  All autodrafts will show up in the "draft" view of your event list table.  You can delete them from there. Please click the "Add %1$s" button to refresh and restart.'),
876
+					$label), __FILE__, __FUNCTION__, __LINE__);
877
+		}
878
+	}
879
+
880
+
881
+
882
+	/**
883
+	 * admin_footer_scripts_global
884
+	 * Anything triggered by the 'admin_print_footer_scripts' WP hook should be put in here. This particular method
885
+	 * will apply on ALL EE_Admin pages.
886
+	 *
887
+	 * @access public
888
+	 * @return void
889
+	 */
890
+	public function admin_footer_scripts_global()
891
+	{
892
+		$this->_add_admin_page_ajax_loading_img();
893
+		$this->_add_admin_page_overlay();
894
+	}
895
+
896
+
897
+
898
+	/**
899
+	 * add in any global scripts for cpt routes
900
+	 *
901
+	 * @return void
902
+	 */
903
+	public function load_global_scripts_styles()
904
+	{
905
+		parent::load_global_scripts_styles();
906
+		if ($this->_cpt_model_obj instanceof EE_CPT_Base) {
907
+			//setup custom post status object for localize script but only if we've got a cpt object
908
+			$statuses = $this->_cpt_model_obj->get_custom_post_statuses();
909
+			if ( ! empty($statuses)) {
910
+				//get ALL statuses!
911
+				$statuses = $this->_cpt_model_obj->get_all_post_statuses();
912
+				//setup object
913
+				$ee_cpt_statuses = array();
914
+				foreach ($statuses as $status => $label) {
915
+					$ee_cpt_statuses[$status] = array(
916
+						'label'      => $label,
917
+						'save_label' => sprintf(__('Save as %s', 'event_espresso'), $label),
918
+					);
919
+				}
920
+				wp_localize_script('ee_admin_js', 'eeCPTstatuses', $ee_cpt_statuses);
921
+			}
922
+		}
923
+	}
924
+
925
+
926
+
927
+	/**
928
+	 * This is a wrapper for the insert/update routes for cpt items so we can add things that are common to ALL
929
+	 * insert/updates
930
+	 *
931
+	 * @param  int     $post_id ID of post being updated
932
+	 * @param  WP_Post $post    Post object from WP
933
+	 * @param  bool    $update  Whether this is an update or a new save.
934
+	 * @return void
935
+	 * @throws \EE_Error
936
+	 */
937
+	public function insert_update($post_id, $post, $update)
938
+	{
939
+		//make sure that if this is a revision OR trash action that we don't do any updates!
940
+		if (
941
+			isset($this->_req_data['action'])
942
+			&& (
943
+				$this->_req_data['action'] === 'restore'
944
+				|| $this->_req_data['action'] === 'trash'
945
+			)
946
+		) {
947
+			return;
948
+		}
949
+		$this->_set_model_object($post_id, true, 'insert_update');
950
+		//if our cpt object is not instantiated and its NOT the same post_id as what is triggering this callback, then exit.
951
+		if ($update
952
+			&& (
953
+				! $this->_cpt_model_obj instanceof EE_CPT_Base
954
+				|| $this->_cpt_model_obj->ID() !== $post_id
955
+			)
956
+		) {
957
+			return;
958
+		}
959
+		//check for autosave and update our req_data property accordingly.
960
+		/*if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE && isset( $this->_req_data['ee_autosave_data'] ) ) {
961 961
             foreach( (array) $this->_req_data['ee_autosave_data'] as $id => $values ) {
962 962
 
963 963
                 foreach ( (array) $values as $key => $value ) {
@@ -967,542 +967,542 @@  discard block
 block discarded – undo
967 967
 
968 968
         }/**/ //TODO reactivate after autosave is implemented in 4.2
969 969
 
970
-        //take care of updating any selected page_template IF this cpt supports it.
971
-        if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
972
-            //wp version aware.
973
-            if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
974
-                $page_templates = wp_get_theme()->get_page_templates();
975
-            } else {
976
-                $post->page_template = $this->_req_data['page_template'];
977
-                $page_templates      = wp_get_theme()->get_page_templates($post);
978
-            }
979
-            if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[$this->_req_data['page_template']])) {
980
-                EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
981
-            } else {
982
-                update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
983
-            }
984
-        }
985
-        if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
986
-            return;
987
-        } //TODO we'll remove this after reimplementing autosave in 4.2
988
-        $this->_insert_update_cpt_item($post_id, $post);
989
-    }
990
-
991
-
992
-
993
-    /**
994
-     * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
995
-     * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
996
-     * so we don't have to check for our CPT.
997
-     *
998
-     * @param  int $post_id ID of the post
999
-     * @return void
1000
-     */
1001
-    public function dont_permanently_delete_ee_cpts($post_id)
1002
-    {
1003
-        //only do this if we're actually processing one of our CPTs
1004
-        //if our cpt object isn't existent then get out immediately.
1005
-        if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1006
-            return;
1007
-        }
1008
-        delete_post_meta($post_id, '_wp_trash_meta_status');
1009
-        delete_post_meta($post_id, '_wp_trash_meta_time');
1010
-        //our cpts may have comments so let's take care of that too
1011
-        delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1012
-    }
1013
-
1014
-
1015
-
1016
-    /**
1017
-     * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1018
-     * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1019
-     * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1020
-     *
1021
-     * @param  int $post_id     ID of cpt item
1022
-     * @param  int $revision_id ID of revision being restored
1023
-     * @return void
1024
-     */
1025
-    public function restore_revision($post_id, $revision_id)
1026
-    {
1027
-        $this->_restore_cpt_item($post_id, $revision_id);
1028
-        //global action
1029
-        do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1030
-        //class specific action so you can limit hooking into a specific page.
1031
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1032
-    }
1033
-
1034
-
1035
-
1036
-    /**
1037
-     * @see restore_revision() for details
1038
-     * @param  int $post_id     ID of cpt item
1039
-     * @param  int $revision_id ID of revision for item
1040
-     * @return void
1041
-     */
1042
-    abstract protected function _restore_cpt_item($post_id, $revision_id);
1043
-
1044
-
1045
-
1046
-    /**
1047
-     * Execution of this method is added to the end of the load_page_dependencies method in the parent
1048
-     * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1049
-     * To fix we have to reset the current_screen using the page_slug
1050
-     * (which is identical - or should be - to our registered_post_type id.)
1051
-     * Also, since the core WP file loads the admin_header.php for WP
1052
-     * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1053
-     * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1054
-     *
1055
-     * @return void
1056
-     */
1057
-    public function modify_current_screen()
1058
-    {
1059
-        //ONLY do this if the current page_route IS a cpt route
1060
-        if ( ! $this->_cpt_route) {
1061
-            return;
1062
-        }
1063
-        //routing things REALLY early b/c this is a cpt admin page
1064
-        set_current_screen($this->_cpt_routes[$this->_req_action]);
1065
-        $this->_current_screen       = get_current_screen();
1066
-        $this->_current_screen->base = 'event-espresso';
1067
-        $this->_add_help_tabs(); //we make sure we add any help tabs back in!
1068
-        /*try {
970
+		//take care of updating any selected page_template IF this cpt supports it.
971
+		if ($this->_supports_page_templates($post->post_type) && ! empty($this->_req_data['page_template'])) {
972
+			//wp version aware.
973
+			if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
974
+				$page_templates = wp_get_theme()->get_page_templates();
975
+			} else {
976
+				$post->page_template = $this->_req_data['page_template'];
977
+				$page_templates      = wp_get_theme()->get_page_templates($post);
978
+			}
979
+			if ('default' != $this->_req_data['page_template'] && ! isset($page_templates[$this->_req_data['page_template']])) {
980
+				EE_Error::add_error(__('Invalid Page Template.', 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
981
+			} else {
982
+				update_post_meta($post_id, '_wp_page_template', $this->_req_data['page_template']);
983
+			}
984
+		}
985
+		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
986
+			return;
987
+		} //TODO we'll remove this after reimplementing autosave in 4.2
988
+		$this->_insert_update_cpt_item($post_id, $post);
989
+	}
990
+
991
+
992
+
993
+	/**
994
+	 * This hooks into the wp_trash_post() function and removes the `_wp_trash_meta_status` and `_wp_trash_meta_time`
995
+	 * post meta IF the trashed post is one of our CPT's - note this method should only be called with our cpt routes
996
+	 * so we don't have to check for our CPT.
997
+	 *
998
+	 * @param  int $post_id ID of the post
999
+	 * @return void
1000
+	 */
1001
+	public function dont_permanently_delete_ee_cpts($post_id)
1002
+	{
1003
+		//only do this if we're actually processing one of our CPTs
1004
+		//if our cpt object isn't existent then get out immediately.
1005
+		if ( ! $this->_cpt_model_obj instanceof EE_CPT_Base) {
1006
+			return;
1007
+		}
1008
+		delete_post_meta($post_id, '_wp_trash_meta_status');
1009
+		delete_post_meta($post_id, '_wp_trash_meta_time');
1010
+		//our cpts may have comments so let's take care of that too
1011
+		delete_post_meta($post_id, '_wp_trash_meta_comments_status');
1012
+	}
1013
+
1014
+
1015
+
1016
+	/**
1017
+	 * This is a wrapper for the restore_cpt_revision route for cpt items so we can make sure that when a revision is
1018
+	 * triggered that we restore related items.  In order to work cpt classes MUST have a restore_cpt_revision method
1019
+	 * in them. We also have our OWN action in here so addons can hook into the restore process easily.
1020
+	 *
1021
+	 * @param  int $post_id     ID of cpt item
1022
+	 * @param  int $revision_id ID of revision being restored
1023
+	 * @return void
1024
+	 */
1025
+	public function restore_revision($post_id, $revision_id)
1026
+	{
1027
+		$this->_restore_cpt_item($post_id, $revision_id);
1028
+		//global action
1029
+		do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1030
+		//class specific action so you can limit hooking into a specific page.
1031
+		do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1032
+	}
1033
+
1034
+
1035
+
1036
+	/**
1037
+	 * @see restore_revision() for details
1038
+	 * @param  int $post_id     ID of cpt item
1039
+	 * @param  int $revision_id ID of revision for item
1040
+	 * @return void
1041
+	 */
1042
+	abstract protected function _restore_cpt_item($post_id, $revision_id);
1043
+
1044
+
1045
+
1046
+	/**
1047
+	 * Execution of this method is added to the end of the load_page_dependencies method in the parent
1048
+	 * so that we can fix a bug where default core metaboxes were not being called in the sidebar.
1049
+	 * To fix we have to reset the current_screen using the page_slug
1050
+	 * (which is identical - or should be - to our registered_post_type id.)
1051
+	 * Also, since the core WP file loads the admin_header.php for WP
1052
+	 * (and there are a bunch of other things edit-form-advanced.php loads that need to happen really early)
1053
+	 * we need to load it NOW, hence our _route_admin_request in here. (Otherwise screen options won't be set).
1054
+	 *
1055
+	 * @return void
1056
+	 */
1057
+	public function modify_current_screen()
1058
+	{
1059
+		//ONLY do this if the current page_route IS a cpt route
1060
+		if ( ! $this->_cpt_route) {
1061
+			return;
1062
+		}
1063
+		//routing things REALLY early b/c this is a cpt admin page
1064
+		set_current_screen($this->_cpt_routes[$this->_req_action]);
1065
+		$this->_current_screen       = get_current_screen();
1066
+		$this->_current_screen->base = 'event-espresso';
1067
+		$this->_add_help_tabs(); //we make sure we add any help tabs back in!
1068
+		/*try {
1069 1069
             $this->_route_admin_request();
1070 1070
         } catch ( EE_Error $e ) {
1071 1071
             $e->get_error();
1072 1072
         }/**/
1073
-    }
1074
-
1075
-
1076
-
1077
-    /**
1078
-     * This allows child classes to modify the default editor title that appears when people add a new or edit an
1079
-     * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1080
-     * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1081
-     * default to be.
1082
-     *
1083
-     * @param string $title The new title (or existing if there is no editor_title defined)
1084
-     * @return string
1085
-     */
1086
-    public function add_custom_editor_default_title($title)
1087
-    {
1088
-        return isset($this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]])
1089
-            ? $this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]]
1090
-            : $title;
1091
-    }
1092
-
1093
-
1094
-
1095
-    /**
1096
-     * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1097
-     *
1098
-     * @param string $shortlink   The already generated shortlink
1099
-     * @param int    $id          Post ID for this item
1100
-     * @param string $context     The context for the link
1101
-     * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1102
-     * @return string
1103
-     */
1104
-    public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1105
-    {
1106
-        if ( ! empty($id) && get_option('permalink_structure') !== '') {
1107
-            $post = get_post($id);
1108
-            if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1109
-                $shortlink = home_url('?p=' . $post->ID);
1110
-            }
1111
-        }
1112
-        return $shortlink;
1113
-    }
1114
-
1115
-
1116
-
1117
-    /**
1118
-     * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1119
-     * already run in modify_current_screen())
1120
-     *
1121
-     * @return void
1122
-     */
1123
-    public function route_admin_request()
1124
-    {
1125
-        if ($this->_cpt_route) {
1126
-            return;
1127
-        }
1128
-        try {
1129
-            $this->_route_admin_request();
1130
-        } catch (EE_Error $e) {
1131
-            $e->get_error();
1132
-        }
1133
-    }
1134
-
1135
-
1136
-
1137
-    /**
1138
-     * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1139
-     *
1140
-     * @return void
1141
-     */
1142
-    public function cpt_post_form_hidden_input()
1143
-    {
1144
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1145
-        //we're also going to add the route value and the current page so we can direct autosave parsing correctly
1146
-        echo '<div id="ee-cpt-hidden-inputs">';
1147
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1148
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1149
-        echo '</div>';
1150
-    }
1151
-
1152
-
1153
-
1154
-    /**
1155
-     * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1156
-     *
1157
-     * @param  string $location Original location url
1158
-     * @param  int    $status   Status for http header
1159
-     * @return string           new (or original) url to redirect to.
1160
-     */
1161
-    public function revision_redirect($location, $status)
1162
-    {
1163
-        //get revision
1164
-        $rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1165
-        //can't do anything without revision so let's get out if not present
1166
-        if (empty($rev_id)) {
1167
-            return $location;
1168
-        }
1169
-        //get rev_post_data
1170
-        $rev = get_post($rev_id);
1171
-        $admin_url = $this->_admin_base_url;
1172
-        $query_args = array(
1173
-            'action'   => 'edit',
1174
-            'post'     => $rev->post_parent,
1175
-            'revision' => $rev_id,
1176
-            'message'  => 5,
1177
-        );
1178
-        $this->_process_notices($query_args, true);
1179
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1180
-    }
1181
-
1182
-
1183
-
1184
-    /**
1185
-     * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1186
-     *
1187
-     * @param  string $link    the original generated link
1188
-     * @param  int    $id      post id
1189
-     * @param  string $context optional, defaults to display.  How to write the '&'
1190
-     * @return string          the link
1191
-     */
1192
-    public function modify_edit_post_link($link, $id, $context)
1193
-    {
1194
-        $post = get_post($id);
1195
-        if ( ! isset($this->_req_data['action'])
1196
-             || ! isset($this->_cpt_routes[$this->_req_data['action']])
1197
-             || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1198
-        ) {
1199
-            return $link;
1200
-        }
1201
-        $query_args = array(
1202
-            'action' => isset($this->_cpt_edit_routes[$post->post_type])
1203
-                ? $this->_cpt_edit_routes[$post->post_type]
1204
-                : 'edit',
1205
-            'post'   => $id,
1206
-        );
1207
-        return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1208
-    }
1209
-
1210
-
1211
-    /**
1212
-     * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1213
-     * our routes.
1214
-     *
1215
-     * @param  string $delete_link  original delete link
1216
-     * @param  int    $post_id      id of cpt object
1217
-     * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1218
-     * @return string new delete link
1219
-     * @throws EE_Error
1220
-     */
1221
-    public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1222
-    {
1223
-        $post = get_post($post_id);
1224
-
1225
-        if (empty($this->_req_data['action'])
1226
-            || ! isset($this->_cpt_routes[$this->_req_data['action']])
1227
-            || ! $post instanceof WP_Post
1228
-            || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1229
-        ) {
1230
-            return $delete_link;
1231
-        }
1232
-        $this->_set_model_object($post->ID, true);
1233
-
1234
-        //returns something like `trash_event` or `trash_attendee` or `trash_venue`
1235
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1236
-
1237
-        return EE_Admin_Page::add_query_args_and_nonce(
1238
-            array(
1239
-                'page' => $this->_req_data['page'],
1240
-                'action' => $action,
1241
-                $this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1242
-                    => $post->ID
1243
-            ),
1244
-            admin_url()
1245
-        );
1246
-    }
1247
-
1248
-
1249
-
1250
-    /**
1251
-     * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1252
-     * so that we can hijack the default redirect locations for wp custom post types
1253
-     * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1254
-     *
1255
-     * @param  string $location This is the incoming currently set redirect location
1256
-     * @param  string $post_id  This is the 'ID' value of the wp_posts table
1257
-     * @return string           the new location to redirect to
1258
-     */
1259
-    public function cpt_post_location_redirect($location, $post_id)
1260
-    {
1261
-        //we DO have a match so let's setup the url
1262
-        //we have to get the post to determine our route
1263
-        $post       = get_post($post_id);
1264
-        $edit_route = $this->_cpt_edit_routes[$post->post_type];
1265
-        //shared query_args
1266
-        $query_args = array('action' => $edit_route, 'post' => $post_id);
1267
-        $admin_url  = $this->_admin_base_url;
1268
-        if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1269
-            $status = get_post_status($post_id);
1270
-            if (isset($this->_req_data['publish'])) {
1271
-                switch ($status) {
1272
-                    case 'pending':
1273
-                        $message = 8;
1274
-                        break;
1275
-                    case 'future':
1276
-                        $message = 9;
1277
-                        break;
1278
-                    default:
1279
-                        $message = 6;
1280
-                }
1281
-            } else {
1282
-                $message = 'draft' === $status ? 10 : 1;
1283
-            }
1284
-        } else if (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1285
-            $message = 2;
1286
-            //			$append = '#postcustom';
1287
-        } else if (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1288
-            $message = 3;
1289
-            //			$append = '#postcustom';
1290
-        } elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1291
-            $message = 7;
1292
-        } else {
1293
-            $message = 4;
1294
-        }
1295
-        //change the message if the post type is not viewable on the frontend
1296
-        $this->_cpt_object = get_post_type_object($post->post_type);
1297
-        $message           = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1298
-        $query_args = array_merge(array('message' => $message), $query_args);
1299
-        $this->_process_notices($query_args, true);
1300
-        return self::add_query_args_and_nonce($query_args, $admin_url);
1301
-    }
1302
-
1303
-
1304
-
1305
-    /**
1306
-     * This method is called to inject nav tabs on core WP cpt pages
1307
-     *
1308
-     * @access public
1309
-     * @return void
1310
-     */
1311
-    public function inject_nav_tabs()
1312
-    {
1313
-        //can we hijack and insert the nav_tabs?
1314
-        $nav_tabs = $this->_get_main_nav_tabs();
1315
-        //first close off existing form tag
1316
-        $html = '>';
1317
-        $html .= $nav_tabs;
1318
-        //now let's handle the remaining tag ( missing ">" is CORRECT )
1319
-        $html .= '<span></span';
1320
-        echo $html;
1321
-    }
1322
-
1323
-
1324
-
1325
-    /**
1326
-     * This just sets up the post update messages when an update form is loaded
1327
-     *
1328
-     * @access public
1329
-     * @param  array $messages the original messages array
1330
-     * @return array           the new messages array
1331
-     */
1332
-    public function post_update_messages($messages)
1333
-    {
1334
-        global $post;
1335
-        $id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1336
-        $id = empty($id) && is_object($post) ? $post->ID : null;
1337
-        //		$post_type = $post ? $post->post_type : false;
1338
-        /*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1073
+	}
1074
+
1075
+
1076
+
1077
+	/**
1078
+	 * This allows child classes to modify the default editor title that appears when people add a new or edit an
1079
+	 * existing CPT item.     * This uses the _labels property set by the child class via _define_page_props. Just make
1080
+	 * sure you have a key in _labels property that equals 'editor_title' and the value can be whatever you want the
1081
+	 * default to be.
1082
+	 *
1083
+	 * @param string $title The new title (or existing if there is no editor_title defined)
1084
+	 * @return string
1085
+	 */
1086
+	public function add_custom_editor_default_title($title)
1087
+	{
1088
+		return isset($this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]])
1089
+			? $this->_labels['editor_title'][$this->_cpt_routes[$this->_req_action]]
1090
+			: $title;
1091
+	}
1092
+
1093
+
1094
+
1095
+	/**
1096
+	 * hooks into the wp_get_shortlink button and makes sure that the shortlink gets generated
1097
+	 *
1098
+	 * @param string $shortlink   The already generated shortlink
1099
+	 * @param int    $id          Post ID for this item
1100
+	 * @param string $context     The context for the link
1101
+	 * @param bool   $allow_slugs Whether to allow post slugs in the shortlink.
1102
+	 * @return string
1103
+	 */
1104
+	public function add_shortlink_button_to_editor($shortlink, $id, $context, $allow_slugs)
1105
+	{
1106
+		if ( ! empty($id) && get_option('permalink_structure') !== '') {
1107
+			$post = get_post($id);
1108
+			if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1109
+				$shortlink = home_url('?p=' . $post->ID);
1110
+			}
1111
+		}
1112
+		return $shortlink;
1113
+	}
1114
+
1115
+
1116
+
1117
+	/**
1118
+	 * overriding the parent route_admin_request method so we DON'T run the route twice on cpt core page loads (it's
1119
+	 * already run in modify_current_screen())
1120
+	 *
1121
+	 * @return void
1122
+	 */
1123
+	public function route_admin_request()
1124
+	{
1125
+		if ($this->_cpt_route) {
1126
+			return;
1127
+		}
1128
+		try {
1129
+			$this->_route_admin_request();
1130
+		} catch (EE_Error $e) {
1131
+			$e->get_error();
1132
+		}
1133
+	}
1134
+
1135
+
1136
+
1137
+	/**
1138
+	 * Add a hidden form input to cpt core pages so that we know to do redirects to our routes on saves
1139
+	 *
1140
+	 * @return void
1141
+	 */
1142
+	public function cpt_post_form_hidden_input()
1143
+	{
1144
+		echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1145
+		//we're also going to add the route value and the current page so we can direct autosave parsing correctly
1146
+		echo '<div id="ee-cpt-hidden-inputs">';
1147
+		echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1148
+		echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1149
+		echo '</div>';
1150
+	}
1151
+
1152
+
1153
+
1154
+	/**
1155
+	 * This allows us to redirect the location of revision restores when they happen so it goes to our CPT routes.
1156
+	 *
1157
+	 * @param  string $location Original location url
1158
+	 * @param  int    $status   Status for http header
1159
+	 * @return string           new (or original) url to redirect to.
1160
+	 */
1161
+	public function revision_redirect($location, $status)
1162
+	{
1163
+		//get revision
1164
+		$rev_id = isset($this->_req_data['revision']) ? $this->_req_data['revision'] : null;
1165
+		//can't do anything without revision so let's get out if not present
1166
+		if (empty($rev_id)) {
1167
+			return $location;
1168
+		}
1169
+		//get rev_post_data
1170
+		$rev = get_post($rev_id);
1171
+		$admin_url = $this->_admin_base_url;
1172
+		$query_args = array(
1173
+			'action'   => 'edit',
1174
+			'post'     => $rev->post_parent,
1175
+			'revision' => $rev_id,
1176
+			'message'  => 5,
1177
+		);
1178
+		$this->_process_notices($query_args, true);
1179
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1180
+	}
1181
+
1182
+
1183
+
1184
+	/**
1185
+	 * Modify the edit post link generated by wp core function so that EE CPTs get setup differently.
1186
+	 *
1187
+	 * @param  string $link    the original generated link
1188
+	 * @param  int    $id      post id
1189
+	 * @param  string $context optional, defaults to display.  How to write the '&'
1190
+	 * @return string          the link
1191
+	 */
1192
+	public function modify_edit_post_link($link, $id, $context)
1193
+	{
1194
+		$post = get_post($id);
1195
+		if ( ! isset($this->_req_data['action'])
1196
+			 || ! isset($this->_cpt_routes[$this->_req_data['action']])
1197
+			 || $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1198
+		) {
1199
+			return $link;
1200
+		}
1201
+		$query_args = array(
1202
+			'action' => isset($this->_cpt_edit_routes[$post->post_type])
1203
+				? $this->_cpt_edit_routes[$post->post_type]
1204
+				: 'edit',
1205
+			'post'   => $id,
1206
+		);
1207
+		return self::add_query_args_and_nonce($query_args, $this->_admin_base_url);
1208
+	}
1209
+
1210
+
1211
+	/**
1212
+	 * Modify the trash link on our cpt edit pages so it has the required query var for triggering redirect properly on
1213
+	 * our routes.
1214
+	 *
1215
+	 * @param  string $delete_link  original delete link
1216
+	 * @param  int    $post_id      id of cpt object
1217
+	 * @param  bool   $force_delete whether this is forcing a hard delete instead of trash
1218
+	 * @return string new delete link
1219
+	 * @throws EE_Error
1220
+	 */
1221
+	public function modify_delete_post_link($delete_link, $post_id, $force_delete)
1222
+	{
1223
+		$post = get_post($post_id);
1224
+
1225
+		if (empty($this->_req_data['action'])
1226
+			|| ! isset($this->_cpt_routes[$this->_req_data['action']])
1227
+			|| ! $post instanceof WP_Post
1228
+			|| $post->post_type !== $this->_cpt_routes[$this->_req_data['action']]
1229
+		) {
1230
+			return $delete_link;
1231
+		}
1232
+		$this->_set_model_object($post->ID, true);
1233
+
1234
+		//returns something like `trash_event` or `trash_attendee` or `trash_venue`
1235
+		$action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1236
+
1237
+		return EE_Admin_Page::add_query_args_and_nonce(
1238
+			array(
1239
+				'page' => $this->_req_data['page'],
1240
+				'action' => $action,
1241
+				$this->_cpt_model_obj->get_model()->get_primary_key_field()->get_name()
1242
+					=> $post->ID
1243
+			),
1244
+			admin_url()
1245
+		);
1246
+	}
1247
+
1248
+
1249
+
1250
+	/**
1251
+	 * This is the callback for the 'redirect_post_location' filter in wp-admin/post.php
1252
+	 * so that we can hijack the default redirect locations for wp custom post types
1253
+	 * that WE'RE using and send back to OUR routes.  This should only be hooked in on the right route.
1254
+	 *
1255
+	 * @param  string $location This is the incoming currently set redirect location
1256
+	 * @param  string $post_id  This is the 'ID' value of the wp_posts table
1257
+	 * @return string           the new location to redirect to
1258
+	 */
1259
+	public function cpt_post_location_redirect($location, $post_id)
1260
+	{
1261
+		//we DO have a match so let's setup the url
1262
+		//we have to get the post to determine our route
1263
+		$post       = get_post($post_id);
1264
+		$edit_route = $this->_cpt_edit_routes[$post->post_type];
1265
+		//shared query_args
1266
+		$query_args = array('action' => $edit_route, 'post' => $post_id);
1267
+		$admin_url  = $this->_admin_base_url;
1268
+		if (isset($this->_req_data['save']) || isset($this->_req_data['publish'])) {
1269
+			$status = get_post_status($post_id);
1270
+			if (isset($this->_req_data['publish'])) {
1271
+				switch ($status) {
1272
+					case 'pending':
1273
+						$message = 8;
1274
+						break;
1275
+					case 'future':
1276
+						$message = 9;
1277
+						break;
1278
+					default:
1279
+						$message = 6;
1280
+				}
1281
+			} else {
1282
+				$message = 'draft' === $status ? 10 : 1;
1283
+			}
1284
+		} else if (isset($this->_req_data['addmeta']) && $this->_req_data['addmeta']) {
1285
+			$message = 2;
1286
+			//			$append = '#postcustom';
1287
+		} else if (isset($this->_req_data['deletemeta']) && $this->_req_data['deletemeta']) {
1288
+			$message = 3;
1289
+			//			$append = '#postcustom';
1290
+		} elseif ($this->_req_data['action'] === 'post-quickpress-save-cont') {
1291
+			$message = 7;
1292
+		} else {
1293
+			$message = 4;
1294
+		}
1295
+		//change the message if the post type is not viewable on the frontend
1296
+		$this->_cpt_object = get_post_type_object($post->post_type);
1297
+		$message           = $message === 1 && ! $this->_cpt_object->publicly_queryable ? 4 : $message;
1298
+		$query_args = array_merge(array('message' => $message), $query_args);
1299
+		$this->_process_notices($query_args, true);
1300
+		return self::add_query_args_and_nonce($query_args, $admin_url);
1301
+	}
1302
+
1303
+
1304
+
1305
+	/**
1306
+	 * This method is called to inject nav tabs on core WP cpt pages
1307
+	 *
1308
+	 * @access public
1309
+	 * @return void
1310
+	 */
1311
+	public function inject_nav_tabs()
1312
+	{
1313
+		//can we hijack and insert the nav_tabs?
1314
+		$nav_tabs = $this->_get_main_nav_tabs();
1315
+		//first close off existing form tag
1316
+		$html = '>';
1317
+		$html .= $nav_tabs;
1318
+		//now let's handle the remaining tag ( missing ">" is CORRECT )
1319
+		$html .= '<span></span';
1320
+		echo $html;
1321
+	}
1322
+
1323
+
1324
+
1325
+	/**
1326
+	 * This just sets up the post update messages when an update form is loaded
1327
+	 *
1328
+	 * @access public
1329
+	 * @param  array $messages the original messages array
1330
+	 * @return array           the new messages array
1331
+	 */
1332
+	public function post_update_messages($messages)
1333
+	{
1334
+		global $post;
1335
+		$id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1336
+		$id = empty($id) && is_object($post) ? $post->ID : null;
1337
+		//		$post_type = $post ? $post->post_type : false;
1338
+		/*$current_route = isset($this->_req_data['current_route']) ? $this->_req_data['current_route'] : 'shouldneverwork';
1339 1339
 
1340 1340
         $route_to_check = $post_type && isset( $this->_cpt_routes[$current_route]) ? $this->_cpt_routes[$current_route] : '';/**/
1341
-        $messages[$post->post_type] = array(
1342
-            0 => '', //Unused. Messages start at index 1.
1343
-            1 => sprintf(
1344
-                __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1345
-                $this->_cpt_object->labels->singular_name,
1346
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1347
-                '</a>'
1348
-            ),
1349
-            2 => __('Custom field updated'),
1350
-            3 => __('Custom field deleted.'),
1351
-            4 => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1352
-            5 => isset($_GET['revision']) ? sprintf(__('%s restored to revision from %s', 'event_espresso'),
1353
-                $this->_cpt_object->labels->singular_name, wp_post_revision_title((int)$_GET['revision'], false))
1354
-                : false,
1355
-            6 => sprintf(
1356
-                __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1357
-                $this->_cpt_object->labels->singular_name,
1358
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1359
-                '</a>'
1360
-            ),
1361
-            7 => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1362
-            8 => sprintf(
1363
-                __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1364
-                $this->_cpt_object->labels->singular_name,
1365
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1366
-                '</a>'
1367
-            ),
1368
-            9 => sprintf(
1369
-                __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1370
-                $this->_cpt_object->labels->singular_name,
1371
-                '<strong>' . date_i18n(__('M j, Y @ G:i'), strtotime($post->post_date)) . '</strong>',
1372
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1373
-                '</a>'
1374
-            ),
1375
-            10 => sprintf(
1376
-                __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1377
-                $this->_cpt_object->labels->singular_name,
1378
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1379
-                '</a>'
1380
-            ),
1381
-        );
1382
-        return $messages;
1383
-    }
1384
-
1385
-
1386
-
1387
-    /**
1388
-     * default method for the 'create_new' route for cpt admin pages.
1389
-     * For reference what to include in here, see wp-admin/post-new.php
1390
-     *
1391
-     * @access  protected
1392
-     * @return void
1393
-     */
1394
-    protected function _create_new_cpt_item()
1395
-    {
1396
-        // gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1397
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1398
-        $post_type        = $this->_cpt_routes[$this->_req_action];
1399
-        $post_type_object = $this->_cpt_object;
1400
-        $title            = $post_type_object->labels->add_new_item;
1401
-        $post    = $post = get_default_post_to_edit($this->_cpt_routes[$this->_req_action], true);
1402
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1403
-        //modify the default editor title field with default title.
1404
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1405
-        $this->loadEditorTemplate(true);
1406
-    }
1407
-
1408
-
1409
-    /**
1410
-     * Enqueues auto-save and loads the editor template
1411
-     *
1412
-     * @param bool $creating
1413
-     */
1414
-    private function loadEditorTemplate($creating = true) {
1415
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1416
-        //these vars are used by the template
1417
-        $editing = true;
1418
-        $post_ID = $post->ID;
1419
-        if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1420
-            //only enqueue autosave when creating event (necessary to get permalink/url generated)
1421
-            //otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1422
-            if ($creating) {
1423
-                wp_enqueue_script('autosave');
1424
-            } else {
1425
-                if (isset($this->_cpt_routes[$this->_req_data['action']])
1426
-                    && ! isset($this->_labels['hide_add_button_on_cpt_route'][$this->_req_data['action']])
1427
-                ) {
1428
-                    $create_new_action = apply_filters('FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1429
-                        'create_new', $this);
1430
-                    $post_new_file = EE_Admin_Page::add_query_args_and_nonce(array(
1431
-                        'action' => $create_new_action,
1432
-                        'page'   => $this->page_slug,
1433
-                    ), 'admin.php');
1434
-                }
1435
-            }
1436
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1437
-        }
1438
-    }
1439
-
1440
-
1441
-
1442
-    public function add_new_admin_page_global()
1443
-    {
1444
-        $admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1445
-        ?>
1341
+		$messages[$post->post_type] = array(
1342
+			0 => '', //Unused. Messages start at index 1.
1343
+			1 => sprintf(
1344
+				__('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1345
+				$this->_cpt_object->labels->singular_name,
1346
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1347
+				'</a>'
1348
+			),
1349
+			2 => __('Custom field updated'),
1350
+			3 => __('Custom field deleted.'),
1351
+			4 => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1352
+			5 => isset($_GET['revision']) ? sprintf(__('%s restored to revision from %s', 'event_espresso'),
1353
+				$this->_cpt_object->labels->singular_name, wp_post_revision_title((int)$_GET['revision'], false))
1354
+				: false,
1355
+			6 => sprintf(
1356
+				__('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1357
+				$this->_cpt_object->labels->singular_name,
1358
+				'<a href="' . esc_url(get_permalink($id)) . '">',
1359
+				'</a>'
1360
+			),
1361
+			7 => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1362
+			8 => sprintf(
1363
+				__('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1364
+				$this->_cpt_object->labels->singular_name,
1365
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1366
+				'</a>'
1367
+			),
1368
+			9 => sprintf(
1369
+				__('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1370
+				$this->_cpt_object->labels->singular_name,
1371
+				'<strong>' . date_i18n(__('M j, Y @ G:i'), strtotime($post->post_date)) . '</strong>',
1372
+				'<a target="_blank" href="' . esc_url(get_permalink($id)),
1373
+				'</a>'
1374
+			),
1375
+			10 => sprintf(
1376
+				__('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1377
+				$this->_cpt_object->labels->singular_name,
1378
+				'<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1379
+				'</a>'
1380
+			),
1381
+		);
1382
+		return $messages;
1383
+	}
1384
+
1385
+
1386
+
1387
+	/**
1388
+	 * default method for the 'create_new' route for cpt admin pages.
1389
+	 * For reference what to include in here, see wp-admin/post-new.php
1390
+	 *
1391
+	 * @access  protected
1392
+	 * @return void
1393
+	 */
1394
+	protected function _create_new_cpt_item()
1395
+	{
1396
+		// gather template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1397
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1398
+		$post_type        = $this->_cpt_routes[$this->_req_action];
1399
+		$post_type_object = $this->_cpt_object;
1400
+		$title            = $post_type_object->labels->add_new_item;
1401
+		$post    = $post = get_default_post_to_edit($this->_cpt_routes[$this->_req_action], true);
1402
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1403
+		//modify the default editor title field with default title.
1404
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1405
+		$this->loadEditorTemplate(true);
1406
+	}
1407
+
1408
+
1409
+	/**
1410
+	 * Enqueues auto-save and loads the editor template
1411
+	 *
1412
+	 * @param bool $creating
1413
+	 */
1414
+	private function loadEditorTemplate($creating = true) {
1415
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1416
+		//these vars are used by the template
1417
+		$editing = true;
1418
+		$post_ID = $post->ID;
1419
+		if (apply_filters('FHEE__EE_Admin_Page_CPT___create_new_cpt_item__replace_editor', false, $post) === false) {
1420
+			//only enqueue autosave when creating event (necessary to get permalink/url generated)
1421
+			//otherwise EE doesn't support autosave fully, so to prevent user confusion we disable it in edit context.
1422
+			if ($creating) {
1423
+				wp_enqueue_script('autosave');
1424
+			} else {
1425
+				if (isset($this->_cpt_routes[$this->_req_data['action']])
1426
+					&& ! isset($this->_labels['hide_add_button_on_cpt_route'][$this->_req_data['action']])
1427
+				) {
1428
+					$create_new_action = apply_filters('FHEE__EE_Admin_Page_CPT___edit_cpt_item__create_new_action',
1429
+						'create_new', $this);
1430
+					$post_new_file = EE_Admin_Page::add_query_args_and_nonce(array(
1431
+						'action' => $create_new_action,
1432
+						'page'   => $this->page_slug,
1433
+					), 'admin.php');
1434
+				}
1435
+			}
1436
+			include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1437
+		}
1438
+	}
1439
+
1440
+
1441
+
1442
+	public function add_new_admin_page_global()
1443
+	{
1444
+		$admin_page = ! empty($this->_req_data['post']) ? 'post-php' : 'post-new-php';
1445
+		?>
1446 1446
         <script type="text/javascript">
1447 1447
             adminpage = '<?php echo $admin_page; ?>';
1448 1448
         </script>
1449 1449
         <?php
1450
-    }
1451
-
1452
-
1453
-
1454
-    /**
1455
-     * default method for the 'edit' route for cpt admin pages
1456
-     * For reference on what to put in here, refer to wp-admin/post.php
1457
-     *
1458
-     * @access protected
1459
-     * @return string   template for edit cpt form
1460
-     */
1461
-    protected function _edit_cpt_item()
1462
-    {
1463
-        global $post, $title, $is_IE, $post_type, $post_type_object;
1464
-        $post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1465
-        $post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1466
-        if (empty ($post)) {
1467
-            wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?'));
1468
-        }
1469
-        if ( ! empty($_GET['get-post-lock'])) {
1470
-            wp_set_post_lock($post_id);
1471
-            wp_redirect(get_edit_post_link($post_id, 'url'));
1472
-            exit();
1473
-        }
1474
-
1475
-        // template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1476
-        $post_type        = $this->_cpt_routes[$this->_req_action];
1477
-        $post_type_object = $this->_cpt_object;
1478
-
1479
-        if ( ! wp_check_post_lock($post->ID)) {
1480
-            wp_set_post_lock($post->ID);
1481
-        }
1482
-        add_action('admin_footer', '_admin_notice_post_locked');
1483
-        if (post_type_supports($this->_cpt_routes[$this->_req_action], 'comments')) {
1484
-            wp_enqueue_script('admin-comments');
1485
-            enqueue_comment_hotkeys_js();
1486
-        }
1487
-        add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1488
-        //modify the default editor title field with default title.
1489
-        add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1490
-        $this->loadEditorTemplate(false);
1491
-    }
1492
-
1493
-
1494
-
1495
-    /**
1496
-     * some getters
1497
-     */
1498
-    /**
1499
-     * This returns the protected _cpt_model_obj property
1500
-     *
1501
-     * @return EE_CPT_Base
1502
-     */
1503
-    public function get_cpt_model_obj()
1504
-    {
1505
-        return $this->_cpt_model_obj;
1506
-    }
1450
+	}
1451
+
1452
+
1453
+
1454
+	/**
1455
+	 * default method for the 'edit' route for cpt admin pages
1456
+	 * For reference on what to put in here, refer to wp-admin/post.php
1457
+	 *
1458
+	 * @access protected
1459
+	 * @return string   template for edit cpt form
1460
+	 */
1461
+	protected function _edit_cpt_item()
1462
+	{
1463
+		global $post, $title, $is_IE, $post_type, $post_type_object;
1464
+		$post_id = isset($this->_req_data['post']) ? $this->_req_data['post'] : null;
1465
+		$post = ! empty($post_id) ? get_post($post_id, OBJECT, 'edit') : null;
1466
+		if (empty ($post)) {
1467
+			wp_die(__('You attempted to edit an item that doesn&#8217;t exist. Perhaps it was deleted?'));
1468
+		}
1469
+		if ( ! empty($_GET['get-post-lock'])) {
1470
+			wp_set_post_lock($post_id);
1471
+			wp_redirect(get_edit_post_link($post_id, 'url'));
1472
+			exit();
1473
+		}
1474
+
1475
+		// template vars for WP_ADMIN_PATH . 'edit-form-advanced.php'
1476
+		$post_type        = $this->_cpt_routes[$this->_req_action];
1477
+		$post_type_object = $this->_cpt_object;
1478
+
1479
+		if ( ! wp_check_post_lock($post->ID)) {
1480
+			wp_set_post_lock($post->ID);
1481
+		}
1482
+		add_action('admin_footer', '_admin_notice_post_locked');
1483
+		if (post_type_supports($this->_cpt_routes[$this->_req_action], 'comments')) {
1484
+			wp_enqueue_script('admin-comments');
1485
+			enqueue_comment_hotkeys_js();
1486
+		}
1487
+		add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1488
+		//modify the default editor title field with default title.
1489
+		add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
1490
+		$this->loadEditorTemplate(false);
1491
+	}
1492
+
1493
+
1494
+
1495
+	/**
1496
+	 * some getters
1497
+	 */
1498
+	/**
1499
+	 * This returns the protected _cpt_model_obj property
1500
+	 *
1501
+	 * @return EE_CPT_Base
1502
+	 */
1503
+	public function get_cpt_model_obj()
1504
+	{
1505
+		return $this->_cpt_model_obj;
1506
+	}
1507 1507
 
1508 1508
 }
Please login to merge, or discard this patch.
Spacing   +26 added lines, -26 removed lines patch added patch discarded remove patch
@@ -242,7 +242,7 @@  discard block
 block discarded – undo
242 242
      */
243 243
     protected function _register_autosave_containers($ids)
244 244
     {
245
-        $this->_autosave_containers = array_merge($this->_autosave_fields, (array)$ids);
245
+        $this->_autosave_containers = array_merge($this->_autosave_fields, (array) $ids);
246 246
     }
247 247
 
248 248
 
@@ -289,7 +289,7 @@  discard block
 block discarded – undo
289 289
         //filter _autosave_containers
290 290
         $containers = apply_filters('FHEE__EE_Admin_Page_CPT___load_autosave_scripts_styles__containers',
291 291
             $this->_autosave_containers, $this);
292
-        $containers = apply_filters('FHEE__EE_Admin_Page_CPT__' . get_class($this) . '___load_autosave_scripts_styles__containers',
292
+        $containers = apply_filters('FHEE__EE_Admin_Page_CPT__'.get_class($this).'___load_autosave_scripts_styles__containers',
293 293
             $containers, $this);
294 294
 
295 295
         wp_localize_script('event_editor_js', 'EE_AUTOSAVE_IDS',
@@ -401,7 +401,7 @@  discard block
 block discarded – undo
401 401
         // This is for any plugins that are doing things properly
402 402
         // and hooking into the load page hook for core wp cpt routes.
403 403
         global $pagenow;
404
-        do_action('load-' . $pagenow);
404
+        do_action('load-'.$pagenow);
405 405
         $this->modify_current_screen();
406 406
         add_action('admin_enqueue_scripts', array($this, 'setup_autosave_hooks'), 30);
407 407
         //we route REALLY early.
@@ -432,8 +432,8 @@  discard block
 block discarded – undo
432 432
                 'admin.php?page=espresso_registrations&action=contact_list',
433 433
             ),
434 434
             1 => array(
435
-                'edit.php?post_type=' . $this->_cpt_object->name,
436
-                'admin.php?page=' . $this->_cpt_object->name,
435
+                'edit.php?post_type='.$this->_cpt_object->name,
436
+                'admin.php?page='.$this->_cpt_object->name,
437 437
             ),
438 438
         );
439 439
         foreach ($routes_to_match as $route_matches) {
@@ -466,7 +466,7 @@  discard block
 block discarded – undo
466 466
         $cpt_has_support = ! empty($cpt_args['page_templates']);
467 467
 
468 468
         //if the installed version of WP is > 4.7 we do some additional checks.
469
-        if (RecommendedVersions::compareWordPressVersion('4.7','>=')) {
469
+        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
470 470
             $post_templates = wp_get_theme()->get_post_templates();
471 471
             //if there are $post_templates for this cpt, then we return false for this method because
472 472
             //that means we aren't going to load our page template manager and leave that up to the native
@@ -489,7 +489,7 @@  discard block
 block discarded – undo
489 489
         global $post;
490 490
         $template = '';
491 491
 
492
-        if (RecommendedVersions::compareWordPressVersion('4.7','>=')) {
492
+        if (RecommendedVersions::compareWordPressVersion('4.7', '>=')) {
493 493
             $page_template_count = count(get_page_templates());
494 494
         } else {
495 495
             $page_template_count = count(get_page_templates($post));
@@ -526,7 +526,7 @@  discard block
 block discarded – undo
526 526
         $post = get_post($id);
527 527
         if ('publish' !== get_post_status($post)) {
528 528
             //include shims for the `get_preview_post_link` function
529
-            require_once( EE_CORE . 'wordpress-shims.php' );
529
+            require_once(EE_CORE.'wordpress-shims.php');
530 530
             $return .= '<span_id="view-post-btn"><a target="_blank" href="'
531 531
                        . get_preview_post_link($id)
532 532
                        . '" class="button button-small">'
@@ -564,7 +564,7 @@  discard block
 block discarded – undo
564 564
             $template_args['statuses']         = $statuses;
565 565
         }
566 566
 
567
-        $template = EE_ADMIN_TEMPLATE . 'status_dropdown.template.php';
567
+        $template = EE_ADMIN_TEMPLATE.'status_dropdown.template.php';
568 568
         EEH_Template::display_template($template, $template_args);
569 569
     }
570 570
 
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
             $this->_template_args['success'] = true;
619 619
         }
620 620
         do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__global_after', $this);
621
-        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_' . get_class($this), $this);
621
+        do_action('AHEE__EE_Admin_Page_CPT__do_extra_autosave_stuff__after_'.get_class($this), $this);
622 622
         //now let's return json
623 623
         $this->_return_json();
624 624
     }
@@ -716,7 +716,7 @@  discard block
 block discarded – undo
716 716
         }
717 717
         // if ignore_route_check is true, then get the model name via CustomPostTypeDefinitions
718 718
         if ($ignore_route_check) {
719
-            $post_type   = get_post_type($id);
719
+            $post_type = get_post_type($id);
720 720
             /** @var EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions $custom_post_types */
721 721
             $custom_post_types = LoaderFactory::getLoader()->getShared(
722 722
                 'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'
@@ -1028,7 +1028,7 @@  discard block
 block discarded – undo
1028 1028
         //global action
1029 1029
         do_action('AHEE_EE_Admin_Page_CPT__restore_revision', $post_id, $revision_id);
1030 1030
         //class specific action so you can limit hooking into a specific page.
1031
-        do_action('AHEE_EE_Admin_Page_CPT_' . get_class($this) . '__restore_revision', $post_id, $revision_id);
1031
+        do_action('AHEE_EE_Admin_Page_CPT_'.get_class($this).'__restore_revision', $post_id, $revision_id);
1032 1032
     }
1033 1033
 
1034 1034
 
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
         if ( ! empty($id) && get_option('permalink_structure') !== '') {
1107 1107
             $post = get_post($id);
1108 1108
             if (isset($post->post_type) && $this->page_slug === $post->post_type) {
1109
-                $shortlink = home_url('?p=' . $post->ID);
1109
+                $shortlink = home_url('?p='.$post->ID);
1110 1110
             }
1111 1111
         }
1112 1112
         return $shortlink;
@@ -1141,11 +1141,11 @@  discard block
 block discarded – undo
1141 1141
      */
1142 1142
     public function cpt_post_form_hidden_input()
1143 1143
     {
1144
-        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="' . $this->_admin_base_url . '" />';
1144
+        echo '<input type="hidden" name="ee_cpt_item_redirect_url" value="'.$this->_admin_base_url.'" />';
1145 1145
         //we're also going to add the route value and the current page so we can direct autosave parsing correctly
1146 1146
         echo '<div id="ee-cpt-hidden-inputs">';
1147
-        echo '<input type="hidden" id="current_route" name="current_route" value="' . $this->_current_view . '" />';
1148
-        echo '<input type="hidden" id="current_page" name="current_page" value="' . $this->page_slug . '" />';
1147
+        echo '<input type="hidden" id="current_route" name="current_route" value="'.$this->_current_view.'" />';
1148
+        echo '<input type="hidden" id="current_page" name="current_page" value="'.$this->page_slug.'" />';
1149 1149
         echo '</div>';
1150 1150
     }
1151 1151
 
@@ -1232,7 +1232,7 @@  discard block
 block discarded – undo
1232 1232
         $this->_set_model_object($post->ID, true);
1233 1233
 
1234 1234
         //returns something like `trash_event` or `trash_attendee` or `trash_venue`
1235
-        $action = 'trash_' . str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1235
+        $action = 'trash_'.str_replace('ee_', '', strtolower(get_class($this->_cpt_model_obj)));
1236 1236
 
1237 1237
         return EE_Admin_Page::add_query_args_and_nonce(
1238 1238
             array(
@@ -1343,39 +1343,39 @@  discard block
 block discarded – undo
1343 1343
             1 => sprintf(
1344 1344
                 __('%1$s updated. %2$sView %1$s%3$s', 'event_espresso'),
1345 1345
                 $this->_cpt_object->labels->singular_name,
1346
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1346
+                '<a href="'.esc_url(get_permalink($id)).'">',
1347 1347
                 '</a>'
1348 1348
             ),
1349 1349
             2 => __('Custom field updated'),
1350 1350
             3 => __('Custom field deleted.'),
1351 1351
             4 => sprintf(__('%1$s updated.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1352 1352
             5 => isset($_GET['revision']) ? sprintf(__('%s restored to revision from %s', 'event_espresso'),
1353
-                $this->_cpt_object->labels->singular_name, wp_post_revision_title((int)$_GET['revision'], false))
1353
+                $this->_cpt_object->labels->singular_name, wp_post_revision_title((int) $_GET['revision'], false))
1354 1354
                 : false,
1355 1355
             6 => sprintf(
1356 1356
                 __('%1$s published. %2$sView %1$s%3$s', 'event_espresso'),
1357 1357
                 $this->_cpt_object->labels->singular_name,
1358
-                '<a href="' . esc_url(get_permalink($id)) . '">',
1358
+                '<a href="'.esc_url(get_permalink($id)).'">',
1359 1359
                 '</a>'
1360 1360
             ),
1361 1361
             7 => sprintf(__('%1$s saved.', 'event_espresso'), $this->_cpt_object->labels->singular_name),
1362 1362
             8 => sprintf(
1363 1363
                 __('%1$s submitted. %2$sPreview %1$s%3$s', 'event_espresso'),
1364 1364
                 $this->_cpt_object->labels->singular_name,
1365
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))) . '">',
1365
+                '<a target="_blank" href="'.esc_url(add_query_arg('preview', 'true', get_permalink($id))).'">',
1366 1366
                 '</a>'
1367 1367
             ),
1368 1368
             9 => sprintf(
1369 1369
                 __('%1$s scheduled for: %2$s. %3$s">Preview %1$s%3$s', 'event_espresso'),
1370 1370
                 $this->_cpt_object->labels->singular_name,
1371
-                '<strong>' . date_i18n(__('M j, Y @ G:i'), strtotime($post->post_date)) . '</strong>',
1372
-                '<a target="_blank" href="' . esc_url(get_permalink($id)),
1371
+                '<strong>'.date_i18n(__('M j, Y @ G:i'), strtotime($post->post_date)).'</strong>',
1372
+                '<a target="_blank" href="'.esc_url(get_permalink($id)),
1373 1373
                 '</a>'
1374 1374
             ),
1375 1375
             10 => sprintf(
1376 1376
                 __('%1$s draft updated. %2$s">Preview page%3$s', 'event_espresso'),
1377 1377
                 $this->_cpt_object->labels->singular_name,
1378
-                '<a target="_blank" href="' . esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1378
+                '<a target="_blank" href="'.esc_url(add_query_arg('preview', 'true', get_permalink($id))),
1379 1379
                 '</a>'
1380 1380
             ),
1381 1381
         );
@@ -1398,7 +1398,7 @@  discard block
 block discarded – undo
1398 1398
         $post_type        = $this->_cpt_routes[$this->_req_action];
1399 1399
         $post_type_object = $this->_cpt_object;
1400 1400
         $title            = $post_type_object->labels->add_new_item;
1401
-        $post    = $post = get_default_post_to_edit($this->_cpt_routes[$this->_req_action], true);
1401
+        $post = $post = get_default_post_to_edit($this->_cpt_routes[$this->_req_action], true);
1402 1402
         add_action('admin_print_styles', array($this, 'add_new_admin_page_global'));
1403 1403
         //modify the default editor title field with default title.
1404 1404
         add_filter('enter_title_here', array($this, 'add_custom_editor_default_title'), 10);
@@ -1433,7 +1433,7 @@  discard block
 block discarded – undo
1433 1433
                     ), 'admin.php');
1434 1434
                 }
1435 1435
             }
1436
-            include_once WP_ADMIN_PATH . 'edit-form-advanced.php';
1436
+            include_once WP_ADMIN_PATH.'edit-form-advanced.php';
1437 1437
         }
1438 1438
     }
1439 1439
 
Please login to merge, or discard this patch.
core/domain/services/custom_post_types/RegisterCustomTaxonomies.php 2 patches
Indentation   +84 added lines, -84 removed lines patch added patch discarded remove patch
@@ -21,96 +21,96 @@
 block discarded – undo
21 21
 class RegisterCustomTaxonomies
22 22
 {
23 23
 
24
-    /**
25
-     * @var CustomTaxonomyDefinitions $custom_taxonomies
26
-     */
27
-    public $custom_taxonomies;
24
+	/**
25
+	 * @var CustomTaxonomyDefinitions $custom_taxonomies
26
+	 */
27
+	public $custom_taxonomies;
28 28
 
29 29
 
30
-    /**
31
-     * RegisterCustomTaxonomies constructor.
32
-     *
33
-     * @param CustomTaxonomyDefinitions $custom_taxonomies
34
-     */
35
-    public function __construct(CustomTaxonomyDefinitions $custom_taxonomies)
36
-    {
37
-        $this->custom_taxonomies = $custom_taxonomies;
38
-    }
30
+	/**
31
+	 * RegisterCustomTaxonomies constructor.
32
+	 *
33
+	 * @param CustomTaxonomyDefinitions $custom_taxonomies
34
+	 */
35
+	public function __construct(CustomTaxonomyDefinitions $custom_taxonomies)
36
+	{
37
+		$this->custom_taxonomies = $custom_taxonomies;
38
+	}
39 39
 
40 40
 
41
-    /**
42
-     * @return void
43
-     * @throws DomainException
44
-     */
45
-    public function registerCustomTaxonomies()
46
-    {
47
-        $custom_taxonomies = $this->custom_taxonomies->getCustomTaxonomyDefinitions();
48
-        foreach ($custom_taxonomies as $taxonomy => $tax) {
49
-            $this->registerCustomTaxonomy(
50
-                $taxonomy,
51
-                $tax['singular_name'],
52
-                $tax['plural_name'],
53
-                $tax['args']
54
-            );
55
-        }
56
-    }
41
+	/**
42
+	 * @return void
43
+	 * @throws DomainException
44
+	 */
45
+	public function registerCustomTaxonomies()
46
+	{
47
+		$custom_taxonomies = $this->custom_taxonomies->getCustomTaxonomyDefinitions();
48
+		foreach ($custom_taxonomies as $taxonomy => $tax) {
49
+			$this->registerCustomTaxonomy(
50
+				$taxonomy,
51
+				$tax['singular_name'],
52
+				$tax['plural_name'],
53
+				$tax['args']
54
+			);
55
+		}
56
+	}
57 57
 
58 58
 
59
-    /**
60
-     * Registers a custom taxonomy. Should be called before registering custom post types,
61
-     * otherwise you should link the taxonomy to the custom post type using 'register_taxonomy_for_object_type'.
62
-     *
63
-     * @param string $taxonomy_name      , eg 'books'
64
-     * @param string $singular_name      internationalized singular name
65
-     * @param string $plural_name        internationalized plural name
66
-     * @param array  $override_arguments like $args on http://codex.wordpress.org/Function_Reference/register_taxonomy
67
-     * @throws DomainException
68
-     */
69
-    public function registerCustomTaxonomy($taxonomy_name, $singular_name, $plural_name, array $override_arguments)
70
-    {
71
-        $result = register_taxonomy(
72
-            $taxonomy_name,
73
-            null,
74
-            $this->prepareArguments(
75
-                $singular_name,
76
-                $plural_name,
77
-                $override_arguments
78
-            )
79
-        );
80
-        if ($result instanceof WP_Error) {
81
-            throw new DomainException($result->get_error_message());
82
-        }
83
-    }
59
+	/**
60
+	 * Registers a custom taxonomy. Should be called before registering custom post types,
61
+	 * otherwise you should link the taxonomy to the custom post type using 'register_taxonomy_for_object_type'.
62
+	 *
63
+	 * @param string $taxonomy_name      , eg 'books'
64
+	 * @param string $singular_name      internationalized singular name
65
+	 * @param string $plural_name        internationalized plural name
66
+	 * @param array  $override_arguments like $args on http://codex.wordpress.org/Function_Reference/register_taxonomy
67
+	 * @throws DomainException
68
+	 */
69
+	public function registerCustomTaxonomy($taxonomy_name, $singular_name, $plural_name, array $override_arguments)
70
+	{
71
+		$result = register_taxonomy(
72
+			$taxonomy_name,
73
+			null,
74
+			$this->prepareArguments(
75
+				$singular_name,
76
+				$plural_name,
77
+				$override_arguments
78
+			)
79
+		);
80
+		if ($result instanceof WP_Error) {
81
+			throw new DomainException($result->get_error_message());
82
+		}
83
+	}
84 84
 
85 85
 
86
-    /**
87
-     * @param string $singular_name
88
-     * @param string $plural_name
89
-     * @param array  $override_arguments
90
-     * @since $VID:$
91
-     * @return array
92
-     */
93
-    protected function prepareArguments($singular_name, $plural_name, array $override_arguments){
94
-        $arguments = array(
95
-            'hierarchical'      => true,
96
-            'labels'            => array(
97
-                'name'          => $plural_name,
98
-                'singular_name' => $singular_name,
99
-            ),
100
-            'show_ui'           => true,
101
-            'show_ee_ui'        => true,
102
-            'show_admin_column' => true,
103
-            'query_var'         => true,
104
-            'show_in_nav_menus' => false,
105
-            'map_meta_cap'      => true
106
-        );
107
-        if ($override_arguments) {
108
-            if (isset($override_args['labels'])) {
109
-                $labels         = array_merge($arguments['labels'], $override_arguments['labels']);
110
-                $arguments['labels'] = $labels;
111
-            }
112
-            $arguments = array_merge($arguments, $override_arguments);
113
-        }
114
-        return $arguments;
115
-    }
86
+	/**
87
+	 * @param string $singular_name
88
+	 * @param string $plural_name
89
+	 * @param array  $override_arguments
90
+	 * @since $VID:$
91
+	 * @return array
92
+	 */
93
+	protected function prepareArguments($singular_name, $plural_name, array $override_arguments){
94
+		$arguments = array(
95
+			'hierarchical'      => true,
96
+			'labels'            => array(
97
+				'name'          => $plural_name,
98
+				'singular_name' => $singular_name,
99
+			),
100
+			'show_ui'           => true,
101
+			'show_ee_ui'        => true,
102
+			'show_admin_column' => true,
103
+			'query_var'         => true,
104
+			'show_in_nav_menus' => false,
105
+			'map_meta_cap'      => true
106
+		);
107
+		if ($override_arguments) {
108
+			if (isset($override_args['labels'])) {
109
+				$labels         = array_merge($arguments['labels'], $override_arguments['labels']);
110
+				$arguments['labels'] = $labels;
111
+			}
112
+			$arguments = array_merge($arguments, $override_arguments);
113
+		}
114
+		return $arguments;
115
+	}
116 116
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -90,7 +90,7 @@  discard block
 block discarded – undo
90 90
      * @since $VID:$
91 91
      * @return array
92 92
      */
93
-    protected function prepareArguments($singular_name, $plural_name, array $override_arguments){
93
+    protected function prepareArguments($singular_name, $plural_name, array $override_arguments) {
94 94
         $arguments = array(
95 95
             'hierarchical'      => true,
96 96
             'labels'            => array(
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
         );
107 107
         if ($override_arguments) {
108 108
             if (isset($override_args['labels'])) {
109
-                $labels         = array_merge($arguments['labels'], $override_arguments['labels']);
109
+                $labels = array_merge($arguments['labels'], $override_arguments['labels']);
110 110
                 $arguments['labels'] = $labels;
111 111
             }
112 112
             $arguments = array_merge($arguments, $override_arguments);
Please login to merge, or discard this patch.
core/domain/services/custom_post_types/RegisterCustomPostTypes.php 2 patches
Indentation   +221 added lines, -221 removed lines patch added patch discarded remove patch
@@ -22,240 +22,240 @@
 block discarded – undo
22 22
 class RegisterCustomPostTypes
23 23
 {
24 24
 
25
-    /**
26
-     * @var CustomPostTypeDefinitions $custom_post_types
27
-     */
28
-    public $custom_post_types;
25
+	/**
26
+	 * @var CustomPostTypeDefinitions $custom_post_types
27
+	 */
28
+	public $custom_post_types;
29 29
 
30
-    /**
31
-     * @var WP_Post_Type[] $wp_post_types
32
-     */
33
-    public $wp_post_types = array();
30
+	/**
31
+	 * @var WP_Post_Type[] $wp_post_types
32
+	 */
33
+	public $wp_post_types = array();
34 34
 
35 35
 
36
-    /**
37
-     * RegisterCustomPostTypes constructor.
38
-     *
39
-     * @param CustomPostTypeDefinitions $custom_post_types
40
-     */
41
-    public function __construct(CustomPostTypeDefinitions $custom_post_types)
42
-    {
43
-        $this->custom_post_types = $custom_post_types;
44
-    }
36
+	/**
37
+	 * RegisterCustomPostTypes constructor.
38
+	 *
39
+	 * @param CustomPostTypeDefinitions $custom_post_types
40
+	 */
41
+	public function __construct(CustomPostTypeDefinitions $custom_post_types)
42
+	{
43
+		$this->custom_post_types = $custom_post_types;
44
+	}
45 45
 
46 46
 
47
-    /**
48
-     * @return WP_Post_Type[]
49
-     */
50
-    public function getRegisteredCustomPostTypes()
51
-    {
52
-        return $this->wp_post_types;
53
-    }
47
+	/**
48
+	 * @return WP_Post_Type[]
49
+	 */
50
+	public function getRegisteredCustomPostTypes()
51
+	{
52
+		return $this->wp_post_types;
53
+	}
54 54
 
55 55
 
56
-    /**
57
-     * @return void
58
-     * @throws DomainException
59
-     */
60
-    public function registerCustomPostTypes()
61
-    {
62
-        $custom_post_types = $this->custom_post_types->getDefinitions();
63
-        foreach ($custom_post_types as $custom_post_type => $CPT) {
64
-            $this->wp_post_types[ $custom_post_type ] = $this->registerCustomPostType(
65
-                $custom_post_type,
66
-                $CPT['singular_name'],
67
-                $CPT['plural_name'],
68
-                $CPT['singular_slug'],
69
-                $CPT['plural_slug'],
70
-                $CPT['args']
71
-            );
72
-        }
73
-    }
56
+	/**
57
+	 * @return void
58
+	 * @throws DomainException
59
+	 */
60
+	public function registerCustomPostTypes()
61
+	{
62
+		$custom_post_types = $this->custom_post_types->getDefinitions();
63
+		foreach ($custom_post_types as $custom_post_type => $CPT) {
64
+			$this->wp_post_types[ $custom_post_type ] = $this->registerCustomPostType(
65
+				$custom_post_type,
66
+				$CPT['singular_name'],
67
+				$CPT['plural_name'],
68
+				$CPT['singular_slug'],
69
+				$CPT['plural_slug'],
70
+				$CPT['args']
71
+			);
72
+		}
73
+	}
74 74
 
75 75
 
76
-    /**
77
-     * Registers a new custom post type. Sets default settings given only the following params.
78
-     * Returns the registered post type object, or an error object.
79
-     *
80
-     * @param string $post_type          the actual post type name
81
-     *                                   IMPORTANT:
82
-     *                                   this must match what the slug is for admin pages related to this CPT
83
-     *                                   Also any models must use this slug as well
84
-     * @param string $singular_name      a pre-internationalized string for the singular name of the objects
85
-     * @param string $plural_name        a pre-internationalized string for the plural name of the objects
86
-     * @param string $singular_slug
87
-     * @param string $plural_slug
88
-     * @param array  $override_arguments exactly like $args as described in
89
-     *                                   http://codex.wordpress.org/Function_Reference/register_post_type
90
-     * @return WP_Post_Type|WP_Error
91
-     * @throws DomainException
92
-     */
93
-    public function registerCustomPostType(
94
-        $post_type,
95
-        $singular_name,
96
-        $plural_name,
97
-        $singular_slug = '',
98
-        $plural_slug = '',
99
-        array $override_arguments = array()
100
-    ) {
101
-        $wp_post_type = register_post_type(
102
-            $post_type,
103
-            $this->prepareArguments(
104
-                $post_type,
105
-                $singular_name,
106
-                $plural_name,
107
-                $singular_slug,
108
-                $plural_slug,
109
-                $override_arguments
110
-            )
111
-        );
112
-        if ($wp_post_type instanceof WP_Error) {
113
-            throw new DomainException($wp_post_type->get_error_message());
114
-        }
115
-        return $wp_post_type;
116
-    }
76
+	/**
77
+	 * Registers a new custom post type. Sets default settings given only the following params.
78
+	 * Returns the registered post type object, or an error object.
79
+	 *
80
+	 * @param string $post_type          the actual post type name
81
+	 *                                   IMPORTANT:
82
+	 *                                   this must match what the slug is for admin pages related to this CPT
83
+	 *                                   Also any models must use this slug as well
84
+	 * @param string $singular_name      a pre-internationalized string for the singular name of the objects
85
+	 * @param string $plural_name        a pre-internationalized string for the plural name of the objects
86
+	 * @param string $singular_slug
87
+	 * @param string $plural_slug
88
+	 * @param array  $override_arguments exactly like $args as described in
89
+	 *                                   http://codex.wordpress.org/Function_Reference/register_post_type
90
+	 * @return WP_Post_Type|WP_Error
91
+	 * @throws DomainException
92
+	 */
93
+	public function registerCustomPostType(
94
+		$post_type,
95
+		$singular_name,
96
+		$plural_name,
97
+		$singular_slug = '',
98
+		$plural_slug = '',
99
+		array $override_arguments = array()
100
+	) {
101
+		$wp_post_type = register_post_type(
102
+			$post_type,
103
+			$this->prepareArguments(
104
+				$post_type,
105
+				$singular_name,
106
+				$plural_name,
107
+				$singular_slug,
108
+				$plural_slug,
109
+				$override_arguments
110
+			)
111
+		);
112
+		if ($wp_post_type instanceof WP_Error) {
113
+			throw new DomainException($wp_post_type->get_error_message());
114
+		}
115
+		return $wp_post_type;
116
+	}
117 117
 
118 118
 
119
-    /**
120
-     * @param string $post_type          the actual post type name
121
-     * @param string $singular_name      a pre-internationalized string for the singular name of the objects
122
-     * @param string $plural_name        a pre-internationalized string for the plural name of the objects
123
-     * @param string $singular_slug
124
-     * @param string $plural_slug
125
-     * @param array $override_arguments The default values set in this function will be overridden
126
-     *                                  by whatever you set in $override_arguments
127
-     * @return array
128
-     */
129
-    protected function prepareArguments(
130
-        $post_type,
131
-        $singular_name,
132
-        $plural_name,
133
-        $singular_slug,
134
-        $plural_slug,
135
-        array $override_arguments = array()
136
-    ) {
137
-        // verify plural slug and singular slug, if they aren't we'll use $singular_name and $plural_name
138
-        $singular_slug = ! empty($singular_slug) ? $singular_slug : $singular_name;
139
-        $plural_slug   = ! empty($plural_slug) ? $plural_slug : $plural_name;
140
-        $labels        = $this->getLabels(
141
-            $singular_name,
142
-            $plural_name,
143
-            $singular_slug,
144
-            $plural_slug
145
-        );
146
-        // note the page_templates arg in the supports index is something specific to EE.
147
-        // WordPress doesn't actually have that in their register_post_type api.
148
-        $arguments = $this->getDefaultArguments($labels, $post_type, $plural_slug);
149
-        if ($override_arguments) {
150
-            if (isset($override_arguments['labels'])) {
151
-                $labels = array_merge($arguments['labels'], $override_arguments['labels']);
152
-            }
153
-            $arguments           = array_merge($arguments, $override_arguments);
154
-            $arguments['labels'] = $labels;
155
-        }
156
-        return $arguments;
157
-    }
119
+	/**
120
+	 * @param string $post_type          the actual post type name
121
+	 * @param string $singular_name      a pre-internationalized string for the singular name of the objects
122
+	 * @param string $plural_name        a pre-internationalized string for the plural name of the objects
123
+	 * @param string $singular_slug
124
+	 * @param string $plural_slug
125
+	 * @param array $override_arguments The default values set in this function will be overridden
126
+	 *                                  by whatever you set in $override_arguments
127
+	 * @return array
128
+	 */
129
+	protected function prepareArguments(
130
+		$post_type,
131
+		$singular_name,
132
+		$plural_name,
133
+		$singular_slug,
134
+		$plural_slug,
135
+		array $override_arguments = array()
136
+	) {
137
+		// verify plural slug and singular slug, if they aren't we'll use $singular_name and $plural_name
138
+		$singular_slug = ! empty($singular_slug) ? $singular_slug : $singular_name;
139
+		$plural_slug   = ! empty($plural_slug) ? $plural_slug : $plural_name;
140
+		$labels        = $this->getLabels(
141
+			$singular_name,
142
+			$plural_name,
143
+			$singular_slug,
144
+			$plural_slug
145
+		);
146
+		// note the page_templates arg in the supports index is something specific to EE.
147
+		// WordPress doesn't actually have that in their register_post_type api.
148
+		$arguments = $this->getDefaultArguments($labels, $post_type, $plural_slug);
149
+		if ($override_arguments) {
150
+			if (isset($override_arguments['labels'])) {
151
+				$labels = array_merge($arguments['labels'], $override_arguments['labels']);
152
+			}
153
+			$arguments           = array_merge($arguments, $override_arguments);
154
+			$arguments['labels'] = $labels;
155
+		}
156
+		return $arguments;
157
+	}
158 158
 
159 159
 
160
-    /**
161
-     * @param string $singular_name
162
-     * @param string $plural_name
163
-     * @param string $singular_slug
164
-     * @param string $plural_slug
165
-     * @return array
166
-     */
167
-    private function getLabels($singular_name, $plural_name, $singular_slug, $plural_slug)
168
-    {
169
-        return array(
170
-            'name'               => $plural_name,
171
-            'singular_name'      => $singular_name,
172
-            'singular_slug'      => $singular_slug,
173
-            'plural_slug'        => $plural_slug,
174
-            'add_new'            => sprintf(
175
-                esc_html_x('Add %s', 'Add Event', 'event_espresso'),
176
-                $singular_name
177
-            ),
178
-            'add_new_item'       => sprintf(
179
-                esc_html_x('Add New %s', 'Add New Event', 'event_espresso'),
180
-                $singular_name
181
-            ),
182
-            'edit_item'          => sprintf(
183
-                esc_html_x('Edit %s', 'Edit Event', 'event_espresso'),
184
-                $singular_name
185
-            ),
186
-            'new_item'           => sprintf(
187
-                esc_html_x('New %s', 'New Event', 'event_espresso'),
188
-                $singular_name
189
-            ),
190
-            'all_items'          => sprintf(
191
-                esc_html_x('All %s', 'All Events', 'event_espresso'),
192
-                $plural_name
193
-            ),
194
-            'view_item'          => sprintf(
195
-                esc_html_x('View %s', 'View Event', 'event_espresso'),
196
-                $singular_name
197
-            ),
198
-            'search_items'       => sprintf(
199
-                esc_html_x('Search %s', 'Search Events', 'event_espresso'),
200
-                $plural_name
201
-            ),
202
-            'not_found'          => sprintf(
203
-                esc_html_x('No %s found', 'No Events found', 'event_espresso'),
204
-                $plural_name
205
-            ),
206
-            'not_found_in_trash' => sprintf(
207
-                esc_html_x('No %s found in Trash', 'No Events found in Trash', 'event_espresso'),
208
-                $plural_name
209
-            ),
210
-            'parent_item_colon'  => '',
211
-            'menu_name'          => $plural_name,
212
-        );
213
-    }
160
+	/**
161
+	 * @param string $singular_name
162
+	 * @param string $plural_name
163
+	 * @param string $singular_slug
164
+	 * @param string $plural_slug
165
+	 * @return array
166
+	 */
167
+	private function getLabels($singular_name, $plural_name, $singular_slug, $plural_slug)
168
+	{
169
+		return array(
170
+			'name'               => $plural_name,
171
+			'singular_name'      => $singular_name,
172
+			'singular_slug'      => $singular_slug,
173
+			'plural_slug'        => $plural_slug,
174
+			'add_new'            => sprintf(
175
+				esc_html_x('Add %s', 'Add Event', 'event_espresso'),
176
+				$singular_name
177
+			),
178
+			'add_new_item'       => sprintf(
179
+				esc_html_x('Add New %s', 'Add New Event', 'event_espresso'),
180
+				$singular_name
181
+			),
182
+			'edit_item'          => sprintf(
183
+				esc_html_x('Edit %s', 'Edit Event', 'event_espresso'),
184
+				$singular_name
185
+			),
186
+			'new_item'           => sprintf(
187
+				esc_html_x('New %s', 'New Event', 'event_espresso'),
188
+				$singular_name
189
+			),
190
+			'all_items'          => sprintf(
191
+				esc_html_x('All %s', 'All Events', 'event_espresso'),
192
+				$plural_name
193
+			),
194
+			'view_item'          => sprintf(
195
+				esc_html_x('View %s', 'View Event', 'event_espresso'),
196
+				$singular_name
197
+			),
198
+			'search_items'       => sprintf(
199
+				esc_html_x('Search %s', 'Search Events', 'event_espresso'),
200
+				$plural_name
201
+			),
202
+			'not_found'          => sprintf(
203
+				esc_html_x('No %s found', 'No Events found', 'event_espresso'),
204
+				$plural_name
205
+			),
206
+			'not_found_in_trash' => sprintf(
207
+				esc_html_x('No %s found in Trash', 'No Events found in Trash', 'event_espresso'),
208
+				$plural_name
209
+			),
210
+			'parent_item_colon'  => '',
211
+			'menu_name'          => $plural_name,
212
+		);
213
+	}
214 214
 
215 215
 
216
-    /**
217
-     * @param array  $labels
218
-     * @param string $post_type
219
-     * @param string $plural_slug
220
-     * @return array
221
-     */
222
-    private function getDefaultArguments(array $labels, $post_type, $plural_slug)
223
-    {
224
-        return array(
225
-            'labels'             => $labels,
226
-            'public'             => true,
227
-            'publicly_queryable' => true,
228
-            'show_ui'            => false,
229
-            'show_ee_ui'         => true,
230
-            'show_in_menu'       => false,
231
-            'show_in_nav_menus'  => false,
232
-            'query_var'          => true,
233
-            'rewrite'            => apply_filters(
234
-                'FHEE__EventEspresso_core_domain_entities_custom_post_types_RegisterCustomPostTypes__getDefaultArguments__rewrite',
235
-                // legacy filter applied for now,
236
-                // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
237
-                apply_filters(
238
-                    'FHEE__EE_Register_CPTs__register_CPT__rewrite',
239
-                    array('slug' => $plural_slug),
240
-                    $post_type
241
-                ),
242
-                $post_type,
243
-                $plural_slug
244
-            ),
245
-            'capability_type'    => 'post',
246
-            'map_meta_cap'       => true,
247
-            'has_archive'        => true,
248
-            'hierarchical'       => false,
249
-            'menu_position'      => null,
250
-            'supports'           => array(
251
-                'title',
252
-                'editor',
253
-                'author',
254
-                'thumbnail',
255
-                'excerpt',
256
-                'custom-fields',
257
-                'comments',
258
-            ),
259
-        );
260
-    }
216
+	/**
217
+	 * @param array  $labels
218
+	 * @param string $post_type
219
+	 * @param string $plural_slug
220
+	 * @return array
221
+	 */
222
+	private function getDefaultArguments(array $labels, $post_type, $plural_slug)
223
+	{
224
+		return array(
225
+			'labels'             => $labels,
226
+			'public'             => true,
227
+			'publicly_queryable' => true,
228
+			'show_ui'            => false,
229
+			'show_ee_ui'         => true,
230
+			'show_in_menu'       => false,
231
+			'show_in_nav_menus'  => false,
232
+			'query_var'          => true,
233
+			'rewrite'            => apply_filters(
234
+				'FHEE__EventEspresso_core_domain_entities_custom_post_types_RegisterCustomPostTypes__getDefaultArguments__rewrite',
235
+				// legacy filter applied for now,
236
+				// later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
237
+				apply_filters(
238
+					'FHEE__EE_Register_CPTs__register_CPT__rewrite',
239
+					array('slug' => $plural_slug),
240
+					$post_type
241
+				),
242
+				$post_type,
243
+				$plural_slug
244
+			),
245
+			'capability_type'    => 'post',
246
+			'map_meta_cap'       => true,
247
+			'has_archive'        => true,
248
+			'hierarchical'       => false,
249
+			'menu_position'      => null,
250
+			'supports'           => array(
251
+				'title',
252
+				'editor',
253
+				'author',
254
+				'thumbnail',
255
+				'excerpt',
256
+				'custom-fields',
257
+				'comments',
258
+			),
259
+		);
260
+	}
261 261
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -61,7 +61,7 @@
 block discarded – undo
61 61
     {
62 62
         $custom_post_types = $this->custom_post_types->getDefinitions();
63 63
         foreach ($custom_post_types as $custom_post_type => $CPT) {
64
-            $this->wp_post_types[ $custom_post_type ] = $this->registerCustomPostType(
64
+            $this->wp_post_types[$custom_post_type] = $this->registerCustomPostType(
65 65
                 $custom_post_type,
66 66
                 $CPT['singular_name'],
67 67
                 $CPT['plural_name'],
Please login to merge, or discard this patch.
modules/ticket_sales_monitor/EED_Ticket_Sales_Monitor.module.php 2 patches
Indentation   +1076 added lines, -1076 removed lines patch added patch discarded remove patch
@@ -24,1083 +24,1083 @@
 block discarded – undo
24 24
 class EED_Ticket_Sales_Monitor extends EED_Module
25 25
 {
26 26
 
27
-    const debug = false;    //	true false
28
-
29
-    private static $nl = '';
30
-
31
-    /**
32
-     * an array of raw ticket data from EED_Ticket_Selector
33
-     *
34
-     * @var array $ticket_selections
35
-     */
36
-    protected $ticket_selections = array();
37
-
38
-    /**
39
-     * the raw ticket data from EED_Ticket_Selector is organized in rows
40
-     * according to how they are displayed in the actual Ticket_Selector
41
-     * this tracks the current row being processed
42
-     *
43
-     * @var int $current_row
44
-     */
45
-    protected $current_row = 0;
46
-
47
-    /**
48
-     * an array for tracking names of tickets that have sold out
49
-     *
50
-     * @var array $sold_out_tickets
51
-     */
52
-    protected $sold_out_tickets = array();
53
-
54
-    /**
55
-     * an array for tracking names of tickets that have had their quantities reduced
56
-     *
57
-     * @var array $decremented_tickets
58
-     */
59
-    protected $decremented_tickets = array();
60
-
61
-
62
-
63
-    /**
64
-     * set_hooks - for hooking into EE Core, other modules, etc
65
-     *
66
-     * @return    void
67
-     */
68
-    public static function set_hooks()
69
-    {
70
-        self::$nl = defined('EE_TESTS_DIR')? "\n" : '<br />';
71
-        // release tickets for expired carts
72
-        add_action(
73
-            'EED_Ticket_Selector__process_ticket_selections__before',
74
-            array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
75
-            1
76
-        );
77
-        // check ticket reserves AFTER MER does it's check (hence priority 20)
78
-        add_filter(
79
-            'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
80
-            array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
81
-            20,
82
-            3
83
-        );
84
-        // add notices for sold out tickets
85
-        add_action(
86
-            'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
87
-            array('EED_Ticket_Sales_Monitor', 'post_notices'),
88
-            10
89
-        );
90
-        // handle ticket quantities adjusted in cart
91
-        //add_action(
92
-        //	'FHEE__EED_Multi_Event_Registration__adjust_line_item_quantity__line_item_quantity_updated',
93
-        //	array( 'EED_Ticket_Sales_Monitor', 'ticket_quantity_updated' ),
94
-        //	10, 2
95
-        //);
96
-        // handle tickets deleted from cart
97
-        add_action(
98
-            'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
99
-            array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
100
-            10,
101
-            2
102
-        );
103
-        // handle emptied carts
104
-        add_action(
105
-            'AHEE__EE_Session__reset_cart__before_reset',
106
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
107
-            10,
108
-            1
109
-        );
110
-        add_action(
111
-            'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
112
-            array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
113
-            10,
114
-            1
115
-        );
116
-        // handle cancelled registrations
117
-        add_action(
118
-            'AHEE__EE_Session__reset_checkout__before_reset',
119
-            array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
120
-            10,
121
-            1
122
-        );
123
-        // cron tasks
124
-        add_action(
125
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
126
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
127
-            10,
128
-            1
129
-        );
130
-        add_action(
131
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
132
-            array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
133
-            10,
134
-            1
135
-        );
136
-        add_action(
137
-            'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
138
-            array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
139
-            10,
140
-            1
141
-        );
142
-    }
143
-
144
-
145
-
146
-    /**
147
-     * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
148
-     *
149
-     * @return void
150
-     */
151
-    public static function set_hooks_admin()
152
-    {
153
-        EED_Ticket_Sales_Monitor::set_hooks();
154
-    }
155
-
156
-
157
-
158
-    /**
159
-     * @return EED_Ticket_Sales_Monitor|EED_Module
160
-     */
161
-    public static function instance()
162
-    {
163
-        return parent::get_instance(__CLASS__);
164
-    }
165
-
166
-
167
-
168
-    /**
169
-     * @param WP_Query $WP_Query
170
-     * @return    void
171
-     */
172
-    public function run($WP_Query)
173
-    {
174
-    }
175
-
176
-
177
-
178
-    /********************************** PRE_TICKET_SALES  **********************************/
179
-
180
-
181
-
182
-    /**
183
-     * Retrieves grand totals from the line items that have no TXN ID
184
-     * and timestamps less than the current time minus the session lifespan.
185
-     * These are carts that have been abandoned before the "registrant" even attempted to checkout.
186
-     * We're going to release the tickets for these line items before attempting to add more to the cart.
187
-     *
188
-     * @return void
189
-     * @throws DomainException
190
-     * @throws EE_Error
191
-     * @throws InvalidArgumentException
192
-     * @throws InvalidDataTypeException
193
-     * @throws InvalidInterfaceException
194
-     * @throws UnexpectedEntityException
195
-     */
196
-    public static function release_tickets_for_expired_carts()
197
-    {
198
-        if (self::debug) {
199
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
200
-        }
201
-        do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
202
-        $expired_ticket_IDs = array();
203
-        /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
204
-        $session_lifespan = LoaderFactory::getLoader()->getShared(
205
-            'EventEspresso\core\domain\values\session\SessionLifespan'
206
-        );
207
-        $timestamp = $session_lifespan->expiration();
208
-        $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
209
-        if (self::debug) {
210
-            echo self::$nl . ' . time(): ' . time();
211
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
212
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
213
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
214
-            echo self::$nl . ' . timestamp: ' . $timestamp;
215
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
216
-        }
217
-        if (! empty($expired_ticket_line_items)) {
218
-            foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
219
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
220
-                    continue;
221
-                }
222
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
223
-                if (self::debug) {
224
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
225
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): ' . date('Y-m-d h:i a',
226
-                            $expired_ticket_line_item->timestamp(true));
227
-                }
228
-            }
229
-            if (! empty($expired_ticket_IDs)) {
230
-                EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
231
-                    \EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
232
-                    array(),
233
-                    __FUNCTION__
234
-                );
235
-                // now  let's get rid of expired line items so that they can't interfere with tracking
236
-                EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
237
-            }
238
-        }
239
-        do_action(
240
-            'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
241
-            $expired_ticket_IDs,
242
-            $expired_ticket_line_items
243
-        );
244
-    }
245
-
246
-
247
-
248
-    /********************************** VALIDATE_TICKET_SALE  **********************************/
249
-
250
-
251
-
252
-    /**
253
-     * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
254
-     *
255
-     * @param int       $qty
256
-     * @param EE_Ticket $ticket
257
-     * @return bool
258
-     * @throws UnexpectedEntityException
259
-     * @throws EE_Error
260
-     */
261
-    public static function validate_ticket_sale($qty = 1, EE_Ticket $ticket)
262
-    {
263
-        $qty = absint($qty);
264
-        if ($qty > 0) {
265
-            $qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
266
-        }
267
-        if (self::debug) {
268
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
269
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
270
-        }
271
-        return $qty;
272
-    }
273
-
274
-
275
-
276
-    /**
277
-     * checks whether an individual ticket is available for purchase based on datetime, and ticket details
278
-     *
279
-     * @param   EE_Ticket $ticket
280
-     * @param int         $qty
281
-     * @return int
282
-     * @throws UnexpectedEntityException
283
-     * @throws EE_Error
284
-     */
285
-    protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
286
-    {
287
-        if (self::debug) {
288
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
289
-        }
290
-        if (! $ticket instanceof EE_Ticket) {
291
-            return 0;
292
-        }
293
-        if (self::debug) {
294
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
295
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
296
-        }
297
-        $ticket->refresh_from_db();
298
-        // first let's determine the ticket availability based on sales
299
-        $available = $ticket->qty('saleable');
300
-        if (self::debug) {
301
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
302
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
303
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
304
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
305
-            echo self::$nl . ' . . . available: ' . $available;
306
-        }
307
-        if ($available < 1) {
308
-            $this->_ticket_sold_out($ticket);
309
-            return 0;
310
-        }
311
-        if (self::debug) {
312
-            echo self::$nl . ' . . . qty: ' . $qty;
313
-        }
314
-        if ($available < $qty) {
315
-            $qty = $available;
316
-            if (self::debug) {
317
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
318
-            }
319
-            $this->_ticket_quantity_decremented($ticket);
320
-        }
321
-        $this->_reserve_ticket($ticket, $qty);
322
-        return $qty;
323
-    }
324
-
325
-
326
-
327
-    /**
328
-     * increments ticket reserved based on quantity passed
329
-     *
330
-     * @param    EE_Ticket $ticket
331
-     * @param int          $quantity
332
-     * @return bool
333
-     * @throws EE_Error
334
-     */
335
-    protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
336
-    {
337
-        if (self::debug) {
338
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
339
-        }
340
-        $ticket->increase_reserved($quantity, 'TicketSalesMonitor:'. __LINE__);
341
-        return $ticket->save();
342
-    }
343
-
344
-
345
-
346
-    /**
347
-     * @param  EE_Ticket $ticket
348
-     * @param  int       $quantity
349
-     * @return bool
350
-     * @throws EE_Error
351
-     */
352
-    protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
353
-    {
354
-        if (self::debug) {
355
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
356
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
357
-        }
358
-        $ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:'. __LINE__);
359
-        if (self::debug) {
360
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
361
-        }
362
-        return $ticket->save() ? 1 : 0;
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     * removes quantities within the ticket selector based on zero ticket availability
369
-     *
370
-     * @param    EE_Ticket $ticket
371
-     * @return    void
372
-     * @throws UnexpectedEntityException
373
-     * @throws EE_Error
374
-     */
375
-    protected function _ticket_sold_out(EE_Ticket $ticket)
376
-    {
377
-        if (self::debug) {
378
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
379
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
380
-        }
381
-        $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
382
-    }
383
-
384
-
385
-
386
-    /**
387
-     * adjusts quantities within the ticket selector based on decreased ticket availability
388
-     *
389
-     * @param    EE_Ticket $ticket
390
-     * @return void
391
-     * @throws UnexpectedEntityException
392
-     * @throws EE_Error
393
-     */
394
-    protected function _ticket_quantity_decremented(EE_Ticket $ticket)
395
-    {
396
-        if (self::debug) {
397
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
398
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
399
-        }
400
-        $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
401
-    }
402
-
403
-
404
-
405
-    /**
406
-     * builds string out of ticket and event name
407
-     *
408
-     * @param    EE_Ticket $ticket
409
-     * @return string
410
-     * @throws UnexpectedEntityException
411
-     * @throws EE_Error
412
-     */
413
-    protected function _get_ticket_and_event_name(EE_Ticket $ticket)
414
-    {
415
-        $event = $ticket->get_related_event();
416
-        if ($event instanceof EE_Event) {
417
-            $ticket_name = sprintf(
418
-                _x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
419
-                $ticket->name(),
420
-                $event->name()
421
-            );
422
-        } else {
423
-            $ticket_name = $ticket->name();
424
-        }
425
-        return $ticket_name;
426
-    }
427
-
428
-
429
-
430
-    /********************************** EVENT CART  **********************************/
431
-
432
-
433
-
434
-    /**
435
-     * releases or reserves ticket(s) based on quantity passed
436
-     *
437
-     * @param  EE_Line_Item $line_item
438
-     * @param  int          $quantity
439
-     * @return void
440
-     * @throws EE_Error
441
-     * @throws InvalidArgumentException
442
-     * @throws InvalidDataTypeException
443
-     * @throws InvalidInterfaceException
444
-     */
445
-    public static function ticket_quantity_updated(EE_Line_Item $line_item, $quantity = 1)
446
-    {
447
-        $ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
448
-        if ($ticket instanceof EE_Ticket) {
449
-            $ticket->add_extra_meta(
450
-                EE_Ticket::META_KEY_TICKET_RESERVATIONS,
451
-                __LINE__ . ') ' . __METHOD__ . '()'
452
-            );
453
-            if ($quantity > 0) {
454
-                EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
455
-            } else {
456
-                EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
457
-            }
458
-        }
459
-    }
460
-
461
-
462
-
463
-    /**
464
-     * releases reserved ticket(s) based on quantity passed
465
-     *
466
-     * @param  EE_Ticket $ticket
467
-     * @param  int       $quantity
468
-     * @return void
469
-     * @throws EE_Error
470
-     */
471
-    public static function ticket_removed_from_cart(EE_Ticket $ticket, $quantity = 1)
472
-    {
473
-        $ticket->add_extra_meta(
474
-            EE_Ticket::META_KEY_TICKET_RESERVATIONS,
475
-            __LINE__ . ') ' . __METHOD__ . '()'
476
-        );
477
-        EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
478
-    }
479
-
480
-
481
-
482
-    /********************************** POST_NOTICES  **********************************/
483
-
484
-
485
-
486
-    /**
487
-     * @return void
488
-     * @throws EE_Error
489
-     * @throws InvalidArgumentException
490
-     * @throws ReflectionException
491
-     * @throws InvalidDataTypeException
492
-     * @throws InvalidInterfaceException
493
-     */
494
-    public static function post_notices()
495
-    {
496
-        EED_Ticket_Sales_Monitor::instance()->_post_notices();
497
-    }
498
-
499
-
500
-
501
-    /**
502
-     * @return void
503
-     * @throws EE_Error
504
-     * @throws InvalidArgumentException
505
-     * @throws ReflectionException
506
-     * @throws InvalidDataTypeException
507
-     * @throws InvalidInterfaceException
508
-     */
509
-    protected function _post_notices()
510
-    {
511
-        if (self::debug) {
512
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
513
-        }
514
-        $refresh_msg    = '';
515
-        $none_added_msg = '';
516
-        if (defined('DOING_AJAX') && DOING_AJAX) {
517
-            $refresh_msg    = __(
518
-                'Please refresh the page to view updated ticket quantities.',
519
-                'event_espresso'
520
-            );
521
-            $none_added_msg = __('No tickets were added for the event.', 'event_espresso');
522
-        }
523
-        if (! empty($this->sold_out_tickets)) {
524
-            EE_Error::add_attention(
525
-                sprintf(
526
-                    apply_filters(
527
-                        'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
528
-                        __(
529
-                            'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
530
-                            'event_espresso'
531
-                        )
532
-                    ),
533
-                    '<br />',
534
-                    implode('<br />', $this->sold_out_tickets),
535
-                    $none_added_msg,
536
-                    $refresh_msg
537
-                )
538
-            );
539
-            // alter code flow in the Ticket Selector for better UX
540
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
541
-            add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
542
-            $this->sold_out_tickets = array();
543
-            // and reset the cart
544
-            EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
545
-        }
546
-        if (! empty($this->decremented_tickets)) {
547
-            EE_Error::add_attention(
548
-                sprintf(
549
-                    apply_filters(
550
-                        'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
551
-                        __(
552
-                            'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
553
-                            'event_espresso'
554
-                        )
555
-                    ),
556
-                    '<br />',
557
-                    implode('<br />', $this->decremented_tickets),
558
-                    $none_added_msg,
559
-                    $refresh_msg
560
-                )
561
-            );
562
-            $this->decremented_tickets = array();
563
-        }
564
-    }
565
-
566
-
567
-
568
-    /********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
569
-
570
-
571
-
572
-    /**
573
-     * releases reserved tickets for all registrations of an EE_Transaction
574
-     * by default, will NOT release tickets for finalized transactions
575
-     *
576
-     * @param    EE_Transaction $transaction
577
-     * @return int
578
-     * @throws EE_Error
579
-     * @throws InvalidSessionDataException
580
-     */
581
-    protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
582
-    {
583
-        if (self::debug) {
584
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
585
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
586
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
587
-        }
588
-        // check if 'finalize_registration' step has been completed...
589
-        $finalized = $transaction->reg_step_completed('finalize_registration');
590
-        if (self::debug) {
591
-            // DEBUG LOG
592
-            EEH_Debug_Tools::log(
593
-                __CLASS__,
594
-                __FUNCTION__,
595
-                __LINE__,
596
-                array('finalized' => $finalized),
597
-                false,
598
-                'EE_Transaction: ' . $transaction->ID()
599
-            );
600
-        }
601
-        // how many tickets were released
602
-        $count = 0;
603
-        if (self::debug) {
604
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
605
-        }
606
-        $release_tickets_with_TXN_status = array(
607
-            EEM_Transaction::failed_status_code,
608
-            EEM_Transaction::abandoned_status_code,
609
-            EEM_Transaction::incomplete_status_code,
610
-        );
611
-        $events = array();
612
-        // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
613
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
614
-            // cancel any reserved tickets for registrations that were not approved
615
-            $registrations = $transaction->registrations();
616
-            if (self::debug) {
617
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
618
-                $reg    = reset($registrations);
619
-                $ticket = $reg->ticket();
620
-                if ($ticket instanceof EE_Ticket) {
621
-                    $ticket->add_extra_meta(
622
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
623
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
624
-                    );
625
-                }
626
-            }
627
-            if (! empty($registrations)) {
628
-                foreach ($registrations as $registration) {
629
-                    if (
630
-                        $registration instanceof EE_Registration
631
-                        && $this->_release_reserved_ticket_for_registration($registration, $transaction)
632
-                    ) {
633
-                        $count++;
634
-                        $events[ $registration->event_ID() ] = $registration->event();
635
-                    }
636
-                }
637
-            }
638
-        }
639
-        if ($events !== array()) {
640
-            foreach ($events as $event) {
641
-                /** @var EE_Event $event */
642
-                $event->perform_sold_out_status_check();
643
-            }
644
-        }
645
-        return $count;
646
-    }
647
-
648
-
649
-
650
-    /**
651
-     * releases reserved tickets for an EE_Registration
652
-     * by default, will NOT release tickets for APPROVED registrations
653
-     *
654
-     * @param EE_Registration $registration
655
-     * @param EE_Transaction  $transaction
656
-     * @return int
657
-     * @throws EE_Error
658
-     */
659
-    protected function _release_reserved_ticket_for_registration(
660
-        EE_Registration $registration,
661
-        EE_Transaction $transaction
662
-    ) {
663
-        $STS_ID = $transaction->status_ID();
664
-        if (self::debug) {
665
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
666
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
667
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
668
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
669
-        }
670
-        if (
671
-            // release Tickets for Failed Transactions and Abandoned Transactions
672
-            $STS_ID === EEM_Transaction::failed_status_code
673
-            || $STS_ID === EEM_Transaction::abandoned_status_code
674
-            || (
675
-                // also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
676
-                $STS_ID === EEM_Transaction::incomplete_status_code
677
-                && $registration->status_ID() !== EEM_Registration::status_id_approved
678
-            )
679
-        ) {
680
-            if (self::debug) {
681
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
682
-                $rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
683
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
684
-                var_dump($rsrvd);
685
-            }
686
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:'. __LINE__);
687
-            return 1;
688
-        }
689
-        return 0;
690
-    }
691
-
692
-
693
-
694
-    /********************************** SESSION_CART_RESET  **********************************/
695
-
696
-
697
-
698
-    /**
699
-     * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
700
-     *
701
-     * @param EE_Session $session
702
-     * @return void
703
-     * @throws EE_Error
704
-     * @throws InvalidArgumentException
705
-     * @throws ReflectionException
706
-     * @throws InvalidDataTypeException
707
-     * @throws InvalidInterfaceException
708
-     */
709
-    public static function session_cart_reset(EE_Session $session)
710
-    {
711
-        // don't release tickets if checkout was already reset
712
-        if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
713
-            return;
714
-        }
715
-        if (self::debug) {
716
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
717
-        }
718
-        // first check of the session has a valid Checkout object
719
-        $checkout = $session->checkout();
720
-        if ($checkout instanceof EE_Checkout) {
721
-            // and use that to clear ticket reservations because it will update the associated registration meta data
722
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
723
-            return;
724
-        }
725
-        $cart = $session->cart();
726
-        if ($cart instanceof EE_Cart) {
727
-            if (self::debug) {
728
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
729
-            }
730
-            EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
731
-        } else {
732
-            if (self::debug) {
733
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
734
-                var_export($cart, true);
735
-            }
736
-        }
737
-    }
738
-
739
-
740
-
741
-    /**
742
-     * releases reserved tickets in the EE_Cart
743
-     *
744
-     * @param EE_Cart $cart
745
-     * @return void
746
-     * @throws EE_Error
747
-     * @throws InvalidArgumentException
748
-     * @throws ReflectionException
749
-     * @throws InvalidDataTypeException
750
-     * @throws InvalidInterfaceException
751
-     */
752
-    protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
753
-    {
754
-        if (self::debug) {
755
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
756
-        }
757
-        $ticket_line_items = $cart->get_tickets();
758
-        if (empty($ticket_line_items)) {
759
-            return;
760
-        }
761
-        if (self::debug) {
762
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
763
-        }
764
-        foreach ($ticket_line_items as $ticket_line_item) {
765
-            if (self::debug) {
766
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
767
-            }
768
-            if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
769
-                if (self::debug) {
770
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
771
-                }
772
-                $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
773
-                if ($ticket instanceof EE_Ticket) {
774
-                    if (self::debug) {
775
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
776
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
777
-                    }
778
-                    $ticket->add_extra_meta(
779
-                        EE_Ticket::META_KEY_TICKET_RESERVATIONS,
780
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
781
-                    );
782
-                    $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
783
-                }
784
-            }
785
-        }
786
-        if (self::debug) {
787
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
788
-        }
789
-    }
790
-
791
-
792
-
793
-    /********************************** SESSION_CHECKOUT_RESET  **********************************/
794
-
795
-
796
-
797
-    /**
798
-     * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
799
-     *
800
-     * @param EE_Session $session
801
-     * @return void
802
-     * @throws EE_Error
803
-     * @throws InvalidSessionDataException
804
-     */
805
-    public static function session_checkout_reset(EE_Session $session)
806
-    {
807
-        // don't release tickets if cart was already reset
808
-        if(did_action('AHEE__EE_Session__reset_cart__before_reset')) {
809
-            return;
810
-        }
811
-        $checkout = $session->checkout();
812
-        if ($checkout instanceof EE_Checkout) {
813
-            EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
814
-        }
815
-    }
816
-
817
-
818
-
819
-    /**
820
-     * releases reserved tickets for the EE_Checkout->transaction
821
-     *
822
-     * @param EE_Checkout $checkout
823
-     * @return void
824
-     * @throws EE_Error
825
-     * @throws InvalidSessionDataException
826
-     */
827
-    protected function _session_checkout_reset(EE_Checkout $checkout)
828
-    {
829
-        if (self::debug) {
830
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
831
-        }
832
-        // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
833
-        if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
834
-            return;
835
-        }
836
-        $this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
837
-    }
838
-
839
-
840
-
841
-    /********************************** SESSION_EXPIRED_RESET  **********************************/
842
-
843
-
844
-
845
-    /**
846
-     * @param    EE_Session $session
847
-     * @return    void
848
-     */
849
-    public static function session_expired_reset(EE_Session $session)
850
-    {
851
-    }
852
-
853
-
854
-
855
-    /********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
856
-
857
-
858
-
859
-    /**
860
-     * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
861
-     * by default, will NOT release tickets for free transactions, or any that have received a payment
862
-     *
863
-     * @param EE_Transaction $transaction
864
-     * @return void
865
-     * @throws EE_Error
866
-     * @throws InvalidSessionDataException
867
-     */
868
-    public static function process_abandoned_transactions(EE_Transaction $transaction)
869
-    {
870
-        // is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
871
-        if ($transaction->is_free() || $transaction->paid() > 0) {
872
-            if (self::debug) {
873
-                // DEBUG LOG
874
-                EEH_Debug_Tools::log(
875
-                    __CLASS__,
876
-                    __FUNCTION__,
877
-                    __LINE__,
878
-                    array($transaction),
879
-                    false,
880
-                    'EE_Transaction: ' . $transaction->ID()
881
-                );
882
-            }
883
-            return;
884
-        }
885
-        // have their been any successful payments made ?
886
-        $payments = $transaction->payments();
887
-        foreach ($payments as $payment) {
888
-            if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
889
-                if (self::debug) {
890
-                    // DEBUG LOG
891
-                    EEH_Debug_Tools::log(
892
-                        __CLASS__,
893
-                        __FUNCTION__,
894
-                        __LINE__,
895
-                        array($payment),
896
-                        false,
897
-                        'EE_Transaction: ' . $transaction->ID()
898
-                    );
899
-                }
900
-                return;
901
-            }
902
-        }
903
-        // since you haven't even attempted to pay for your ticket...
904
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
905
-    }
906
-
907
-
908
-
909
-    /********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
910
-
911
-
912
-
913
-    /**
914
-     * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
915
-     *
916
-     * @param EE_Transaction $transaction
917
-     * @return void
918
-     * @throws EE_Error
919
-     * @throws InvalidSessionDataException
920
-     */
921
-    public static function process_failed_transactions(EE_Transaction $transaction)
922
-    {
923
-        // since you haven't even attempted to pay for your ticket...
924
-        EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
925
-    }
926
-
927
-
928
-
929
-    /********************************** RESET RESERVATION COUNTS  *********************************/
930
-
931
-
932
-
933
-    /**
934
-     * Resets all ticket and datetime reserved counts to zero
935
-     * Tickets that are currently associated with a Transaction that is in progress
936
-     *
937
-     * @throws EE_Error
938
-     * @throws DomainException
939
-     * @throws InvalidDataTypeException
940
-     * @throws InvalidInterfaceException
941
-     * @throws InvalidArgumentException
942
-     * @throws UnexpectedEntityException
943
-     */
944
-    public static function reset_reservation_counts()
945
-    {
946
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
947
-        $valid_reserved_tickets = array();
948
-        /** @var EE_Transaction[] $transactions_not_in_progress */
949
-        $transactions_not_in_progress = EEM_Transaction::instance()->get_transactions_not_in_progress();
950
-        foreach ($transactions_not_in_progress as $transaction) {
951
-            // if this TXN has been fully completed, then skip it
952
-            if ($transaction->reg_step_completed('finalize_registration')) {
953
-                continue;
954
-            }
955
-            $total_line_item = $transaction->total_line_item();
956
-            // $transaction_in_progress->line
957
-            if (! $total_line_item instanceof EE_Line_Item) {
958
-                throw new DomainException(
959
-                    esc_html__(
960
-                        'Transaction does not have a valid Total Line Item associated with it.',
961
-                        'event_espresso'
962
-                    )
963
-                );
964
-            }
965
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
966
-                $total_line_item
967
-            );
968
-        }
969
-        $total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
970
-        foreach ($total_line_items as $total_line_item) {
971
-            $valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
972
-                $total_line_item
973
-            );
974
-        }
975
-        $tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
976
-        return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
977
-            $tickets_with_reservations,
978
-            $valid_reserved_tickets,
979
-            __FUNCTION__
980
-        );
981
-    }
982
-
983
-
984
-
985
-    /**
986
-     * @param EE_Line_Item $total_line_item
987
-     * @return EE_Line_Item[]
988
-     */
989
-    private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item)
990
-    {
991
-        /** @var EE_Line_Item[] $valid_reserved_tickets */
992
-        $valid_reserved_tickets = array();
993
-        $ticket_line_items      = EEH_Line_Item::get_ticket_line_items($total_line_item);
994
-        foreach ($ticket_line_items as $ticket_line_item) {
995
-            if ($ticket_line_item instanceof EE_Line_Item) {
996
-                $valid_reserved_tickets[] = $ticket_line_item;
997
-            }
998
-        }
999
-        return $valid_reserved_tickets;
1000
-    }
1001
-
1002
-
1003
-
1004
-    /**
1005
-     * @param EE_Ticket[]    $tickets_with_reservations
1006
-     * @param EE_Line_Item[] $valid_reserved_ticket_line_items
1007
-     * @return int
1008
-     * @throws UnexpectedEntityException
1009
-     * @throws DomainException
1010
-     * @throws EE_Error
1011
-     */
1012
-    private static function release_reservations_for_tickets(
1013
-        array $tickets_with_reservations,
1014
-        array $valid_reserved_ticket_line_items = array(),
1015
-        $source
1016
-    ) {
1017
-        if (self::debug) {
1018
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
1019
-        }
1020
-        $total_tickets_released = 0;
1021
-        $sold_out_events = array();
1022
-        foreach ($tickets_with_reservations as $ticket_with_reservations) {
1023
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
1024
-                continue;
1025
-            }
1026
-            $reserved_qty = $ticket_with_reservations->reserved();
1027
-            if (self::debug) {
1028
-                echo self::$nl . ' . $ticket_with_reservations->ID(): ' . $ticket_with_reservations->ID();
1029
-                echo self::$nl . ' . $reserved_qty: ' . $reserved_qty;
1030
-            }
1031
-            foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1032
-                if (
1033
-                    $valid_reserved_ticket_line_item instanceof EE_Line_Item
1034
-                    && $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1035
-                ) {
1036
-                    if (self::debug) {
1037
-                        echo self::$nl . ' . $valid_reserved_ticket_line_item->quantity(): ' . $valid_reserved_ticket_line_item->quantity();
1038
-                    }
1039
-                    $reserved_qty -= $valid_reserved_ticket_line_item->quantity();
1040
-                }
1041
-            }
1042
-            if ($reserved_qty > 0) {
1043
-                $ticket_with_reservations->add_extra_meta(
1044
-                    EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1045
-                    __LINE__ . ') ' . $source . '()'
1046
-                );
1047
-                $ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:'. __LINE__);
1048
-                $ticket_with_reservations->save();
1049
-                $total_tickets_released += $reserved_qty;
1050
-                $event = $ticket_with_reservations->get_related_event();
1051
-                // track sold out events
1052
-                if ($event instanceof EE_Event && $event->is_sold_out()) {
1053
-                    $sold_out_events[] = $event;
1054
-                }
1055
-            }
1056
-        }
1057
-        if (self::debug) {
1058
-            echo self::$nl . ' . $total_tickets_released: ' . $total_tickets_released;
1059
-        }
1060
-        // double check whether sold out events should remain sold out after releasing tickets
1061
-        if($sold_out_events !== array()){
1062
-            foreach ($sold_out_events as $sold_out_event) {
1063
-                /** @var EE_Event $sold_out_event */
1064
-                $sold_out_event->perform_sold_out_status_check();
1065
-            }
1066
-        }
1067
-        return $total_tickets_released;
1068
-    }
1069
-
1070
-
1071
-
1072
-    /********************************** SHUTDOWN  **********************************/
1073
-
1074
-
1075
-
1076
-    /**
1077
-     * @param int $timestamp
1078
-     * @return false|int
1079
-     * @throws EE_Error
1080
-     * @throws InvalidArgumentException
1081
-     * @throws InvalidDataTypeException
1082
-     * @throws InvalidInterfaceException
1083
-     */
1084
-    public static function clear_expired_line_items_with_no_transaction($timestamp = 0)
1085
-    {
1086
-       /** @type WPDB $wpdb */
1087
-        global $wpdb;
1088
-        if (! absint($timestamp)) {
1089
-            /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1090
-            $session_lifespan = LoaderFactory::getLoader()->getShared(
1091
-                'EventEspresso\core\domain\values\session\SessionLifespan'
1092
-            );
1093
-            $timestamp = $session_lifespan->expiration();
1094
-        }
1095
-         return $wpdb->query(
1096
-            $wpdb->prepare(
1097
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
27
+	const debug = false;    //	true false
28
+
29
+	private static $nl = '';
30
+
31
+	/**
32
+	 * an array of raw ticket data from EED_Ticket_Selector
33
+	 *
34
+	 * @var array $ticket_selections
35
+	 */
36
+	protected $ticket_selections = array();
37
+
38
+	/**
39
+	 * the raw ticket data from EED_Ticket_Selector is organized in rows
40
+	 * according to how they are displayed in the actual Ticket_Selector
41
+	 * this tracks the current row being processed
42
+	 *
43
+	 * @var int $current_row
44
+	 */
45
+	protected $current_row = 0;
46
+
47
+	/**
48
+	 * an array for tracking names of tickets that have sold out
49
+	 *
50
+	 * @var array $sold_out_tickets
51
+	 */
52
+	protected $sold_out_tickets = array();
53
+
54
+	/**
55
+	 * an array for tracking names of tickets that have had their quantities reduced
56
+	 *
57
+	 * @var array $decremented_tickets
58
+	 */
59
+	protected $decremented_tickets = array();
60
+
61
+
62
+
63
+	/**
64
+	 * set_hooks - for hooking into EE Core, other modules, etc
65
+	 *
66
+	 * @return    void
67
+	 */
68
+	public static function set_hooks()
69
+	{
70
+		self::$nl = defined('EE_TESTS_DIR')? "\n" : '<br />';
71
+		// release tickets for expired carts
72
+		add_action(
73
+			'EED_Ticket_Selector__process_ticket_selections__before',
74
+			array('EED_Ticket_Sales_Monitor', 'release_tickets_for_expired_carts'),
75
+			1
76
+		);
77
+		// check ticket reserves AFTER MER does it's check (hence priority 20)
78
+		add_filter(
79
+			'FHEE__EE_Ticket_Selector___add_ticket_to_cart__ticket_qty',
80
+			array('EED_Ticket_Sales_Monitor', 'validate_ticket_sale'),
81
+			20,
82
+			3
83
+		);
84
+		// add notices for sold out tickets
85
+		add_action(
86
+			'AHEE__EE_Ticket_Selector__process_ticket_selections__after_tickets_added_to_cart',
87
+			array('EED_Ticket_Sales_Monitor', 'post_notices'),
88
+			10
89
+		);
90
+		// handle ticket quantities adjusted in cart
91
+		//add_action(
92
+		//	'FHEE__EED_Multi_Event_Registration__adjust_line_item_quantity__line_item_quantity_updated',
93
+		//	array( 'EED_Ticket_Sales_Monitor', 'ticket_quantity_updated' ),
94
+		//	10, 2
95
+		//);
96
+		// handle tickets deleted from cart
97
+		add_action(
98
+			'FHEE__EED_Multi_Event_Registration__delete_ticket__ticket_removed_from_cart',
99
+			array('EED_Ticket_Sales_Monitor', 'ticket_removed_from_cart'),
100
+			10,
101
+			2
102
+		);
103
+		// handle emptied carts
104
+		add_action(
105
+			'AHEE__EE_Session__reset_cart__before_reset',
106
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
107
+			10,
108
+			1
109
+		);
110
+		add_action(
111
+			'AHEE__EED_Multi_Event_Registration__empty_event_cart__before_delete_cart',
112
+			array('EED_Ticket_Sales_Monitor', 'session_cart_reset'),
113
+			10,
114
+			1
115
+		);
116
+		// handle cancelled registrations
117
+		add_action(
118
+			'AHEE__EE_Session__reset_checkout__before_reset',
119
+			array('EED_Ticket_Sales_Monitor', 'session_checkout_reset'),
120
+			10,
121
+			1
122
+		);
123
+		// cron tasks
124
+		add_action(
125
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
126
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
127
+			10,
128
+			1
129
+		);
130
+		add_action(
131
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
132
+			array('EED_Ticket_Sales_Monitor', 'process_abandoned_transactions'),
133
+			10,
134
+			1
135
+		);
136
+		add_action(
137
+			'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
138
+			array('EED_Ticket_Sales_Monitor', 'process_failed_transactions'),
139
+			10,
140
+			1
141
+		);
142
+	}
143
+
144
+
145
+
146
+	/**
147
+	 * set_hooks_admin - for hooking into EE Admin Core, other modules, etc
148
+	 *
149
+	 * @return void
150
+	 */
151
+	public static function set_hooks_admin()
152
+	{
153
+		EED_Ticket_Sales_Monitor::set_hooks();
154
+	}
155
+
156
+
157
+
158
+	/**
159
+	 * @return EED_Ticket_Sales_Monitor|EED_Module
160
+	 */
161
+	public static function instance()
162
+	{
163
+		return parent::get_instance(__CLASS__);
164
+	}
165
+
166
+
167
+
168
+	/**
169
+	 * @param WP_Query $WP_Query
170
+	 * @return    void
171
+	 */
172
+	public function run($WP_Query)
173
+	{
174
+	}
175
+
176
+
177
+
178
+	/********************************** PRE_TICKET_SALES  **********************************/
179
+
180
+
181
+
182
+	/**
183
+	 * Retrieves grand totals from the line items that have no TXN ID
184
+	 * and timestamps less than the current time minus the session lifespan.
185
+	 * These are carts that have been abandoned before the "registrant" even attempted to checkout.
186
+	 * We're going to release the tickets for these line items before attempting to add more to the cart.
187
+	 *
188
+	 * @return void
189
+	 * @throws DomainException
190
+	 * @throws EE_Error
191
+	 * @throws InvalidArgumentException
192
+	 * @throws InvalidDataTypeException
193
+	 * @throws InvalidInterfaceException
194
+	 * @throws UnexpectedEntityException
195
+	 */
196
+	public static function release_tickets_for_expired_carts()
197
+	{
198
+		if (self::debug) {
199
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
200
+		}
201
+		do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
202
+		$expired_ticket_IDs = array();
203
+		/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
204
+		$session_lifespan = LoaderFactory::getLoader()->getShared(
205
+			'EventEspresso\core\domain\values\session\SessionLifespan'
206
+		);
207
+		$timestamp = $session_lifespan->expiration();
208
+		$expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
209
+		if (self::debug) {
210
+			echo self::$nl . ' . time(): ' . time();
211
+			echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
212
+			echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
213
+			echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
214
+			echo self::$nl . ' . timestamp: ' . $timestamp;
215
+			echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
216
+		}
217
+		if (! empty($expired_ticket_line_items)) {
218
+			foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
219
+				if (! $expired_ticket_line_item instanceof EE_Line_Item) {
220
+					continue;
221
+				}
222
+				$expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
223
+				if (self::debug) {
224
+					echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
225
+					echo self::$nl . ' . $expired_ticket_line_item->timestamp(): ' . date('Y-m-d h:i a',
226
+							$expired_ticket_line_item->timestamp(true));
227
+				}
228
+			}
229
+			if (! empty($expired_ticket_IDs)) {
230
+				EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
231
+					\EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
232
+					array(),
233
+					__FUNCTION__
234
+				);
235
+				// now  let's get rid of expired line items so that they can't interfere with tracking
236
+				EED_Ticket_Sales_Monitor::clear_expired_line_items_with_no_transaction($timestamp);
237
+			}
238
+		}
239
+		do_action(
240
+			'AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__end',
241
+			$expired_ticket_IDs,
242
+			$expired_ticket_line_items
243
+		);
244
+	}
245
+
246
+
247
+
248
+	/********************************** VALIDATE_TICKET_SALE  **********************************/
249
+
250
+
251
+
252
+	/**
253
+	 * callback for 'FHEE__EED_Ticket_Selector__process_ticket_selections__valid_post_data'
254
+	 *
255
+	 * @param int       $qty
256
+	 * @param EE_Ticket $ticket
257
+	 * @return bool
258
+	 * @throws UnexpectedEntityException
259
+	 * @throws EE_Error
260
+	 */
261
+	public static function validate_ticket_sale($qty = 1, EE_Ticket $ticket)
262
+	{
263
+		$qty = absint($qty);
264
+		if ($qty > 0) {
265
+			$qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
266
+		}
267
+		if (self::debug) {
268
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
269
+			echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
270
+		}
271
+		return $qty;
272
+	}
273
+
274
+
275
+
276
+	/**
277
+	 * checks whether an individual ticket is available for purchase based on datetime, and ticket details
278
+	 *
279
+	 * @param   EE_Ticket $ticket
280
+	 * @param int         $qty
281
+	 * @return int
282
+	 * @throws UnexpectedEntityException
283
+	 * @throws EE_Error
284
+	 */
285
+	protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
286
+	{
287
+		if (self::debug) {
288
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
289
+		}
290
+		if (! $ticket instanceof EE_Ticket) {
291
+			return 0;
292
+		}
293
+		if (self::debug) {
294
+			echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
295
+			echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
296
+		}
297
+		$ticket->refresh_from_db();
298
+		// first let's determine the ticket availability based on sales
299
+		$available = $ticket->qty('saleable');
300
+		if (self::debug) {
301
+			echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
302
+			echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
303
+			echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
304
+			echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
305
+			echo self::$nl . ' . . . available: ' . $available;
306
+		}
307
+		if ($available < 1) {
308
+			$this->_ticket_sold_out($ticket);
309
+			return 0;
310
+		}
311
+		if (self::debug) {
312
+			echo self::$nl . ' . . . qty: ' . $qty;
313
+		}
314
+		if ($available < $qty) {
315
+			$qty = $available;
316
+			if (self::debug) {
317
+				echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
318
+			}
319
+			$this->_ticket_quantity_decremented($ticket);
320
+		}
321
+		$this->_reserve_ticket($ticket, $qty);
322
+		return $qty;
323
+	}
324
+
325
+
326
+
327
+	/**
328
+	 * increments ticket reserved based on quantity passed
329
+	 *
330
+	 * @param    EE_Ticket $ticket
331
+	 * @param int          $quantity
332
+	 * @return bool
333
+	 * @throws EE_Error
334
+	 */
335
+	protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
336
+	{
337
+		if (self::debug) {
338
+			echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
339
+		}
340
+		$ticket->increase_reserved($quantity, 'TicketSalesMonitor:'. __LINE__);
341
+		return $ticket->save();
342
+	}
343
+
344
+
345
+
346
+	/**
347
+	 * @param  EE_Ticket $ticket
348
+	 * @param  int       $quantity
349
+	 * @return bool
350
+	 * @throws EE_Error
351
+	 */
352
+	protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
353
+	{
354
+		if (self::debug) {
355
+			echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
356
+			echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
357
+		}
358
+		$ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:'. __LINE__);
359
+		if (self::debug) {
360
+			echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
361
+		}
362
+		return $ticket->save() ? 1 : 0;
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 * removes quantities within the ticket selector based on zero ticket availability
369
+	 *
370
+	 * @param    EE_Ticket $ticket
371
+	 * @return    void
372
+	 * @throws UnexpectedEntityException
373
+	 * @throws EE_Error
374
+	 */
375
+	protected function _ticket_sold_out(EE_Ticket $ticket)
376
+	{
377
+		if (self::debug) {
378
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
379
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
380
+		}
381
+		$this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
382
+	}
383
+
384
+
385
+
386
+	/**
387
+	 * adjusts quantities within the ticket selector based on decreased ticket availability
388
+	 *
389
+	 * @param    EE_Ticket $ticket
390
+	 * @return void
391
+	 * @throws UnexpectedEntityException
392
+	 * @throws EE_Error
393
+	 */
394
+	protected function _ticket_quantity_decremented(EE_Ticket $ticket)
395
+	{
396
+		if (self::debug) {
397
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
398
+			echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
399
+		}
400
+		$this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
401
+	}
402
+
403
+
404
+
405
+	/**
406
+	 * builds string out of ticket and event name
407
+	 *
408
+	 * @param    EE_Ticket $ticket
409
+	 * @return string
410
+	 * @throws UnexpectedEntityException
411
+	 * @throws EE_Error
412
+	 */
413
+	protected function _get_ticket_and_event_name(EE_Ticket $ticket)
414
+	{
415
+		$event = $ticket->get_related_event();
416
+		if ($event instanceof EE_Event) {
417
+			$ticket_name = sprintf(
418
+				_x('%1$s for %2$s', 'ticket name for event name', 'event_espresso'),
419
+				$ticket->name(),
420
+				$event->name()
421
+			);
422
+		} else {
423
+			$ticket_name = $ticket->name();
424
+		}
425
+		return $ticket_name;
426
+	}
427
+
428
+
429
+
430
+	/********************************** EVENT CART  **********************************/
431
+
432
+
433
+
434
+	/**
435
+	 * releases or reserves ticket(s) based on quantity passed
436
+	 *
437
+	 * @param  EE_Line_Item $line_item
438
+	 * @param  int          $quantity
439
+	 * @return void
440
+	 * @throws EE_Error
441
+	 * @throws InvalidArgumentException
442
+	 * @throws InvalidDataTypeException
443
+	 * @throws InvalidInterfaceException
444
+	 */
445
+	public static function ticket_quantity_updated(EE_Line_Item $line_item, $quantity = 1)
446
+	{
447
+		$ticket = EEM_Ticket::instance()->get_one_by_ID(absint($line_item->OBJ_ID()));
448
+		if ($ticket instanceof EE_Ticket) {
449
+			$ticket->add_extra_meta(
450
+				EE_Ticket::META_KEY_TICKET_RESERVATIONS,
451
+				__LINE__ . ') ' . __METHOD__ . '()'
452
+			);
453
+			if ($quantity > 0) {
454
+				EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
455
+			} else {
456
+				EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
457
+			}
458
+		}
459
+	}
460
+
461
+
462
+
463
+	/**
464
+	 * releases reserved ticket(s) based on quantity passed
465
+	 *
466
+	 * @param  EE_Ticket $ticket
467
+	 * @param  int       $quantity
468
+	 * @return void
469
+	 * @throws EE_Error
470
+	 */
471
+	public static function ticket_removed_from_cart(EE_Ticket $ticket, $quantity = 1)
472
+	{
473
+		$ticket->add_extra_meta(
474
+			EE_Ticket::META_KEY_TICKET_RESERVATIONS,
475
+			__LINE__ . ') ' . __METHOD__ . '()'
476
+		);
477
+		EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
478
+	}
479
+
480
+
481
+
482
+	/********************************** POST_NOTICES  **********************************/
483
+
484
+
485
+
486
+	/**
487
+	 * @return void
488
+	 * @throws EE_Error
489
+	 * @throws InvalidArgumentException
490
+	 * @throws ReflectionException
491
+	 * @throws InvalidDataTypeException
492
+	 * @throws InvalidInterfaceException
493
+	 */
494
+	public static function post_notices()
495
+	{
496
+		EED_Ticket_Sales_Monitor::instance()->_post_notices();
497
+	}
498
+
499
+
500
+
501
+	/**
502
+	 * @return void
503
+	 * @throws EE_Error
504
+	 * @throws InvalidArgumentException
505
+	 * @throws ReflectionException
506
+	 * @throws InvalidDataTypeException
507
+	 * @throws InvalidInterfaceException
508
+	 */
509
+	protected function _post_notices()
510
+	{
511
+		if (self::debug) {
512
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
513
+		}
514
+		$refresh_msg    = '';
515
+		$none_added_msg = '';
516
+		if (defined('DOING_AJAX') && DOING_AJAX) {
517
+			$refresh_msg    = __(
518
+				'Please refresh the page to view updated ticket quantities.',
519
+				'event_espresso'
520
+			);
521
+			$none_added_msg = __('No tickets were added for the event.', 'event_espresso');
522
+		}
523
+		if (! empty($this->sold_out_tickets)) {
524
+			EE_Error::add_attention(
525
+				sprintf(
526
+					apply_filters(
527
+						'FHEE__EED_Ticket_Sales_Monitor___post_notices__sold_out_tickets_notice',
528
+						__(
529
+							'We\'re sorry...%1$sThe following items have sold out since you first viewed this page, and can no longer be registered for:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
530
+							'event_espresso'
531
+						)
532
+					),
533
+					'<br />',
534
+					implode('<br />', $this->sold_out_tickets),
535
+					$none_added_msg,
536
+					$refresh_msg
537
+				)
538
+			);
539
+			// alter code flow in the Ticket Selector for better UX
540
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__tckts_slctd', '__return_true');
541
+			add_filter('FHEE__EED_Ticket_Selector__process_ticket_selections__success', '__return_false');
542
+			$this->sold_out_tickets = array();
543
+			// and reset the cart
544
+			EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
545
+		}
546
+		if (! empty($this->decremented_tickets)) {
547
+			EE_Error::add_attention(
548
+				sprintf(
549
+					apply_filters(
550
+						'FHEE__EED_Ticket_Sales_Monitor___ticket_quantity_decremented__notice',
551
+						__(
552
+							'We\'re sorry...%1$sDue to sales that have occurred since you first viewed the last page, the following items have had their quantities adjusted to match the current available amount:%1$s%1$s%2$s%1$s%1$sPlease note that availability can change at any time due to cancellations, so please check back again later if registration for this event(s) is important to you.%1$s%1$s%3$s%1$s%4$s%1$s',
553
+							'event_espresso'
554
+						)
555
+					),
556
+					'<br />',
557
+					implode('<br />', $this->decremented_tickets),
558
+					$none_added_msg,
559
+					$refresh_msg
560
+				)
561
+			);
562
+			$this->decremented_tickets = array();
563
+		}
564
+	}
565
+
566
+
567
+
568
+	/********************************** RELEASE_ALL_RESERVED_TICKETS_FOR_TRANSACTION  **********************************/
569
+
570
+
571
+
572
+	/**
573
+	 * releases reserved tickets for all registrations of an EE_Transaction
574
+	 * by default, will NOT release tickets for finalized transactions
575
+	 *
576
+	 * @param    EE_Transaction $transaction
577
+	 * @return int
578
+	 * @throws EE_Error
579
+	 * @throws InvalidSessionDataException
580
+	 */
581
+	protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
582
+	{
583
+		if (self::debug) {
584
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
585
+			echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
586
+			echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
587
+		}
588
+		// check if 'finalize_registration' step has been completed...
589
+		$finalized = $transaction->reg_step_completed('finalize_registration');
590
+		if (self::debug) {
591
+			// DEBUG LOG
592
+			EEH_Debug_Tools::log(
593
+				__CLASS__,
594
+				__FUNCTION__,
595
+				__LINE__,
596
+				array('finalized' => $finalized),
597
+				false,
598
+				'EE_Transaction: ' . $transaction->ID()
599
+			);
600
+		}
601
+		// how many tickets were released
602
+		$count = 0;
603
+		if (self::debug) {
604
+			echo self::$nl . ' . . . TXN finalized: ' . $finalized;
605
+		}
606
+		$release_tickets_with_TXN_status = array(
607
+			EEM_Transaction::failed_status_code,
608
+			EEM_Transaction::abandoned_status_code,
609
+			EEM_Transaction::incomplete_status_code,
610
+		);
611
+		$events = array();
612
+		// if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
613
+		if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
614
+			// cancel any reserved tickets for registrations that were not approved
615
+			$registrations = $transaction->registrations();
616
+			if (self::debug) {
617
+				echo self::$nl . ' . . . # registrations: ' . count($registrations);
618
+				$reg    = reset($registrations);
619
+				$ticket = $reg->ticket();
620
+				if ($ticket instanceof EE_Ticket) {
621
+					$ticket->add_extra_meta(
622
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
623
+						__LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
624
+					);
625
+				}
626
+			}
627
+			if (! empty($registrations)) {
628
+				foreach ($registrations as $registration) {
629
+					if (
630
+						$registration instanceof EE_Registration
631
+						&& $this->_release_reserved_ticket_for_registration($registration, $transaction)
632
+					) {
633
+						$count++;
634
+						$events[ $registration->event_ID() ] = $registration->event();
635
+					}
636
+				}
637
+			}
638
+		}
639
+		if ($events !== array()) {
640
+			foreach ($events as $event) {
641
+				/** @var EE_Event $event */
642
+				$event->perform_sold_out_status_check();
643
+			}
644
+		}
645
+		return $count;
646
+	}
647
+
648
+
649
+
650
+	/**
651
+	 * releases reserved tickets for an EE_Registration
652
+	 * by default, will NOT release tickets for APPROVED registrations
653
+	 *
654
+	 * @param EE_Registration $registration
655
+	 * @param EE_Transaction  $transaction
656
+	 * @return int
657
+	 * @throws EE_Error
658
+	 */
659
+	protected function _release_reserved_ticket_for_registration(
660
+		EE_Registration $registration,
661
+		EE_Transaction $transaction
662
+	) {
663
+		$STS_ID = $transaction->status_ID();
664
+		if (self::debug) {
665
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
666
+			echo self::$nl . ' . . registration->ID: ' . $registration->ID();
667
+			echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
668
+			echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
669
+		}
670
+		if (
671
+			// release Tickets for Failed Transactions and Abandoned Transactions
672
+			$STS_ID === EEM_Transaction::failed_status_code
673
+			|| $STS_ID === EEM_Transaction::abandoned_status_code
674
+			|| (
675
+				// also release Tickets for Incomplete Transactions, but ONLY if the Registrations are NOT Approved
676
+				$STS_ID === EEM_Transaction::incomplete_status_code
677
+				&& $registration->status_ID() !== EEM_Registration::status_id_approved
678
+			)
679
+		) {
680
+			if (self::debug) {
681
+				echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
682
+				$rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
683
+				echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
684
+				var_dump($rsrvd);
685
+			}
686
+			$registration->release_reserved_ticket(true, 'TicketSalesMonitor:'. __LINE__);
687
+			return 1;
688
+		}
689
+		return 0;
690
+	}
691
+
692
+
693
+
694
+	/********************************** SESSION_CART_RESET  **********************************/
695
+
696
+
697
+
698
+	/**
699
+	 * callback hooked into 'AHEE__EE_Session__reset_cart__before_reset'
700
+	 *
701
+	 * @param EE_Session $session
702
+	 * @return void
703
+	 * @throws EE_Error
704
+	 * @throws InvalidArgumentException
705
+	 * @throws ReflectionException
706
+	 * @throws InvalidDataTypeException
707
+	 * @throws InvalidInterfaceException
708
+	 */
709
+	public static function session_cart_reset(EE_Session $session)
710
+	{
711
+		// don't release tickets if checkout was already reset
712
+		if (did_action('AHEE__EE_Session__reset_checkout__before_reset')) {
713
+			return;
714
+		}
715
+		if (self::debug) {
716
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
717
+		}
718
+		// first check of the session has a valid Checkout object
719
+		$checkout = $session->checkout();
720
+		if ($checkout instanceof EE_Checkout) {
721
+			// and use that to clear ticket reservations because it will update the associated registration meta data
722
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
723
+			return;
724
+		}
725
+		$cart = $session->cart();
726
+		if ($cart instanceof EE_Cart) {
727
+			if (self::debug) {
728
+				echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
729
+			}
730
+			EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
731
+		} else {
732
+			if (self::debug) {
733
+				echo self::$nl . self::$nl . ' invalid EE_Cart: ';
734
+				var_export($cart, true);
735
+			}
736
+		}
737
+	}
738
+
739
+
740
+
741
+	/**
742
+	 * releases reserved tickets in the EE_Cart
743
+	 *
744
+	 * @param EE_Cart $cart
745
+	 * @return void
746
+	 * @throws EE_Error
747
+	 * @throws InvalidArgumentException
748
+	 * @throws ReflectionException
749
+	 * @throws InvalidDataTypeException
750
+	 * @throws InvalidInterfaceException
751
+	 */
752
+	protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
753
+	{
754
+		if (self::debug) {
755
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
756
+		}
757
+		$ticket_line_items = $cart->get_tickets();
758
+		if (empty($ticket_line_items)) {
759
+			return;
760
+		}
761
+		if (self::debug) {
762
+			echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
763
+		}
764
+		foreach ($ticket_line_items as $ticket_line_item) {
765
+			if (self::debug) {
766
+				echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
767
+			}
768
+			if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
769
+				if (self::debug) {
770
+					echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
771
+				}
772
+				$ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
773
+				if ($ticket instanceof EE_Ticket) {
774
+					if (self::debug) {
775
+						echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
776
+						echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
777
+					}
778
+					$ticket->add_extra_meta(
779
+						EE_Ticket::META_KEY_TICKET_RESERVATIONS,
780
+						__LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
781
+					);
782
+					$this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
783
+				}
784
+			}
785
+		}
786
+		if (self::debug) {
787
+			echo self::$nl . self::$nl . ' RESET COMPLETED ';
788
+		}
789
+	}
790
+
791
+
792
+
793
+	/********************************** SESSION_CHECKOUT_RESET  **********************************/
794
+
795
+
796
+
797
+	/**
798
+	 * callback hooked into 'AHEE__EE_Session__reset_checkout__before_reset'
799
+	 *
800
+	 * @param EE_Session $session
801
+	 * @return void
802
+	 * @throws EE_Error
803
+	 * @throws InvalidSessionDataException
804
+	 */
805
+	public static function session_checkout_reset(EE_Session $session)
806
+	{
807
+		// don't release tickets if cart was already reset
808
+		if(did_action('AHEE__EE_Session__reset_cart__before_reset')) {
809
+			return;
810
+		}
811
+		$checkout = $session->checkout();
812
+		if ($checkout instanceof EE_Checkout) {
813
+			EED_Ticket_Sales_Monitor::instance()->_session_checkout_reset($checkout);
814
+		}
815
+	}
816
+
817
+
818
+
819
+	/**
820
+	 * releases reserved tickets for the EE_Checkout->transaction
821
+	 *
822
+	 * @param EE_Checkout $checkout
823
+	 * @return void
824
+	 * @throws EE_Error
825
+	 * @throws InvalidSessionDataException
826
+	 */
827
+	protected function _session_checkout_reset(EE_Checkout $checkout)
828
+	{
829
+		if (self::debug) {
830
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
831
+		}
832
+		// we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
833
+		if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
834
+			return;
835
+		}
836
+		$this->_release_all_reserved_tickets_for_transaction($checkout->transaction);
837
+	}
838
+
839
+
840
+
841
+	/********************************** SESSION_EXPIRED_RESET  **********************************/
842
+
843
+
844
+
845
+	/**
846
+	 * @param    EE_Session $session
847
+	 * @return    void
848
+	 */
849
+	public static function session_expired_reset(EE_Session $session)
850
+	{
851
+	}
852
+
853
+
854
+
855
+	/********************************** PROCESS_ABANDONED_TRANSACTIONS  **********************************/
856
+
857
+
858
+
859
+	/**
860
+	 * releases reserved tickets for all registrations of an ABANDONED EE_Transaction
861
+	 * by default, will NOT release tickets for free transactions, or any that have received a payment
862
+	 *
863
+	 * @param EE_Transaction $transaction
864
+	 * @return void
865
+	 * @throws EE_Error
866
+	 * @throws InvalidSessionDataException
867
+	 */
868
+	public static function process_abandoned_transactions(EE_Transaction $transaction)
869
+	{
870
+		// is this TXN free or has any money been paid towards this TXN? If so, then leave it alone
871
+		if ($transaction->is_free() || $transaction->paid() > 0) {
872
+			if (self::debug) {
873
+				// DEBUG LOG
874
+				EEH_Debug_Tools::log(
875
+					__CLASS__,
876
+					__FUNCTION__,
877
+					__LINE__,
878
+					array($transaction),
879
+					false,
880
+					'EE_Transaction: ' . $transaction->ID()
881
+				);
882
+			}
883
+			return;
884
+		}
885
+		// have their been any successful payments made ?
886
+		$payments = $transaction->payments();
887
+		foreach ($payments as $payment) {
888
+			if ($payment instanceof EE_Payment && $payment->status() === EEM_Payment::status_id_approved) {
889
+				if (self::debug) {
890
+					// DEBUG LOG
891
+					EEH_Debug_Tools::log(
892
+						__CLASS__,
893
+						__FUNCTION__,
894
+						__LINE__,
895
+						array($payment),
896
+						false,
897
+						'EE_Transaction: ' . $transaction->ID()
898
+					);
899
+				}
900
+				return;
901
+			}
902
+		}
903
+		// since you haven't even attempted to pay for your ticket...
904
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
905
+	}
906
+
907
+
908
+
909
+	/********************************** PROCESS_FAILED_TRANSACTIONS  **********************************/
910
+
911
+
912
+
913
+	/**
914
+	 * releases reserved tickets for absolutely ALL registrations of a FAILED EE_Transaction
915
+	 *
916
+	 * @param EE_Transaction $transaction
917
+	 * @return void
918
+	 * @throws EE_Error
919
+	 * @throws InvalidSessionDataException
920
+	 */
921
+	public static function process_failed_transactions(EE_Transaction $transaction)
922
+	{
923
+		// since you haven't even attempted to pay for your ticket...
924
+		EED_Ticket_Sales_Monitor::instance()->_release_all_reserved_tickets_for_transaction($transaction);
925
+	}
926
+
927
+
928
+
929
+	/********************************** RESET RESERVATION COUNTS  *********************************/
930
+
931
+
932
+
933
+	/**
934
+	 * Resets all ticket and datetime reserved counts to zero
935
+	 * Tickets that are currently associated with a Transaction that is in progress
936
+	 *
937
+	 * @throws EE_Error
938
+	 * @throws DomainException
939
+	 * @throws InvalidDataTypeException
940
+	 * @throws InvalidInterfaceException
941
+	 * @throws InvalidArgumentException
942
+	 * @throws UnexpectedEntityException
943
+	 */
944
+	public static function reset_reservation_counts()
945
+	{
946
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
947
+		$valid_reserved_tickets = array();
948
+		/** @var EE_Transaction[] $transactions_not_in_progress */
949
+		$transactions_not_in_progress = EEM_Transaction::instance()->get_transactions_not_in_progress();
950
+		foreach ($transactions_not_in_progress as $transaction) {
951
+			// if this TXN has been fully completed, then skip it
952
+			if ($transaction->reg_step_completed('finalize_registration')) {
953
+				continue;
954
+			}
955
+			$total_line_item = $transaction->total_line_item();
956
+			// $transaction_in_progress->line
957
+			if (! $total_line_item instanceof EE_Line_Item) {
958
+				throw new DomainException(
959
+					esc_html__(
960
+						'Transaction does not have a valid Total Line Item associated with it.',
961
+						'event_espresso'
962
+					)
963
+				);
964
+			}
965
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
966
+				$total_line_item
967
+			);
968
+		}
969
+		$total_line_items = EEM_Line_Item::instance()->get_total_line_items_for_active_carts();
970
+		foreach ($total_line_items as $total_line_item) {
971
+			$valid_reserved_tickets += EED_Ticket_Sales_Monitor::get_ticket_line_items_for_grand_total(
972
+				$total_line_item
973
+			);
974
+		}
975
+		$tickets_with_reservations = EEM_Ticket::instance()->get_tickets_with_reservations();
976
+		return EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
977
+			$tickets_with_reservations,
978
+			$valid_reserved_tickets,
979
+			__FUNCTION__
980
+		);
981
+	}
982
+
983
+
984
+
985
+	/**
986
+	 * @param EE_Line_Item $total_line_item
987
+	 * @return EE_Line_Item[]
988
+	 */
989
+	private static function get_ticket_line_items_for_grand_total(EE_Line_Item $total_line_item)
990
+	{
991
+		/** @var EE_Line_Item[] $valid_reserved_tickets */
992
+		$valid_reserved_tickets = array();
993
+		$ticket_line_items      = EEH_Line_Item::get_ticket_line_items($total_line_item);
994
+		foreach ($ticket_line_items as $ticket_line_item) {
995
+			if ($ticket_line_item instanceof EE_Line_Item) {
996
+				$valid_reserved_tickets[] = $ticket_line_item;
997
+			}
998
+		}
999
+		return $valid_reserved_tickets;
1000
+	}
1001
+
1002
+
1003
+
1004
+	/**
1005
+	 * @param EE_Ticket[]    $tickets_with_reservations
1006
+	 * @param EE_Line_Item[] $valid_reserved_ticket_line_items
1007
+	 * @return int
1008
+	 * @throws UnexpectedEntityException
1009
+	 * @throws DomainException
1010
+	 * @throws EE_Error
1011
+	 */
1012
+	private static function release_reservations_for_tickets(
1013
+		array $tickets_with_reservations,
1014
+		array $valid_reserved_ticket_line_items = array(),
1015
+		$source
1016
+	) {
1017
+		if (self::debug) {
1018
+			echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
1019
+		}
1020
+		$total_tickets_released = 0;
1021
+		$sold_out_events = array();
1022
+		foreach ($tickets_with_reservations as $ticket_with_reservations) {
1023
+			if (! $ticket_with_reservations instanceof EE_Ticket) {
1024
+				continue;
1025
+			}
1026
+			$reserved_qty = $ticket_with_reservations->reserved();
1027
+			if (self::debug) {
1028
+				echo self::$nl . ' . $ticket_with_reservations->ID(): ' . $ticket_with_reservations->ID();
1029
+				echo self::$nl . ' . $reserved_qty: ' . $reserved_qty;
1030
+			}
1031
+			foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1032
+				if (
1033
+					$valid_reserved_ticket_line_item instanceof EE_Line_Item
1034
+					&& $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1035
+				) {
1036
+					if (self::debug) {
1037
+						echo self::$nl . ' . $valid_reserved_ticket_line_item->quantity(): ' . $valid_reserved_ticket_line_item->quantity();
1038
+					}
1039
+					$reserved_qty -= $valid_reserved_ticket_line_item->quantity();
1040
+				}
1041
+			}
1042
+			if ($reserved_qty > 0) {
1043
+				$ticket_with_reservations->add_extra_meta(
1044
+					EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1045
+					__LINE__ . ') ' . $source . '()'
1046
+				);
1047
+				$ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:'. __LINE__);
1048
+				$ticket_with_reservations->save();
1049
+				$total_tickets_released += $reserved_qty;
1050
+				$event = $ticket_with_reservations->get_related_event();
1051
+				// track sold out events
1052
+				if ($event instanceof EE_Event && $event->is_sold_out()) {
1053
+					$sold_out_events[] = $event;
1054
+				}
1055
+			}
1056
+		}
1057
+		if (self::debug) {
1058
+			echo self::$nl . ' . $total_tickets_released: ' . $total_tickets_released;
1059
+		}
1060
+		// double check whether sold out events should remain sold out after releasing tickets
1061
+		if($sold_out_events !== array()){
1062
+			foreach ($sold_out_events as $sold_out_event) {
1063
+				/** @var EE_Event $sold_out_event */
1064
+				$sold_out_event->perform_sold_out_status_check();
1065
+			}
1066
+		}
1067
+		return $total_tickets_released;
1068
+	}
1069
+
1070
+
1071
+
1072
+	/********************************** SHUTDOWN  **********************************/
1073
+
1074
+
1075
+
1076
+	/**
1077
+	 * @param int $timestamp
1078
+	 * @return false|int
1079
+	 * @throws EE_Error
1080
+	 * @throws InvalidArgumentException
1081
+	 * @throws InvalidDataTypeException
1082
+	 * @throws InvalidInterfaceException
1083
+	 */
1084
+	public static function clear_expired_line_items_with_no_transaction($timestamp = 0)
1085
+	{
1086
+	   /** @type WPDB $wpdb */
1087
+		global $wpdb;
1088
+		if (! absint($timestamp)) {
1089
+			/** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1090
+			$session_lifespan = LoaderFactory::getLoader()->getShared(
1091
+				'EventEspresso\core\domain\values\session\SessionLifespan'
1092
+			);
1093
+			$timestamp = $session_lifespan->expiration();
1094
+		}
1095
+		 return $wpdb->query(
1096
+			$wpdb->prepare(
1097
+				'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1098 1098
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1099
-                // use GMT time because that's what LIN_timestamps are in
1100
-                date('Y-m-d H:i:s', $timestamp)
1101
-            )
1102
-        );
1103
-    }
1099
+				// use GMT time because that's what LIN_timestamps are in
1100
+				date('Y-m-d H:i:s', $timestamp)
1101
+			)
1102
+		);
1103
+	}
1104 1104
 
1105 1105
 }
1106 1106
 // End of file EED_Ticket_Sales_Monitor.module.php
Please login to merge, or discard this patch.
Spacing   +88 added lines, -88 removed lines patch added patch discarded remove patch
@@ -24,7 +24,7 @@  discard block
 block discarded – undo
24 24
 class EED_Ticket_Sales_Monitor extends EED_Module
25 25
 {
26 26
 
27
-    const debug = false;    //	true false
27
+    const debug = false; //	true false
28 28
 
29 29
     private static $nl = '';
30 30
 
@@ -67,7 +67,7 @@  discard block
 block discarded – undo
67 67
      */
68 68
     public static function set_hooks()
69 69
     {
70
-        self::$nl = defined('EE_TESTS_DIR')? "\n" : '<br />';
70
+        self::$nl = defined('EE_TESTS_DIR') ? "\n" : '<br />';
71 71
         // release tickets for expired carts
72 72
         add_action(
73 73
             'EED_Ticket_Selector__process_ticket_selections__before',
@@ -196,7 +196,7 @@  discard block
 block discarded – undo
196 196
     public static function release_tickets_for_expired_carts()
197 197
     {
198 198
         if (self::debug) {
199
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
199
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
200 200
         }
201 201
         do_action('AHEE__EED_Ticket_Sales_Monitor__release_tickets_for_expired_carts__begin');
202 202
         $expired_ticket_IDs = array();
@@ -207,26 +207,26 @@  discard block
 block discarded – undo
207 207
         $timestamp = $session_lifespan->expiration();
208 208
         $expired_ticket_line_items = EEM_Line_Item::instance()->getTicketLineItemsForExpiredCarts($timestamp);
209 209
         if (self::debug) {
210
-            echo self::$nl . ' . time(): ' . time();
211
-            echo self::$nl . ' . time() as date: ' . date('Y-m-d H:i a');
212
-            echo self::$nl . ' . session expiration: ' . $session_lifespan->expiration();
213
-            echo self::$nl . ' . session expiration as date: ' . date('Y-m-d H:i a', $session_lifespan->expiration());
214
-            echo self::$nl . ' . timestamp: ' . $timestamp;
215
-            echo self::$nl . ' . $expired_ticket_line_items: ' . count($expired_ticket_line_items);
210
+            echo self::$nl.' . time(): '.time();
211
+            echo self::$nl.' . time() as date: '.date('Y-m-d H:i a');
212
+            echo self::$nl.' . session expiration: '.$session_lifespan->expiration();
213
+            echo self::$nl.' . session expiration as date: '.date('Y-m-d H:i a', $session_lifespan->expiration());
214
+            echo self::$nl.' . timestamp: '.$timestamp;
215
+            echo self::$nl.' . $expired_ticket_line_items: '.count($expired_ticket_line_items);
216 216
         }
217
-        if (! empty($expired_ticket_line_items)) {
217
+        if ( ! empty($expired_ticket_line_items)) {
218 218
             foreach ($expired_ticket_line_items as $expired_ticket_line_item) {
219
-                if (! $expired_ticket_line_item instanceof EE_Line_Item) {
219
+                if ( ! $expired_ticket_line_item instanceof EE_Line_Item) {
220 220
                     continue;
221 221
                 }
222
-                $expired_ticket_IDs[ $expired_ticket_line_item->OBJ_ID() ] = $expired_ticket_line_item->OBJ_ID();
222
+                $expired_ticket_IDs[$expired_ticket_line_item->OBJ_ID()] = $expired_ticket_line_item->OBJ_ID();
223 223
                 if (self::debug) {
224
-                    echo self::$nl . ' . $expired_ticket_line_item->OBJ_ID(): ' . $expired_ticket_line_item->OBJ_ID();
225
-                    echo self::$nl . ' . $expired_ticket_line_item->timestamp(): ' . date('Y-m-d h:i a',
224
+                    echo self::$nl.' . $expired_ticket_line_item->OBJ_ID(): '.$expired_ticket_line_item->OBJ_ID();
225
+                    echo self::$nl.' . $expired_ticket_line_item->timestamp(): '.date('Y-m-d h:i a',
226 226
                             $expired_ticket_line_item->timestamp(true));
227 227
                 }
228 228
             }
229
-            if (! empty($expired_ticket_IDs)) {
229
+            if ( ! empty($expired_ticket_IDs)) {
230 230
                 EED_Ticket_Sales_Monitor::release_reservations_for_tickets(
231 231
                     \EEM_Ticket::instance()->get_tickets_with_IDs($expired_ticket_IDs),
232 232
                     array(),
@@ -265,8 +265,8 @@  discard block
 block discarded – undo
265 265
             $qty = EED_Ticket_Sales_Monitor::instance()->_validate_ticket_sale($ticket, $qty);
266 266
         }
267 267
         if (self::debug) {
268
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
269
-            echo self::$nl . self::$nl . '<b> RETURNED QTY: ' . $qty . '</b>';
268
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
269
+            echo self::$nl.self::$nl.'<b> RETURNED QTY: '.$qty.'</b>';
270 270
         }
271 271
         return $qty;
272 272
     }
@@ -285,36 +285,36 @@  discard block
 block discarded – undo
285 285
     protected function _validate_ticket_sale(EE_Ticket $ticket, $qty = 1)
286 286
     {
287 287
         if (self::debug) {
288
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
288
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
289 289
         }
290
-        if (! $ticket instanceof EE_Ticket) {
290
+        if ( ! $ticket instanceof EE_Ticket) {
291 291
             return 0;
292 292
         }
293 293
         if (self::debug) {
294
-            echo self::$nl . '<b> . ticket->ID: ' . $ticket->ID() . '</b>';
295
-            echo self::$nl . ' . original ticket->reserved: ' . $ticket->reserved();
294
+            echo self::$nl.'<b> . ticket->ID: '.$ticket->ID().'</b>';
295
+            echo self::$nl.' . original ticket->reserved: '.$ticket->reserved();
296 296
         }
297 297
         $ticket->refresh_from_db();
298 298
         // first let's determine the ticket availability based on sales
299 299
         $available = $ticket->qty('saleable');
300 300
         if (self::debug) {
301
-            echo self::$nl . ' . . . ticket->qty: ' . $ticket->qty();
302
-            echo self::$nl . ' . . . ticket->sold: ' . $ticket->sold();
303
-            echo self::$nl . ' . . . ticket->reserved: ' . $ticket->reserved();
304
-            echo self::$nl . ' . . . ticket->qty(saleable): ' . $ticket->qty('saleable');
305
-            echo self::$nl . ' . . . available: ' . $available;
301
+            echo self::$nl.' . . . ticket->qty: '.$ticket->qty();
302
+            echo self::$nl.' . . . ticket->sold: '.$ticket->sold();
303
+            echo self::$nl.' . . . ticket->reserved: '.$ticket->reserved();
304
+            echo self::$nl.' . . . ticket->qty(saleable): '.$ticket->qty('saleable');
305
+            echo self::$nl.' . . . available: '.$available;
306 306
         }
307 307
         if ($available < 1) {
308 308
             $this->_ticket_sold_out($ticket);
309 309
             return 0;
310 310
         }
311 311
         if (self::debug) {
312
-            echo self::$nl . ' . . . qty: ' . $qty;
312
+            echo self::$nl.' . . . qty: '.$qty;
313 313
         }
314 314
         if ($available < $qty) {
315 315
             $qty = $available;
316 316
             if (self::debug) {
317
-                echo self::$nl . ' . . . QTY ADJUSTED: ' . $qty;
317
+                echo self::$nl.' . . . QTY ADJUSTED: '.$qty;
318 318
             }
319 319
             $this->_ticket_quantity_decremented($ticket);
320 320
         }
@@ -335,9 +335,9 @@  discard block
 block discarded – undo
335 335
     protected function _reserve_ticket(EE_Ticket $ticket, $quantity = 1)
336 336
     {
337 337
         if (self::debug) {
338
-            echo self::$nl . self::$nl . ' . . . INCREASE RESERVED: ' . $quantity;
338
+            echo self::$nl.self::$nl.' . . . INCREASE RESERVED: '.$quantity;
339 339
         }
340
-        $ticket->increase_reserved($quantity, 'TicketSalesMonitor:'. __LINE__);
340
+        $ticket->increase_reserved($quantity, 'TicketSalesMonitor:'.__LINE__);
341 341
         return $ticket->save();
342 342
     }
343 343
 
@@ -352,12 +352,12 @@  discard block
 block discarded – undo
352 352
     protected function _release_reserved_ticket(EE_Ticket $ticket, $quantity = 1)
353 353
     {
354 354
         if (self::debug) {
355
-            echo self::$nl . ' . . . ticket->ID: ' . $ticket->ID();
356
-            echo self::$nl . ' . . . ticket->reserved before: ' . $ticket->reserved();
355
+            echo self::$nl.' . . . ticket->ID: '.$ticket->ID();
356
+            echo self::$nl.' . . . ticket->reserved before: '.$ticket->reserved();
357 357
         }
358
-        $ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:'. __LINE__);
358
+        $ticket->decrease_reserved($quantity, true, 'TicketSalesMonitor:'.__LINE__);
359 359
         if (self::debug) {
360
-            echo self::$nl . ' . . . ticket->reserved after: ' . $ticket->reserved();
360
+            echo self::$nl.' . . . ticket->reserved after: '.$ticket->reserved();
361 361
         }
362 362
         return $ticket->save() ? 1 : 0;
363 363
     }
@@ -375,8 +375,8 @@  discard block
 block discarded – undo
375 375
     protected function _ticket_sold_out(EE_Ticket $ticket)
376 376
     {
377 377
         if (self::debug) {
378
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
379
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
378
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
379
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
380 380
         }
381 381
         $this->sold_out_tickets[] = $this->_get_ticket_and_event_name($ticket);
382 382
     }
@@ -394,8 +394,8 @@  discard block
 block discarded – undo
394 394
     protected function _ticket_quantity_decremented(EE_Ticket $ticket)
395 395
     {
396 396
         if (self::debug) {
397
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
398
-            echo self::$nl . ' . . ticket->name: ' . $this->_get_ticket_and_event_name($ticket);
397
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
398
+            echo self::$nl.' . . ticket->name: '.$this->_get_ticket_and_event_name($ticket);
399 399
         }
400 400
         $this->decremented_tickets[] = $this->_get_ticket_and_event_name($ticket);
401 401
     }
@@ -448,7 +448,7 @@  discard block
 block discarded – undo
448 448
         if ($ticket instanceof EE_Ticket) {
449 449
             $ticket->add_extra_meta(
450 450
                 EE_Ticket::META_KEY_TICKET_RESERVATIONS,
451
-                __LINE__ . ') ' . __METHOD__ . '()'
451
+                __LINE__.') '.__METHOD__.'()'
452 452
             );
453 453
             if ($quantity > 0) {
454 454
                 EED_Ticket_Sales_Monitor::instance()->_reserve_ticket($ticket, $quantity);
@@ -472,7 +472,7 @@  discard block
 block discarded – undo
472 472
     {
473 473
         $ticket->add_extra_meta(
474 474
             EE_Ticket::META_KEY_TICKET_RESERVATIONS,
475
-            __LINE__ . ') ' . __METHOD__ . '()'
475
+            __LINE__.') '.__METHOD__.'()'
476 476
         );
477 477
         EED_Ticket_Sales_Monitor::instance()->_release_reserved_ticket($ticket, $quantity);
478 478
     }
@@ -509,18 +509,18 @@  discard block
 block discarded – undo
509 509
     protected function _post_notices()
510 510
     {
511 511
         if (self::debug) {
512
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
512
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
513 513
         }
514 514
         $refresh_msg    = '';
515 515
         $none_added_msg = '';
516 516
         if (defined('DOING_AJAX') && DOING_AJAX) {
517
-            $refresh_msg    = __(
517
+            $refresh_msg = __(
518 518
                 'Please refresh the page to view updated ticket quantities.',
519 519
                 'event_espresso'
520 520
             );
521 521
             $none_added_msg = __('No tickets were added for the event.', 'event_espresso');
522 522
         }
523
-        if (! empty($this->sold_out_tickets)) {
523
+        if ( ! empty($this->sold_out_tickets)) {
524 524
             EE_Error::add_attention(
525 525
                 sprintf(
526 526
                     apply_filters(
@@ -543,7 +543,7 @@  discard block
 block discarded – undo
543 543
             // and reset the cart
544 544
             EED_Ticket_Sales_Monitor::session_cart_reset(EE_Registry::instance()->SSN);
545 545
         }
546
-        if (! empty($this->decremented_tickets)) {
546
+        if ( ! empty($this->decremented_tickets)) {
547 547
             EE_Error::add_attention(
548 548
                 sprintf(
549 549
                     apply_filters(
@@ -581,9 +581,9 @@  discard block
 block discarded – undo
581 581
     protected function _release_all_reserved_tickets_for_transaction(EE_Transaction $transaction)
582 582
     {
583 583
         if (self::debug) {
584
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
585
-            echo self::$nl . ' . transaction->ID: ' . $transaction->ID();
586
-            echo self::$nl . ' . TXN status_ID: ' . $transaction->status_ID();
584
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
585
+            echo self::$nl.' . transaction->ID: '.$transaction->ID();
586
+            echo self::$nl.' . TXN status_ID: '.$transaction->status_ID();
587 587
         }
588 588
         // check if 'finalize_registration' step has been completed...
589 589
         $finalized = $transaction->reg_step_completed('finalize_registration');
@@ -595,13 +595,13 @@  discard block
 block discarded – undo
595 595
                 __LINE__,
596 596
                 array('finalized' => $finalized),
597 597
                 false,
598
-                'EE_Transaction: ' . $transaction->ID()
598
+                'EE_Transaction: '.$transaction->ID()
599 599
             );
600 600
         }
601 601
         // how many tickets were released
602 602
         $count = 0;
603 603
         if (self::debug) {
604
-            echo self::$nl . ' . . . TXN finalized: ' . $finalized;
604
+            echo self::$nl.' . . . TXN finalized: '.$finalized;
605 605
         }
606 606
         $release_tickets_with_TXN_status = array(
607 607
             EEM_Transaction::failed_status_code,
@@ -610,28 +610,28 @@  discard block
 block discarded – undo
610 610
         );
611 611
         $events = array();
612 612
         // if the session is getting cleared BEFORE the TXN has been finalized or the transaction is not completed
613
-        if (! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
613
+        if ( ! $finalized || in_array($transaction->status_ID(), $release_tickets_with_TXN_status, true)) {
614 614
             // cancel any reserved tickets for registrations that were not approved
615 615
             $registrations = $transaction->registrations();
616 616
             if (self::debug) {
617
-                echo self::$nl . ' . . . # registrations: ' . count($registrations);
617
+                echo self::$nl.' . . . # registrations: '.count($registrations);
618 618
                 $reg    = reset($registrations);
619 619
                 $ticket = $reg->ticket();
620 620
                 if ($ticket instanceof EE_Ticket) {
621 621
                     $ticket->add_extra_meta(
622 622
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
623
-                        __LINE__ . ') Release All Tickets TXN:' . $transaction->ID()
623
+                        __LINE__.') Release All Tickets TXN:'.$transaction->ID()
624 624
                     );
625 625
                 }
626 626
             }
627
-            if (! empty($registrations)) {
627
+            if ( ! empty($registrations)) {
628 628
                 foreach ($registrations as $registration) {
629 629
                     if (
630 630
                         $registration instanceof EE_Registration
631 631
                         && $this->_release_reserved_ticket_for_registration($registration, $transaction)
632 632
                     ) {
633 633
                         $count++;
634
-                        $events[ $registration->event_ID() ] = $registration->event();
634
+                        $events[$registration->event_ID()] = $registration->event();
635 635
                     }
636 636
                 }
637 637
             }
@@ -662,10 +662,10 @@  discard block
 block discarded – undo
662 662
     ) {
663 663
         $STS_ID = $transaction->status_ID();
664 664
         if (self::debug) {
665
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
666
-            echo self::$nl . ' . . registration->ID: ' . $registration->ID();
667
-            echo self::$nl . ' . . registration->status_ID: ' . $registration->status_ID();
668
-            echo self::$nl . ' . . transaction->status_ID(): ' . $STS_ID;
665
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
666
+            echo self::$nl.' . . registration->ID: '.$registration->ID();
667
+            echo self::$nl.' . . registration->status_ID: '.$registration->status_ID();
668
+            echo self::$nl.' . . transaction->status_ID(): '.$STS_ID;
669 669
         }
670 670
         if (
671 671
             // release Tickets for Failed Transactions and Abandoned Transactions
@@ -678,12 +678,12 @@  discard block
 block discarded – undo
678 678
             )
679 679
         ) {
680 680
             if (self::debug) {
681
-                echo self::$nl . self::$nl . ' . . RELEASE RESERVED TICKET';
681
+                echo self::$nl.self::$nl.' . . RELEASE RESERVED TICKET';
682 682
                 $rsrvd = $registration->get_extra_meta(EE_Registration::HAS_RESERVED_TICKET_KEY, true);
683
-                echo self::$nl . ' . . . registration HAS_RESERVED_TICKET_KEY: ';
683
+                echo self::$nl.' . . . registration HAS_RESERVED_TICKET_KEY: ';
684 684
                 var_dump($rsrvd);
685 685
             }
686
-            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:'. __LINE__);
686
+            $registration->release_reserved_ticket(true, 'TicketSalesMonitor:'.__LINE__);
687 687
             return 1;
688 688
         }
689 689
         return 0;
@@ -713,7 +713,7 @@  discard block
 block discarded – undo
713 713
             return;
714 714
         }
715 715
         if (self::debug) {
716
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
716
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
717 717
         }
718 718
         // first check of the session has a valid Checkout object
719 719
         $checkout = $session->checkout();
@@ -725,12 +725,12 @@  discard block
 block discarded – undo
725 725
         $cart = $session->cart();
726 726
         if ($cart instanceof EE_Cart) {
727 727
             if (self::debug) {
728
-                echo self::$nl . self::$nl . ' cart instance of EE_Cart: ';
728
+                echo self::$nl.self::$nl.' cart instance of EE_Cart: ';
729 729
             }
730 730
             EED_Ticket_Sales_Monitor::instance()->_session_cart_reset($cart, $session);
731 731
         } else {
732 732
             if (self::debug) {
733
-                echo self::$nl . self::$nl . ' invalid EE_Cart: ';
733
+                echo self::$nl.self::$nl.' invalid EE_Cart: ';
734 734
                 var_export($cart, true);
735 735
             }
736 736
         }
@@ -752,39 +752,39 @@  discard block
 block discarded – undo
752 752
     protected function _session_cart_reset(EE_Cart $cart, EE_Session $session)
753 753
     {
754 754
         if (self::debug) {
755
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
755
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
756 756
         }
757 757
         $ticket_line_items = $cart->get_tickets();
758 758
         if (empty($ticket_line_items)) {
759 759
             return;
760 760
         }
761 761
         if (self::debug) {
762
-            echo '<br /> . ticket_line_item count: ' . count($ticket_line_items);
762
+            echo '<br /> . ticket_line_item count: '.count($ticket_line_items);
763 763
         }
764 764
         foreach ($ticket_line_items as $ticket_line_item) {
765 765
             if (self::debug) {
766
-                echo self::$nl . ' . ticket_line_item->ID(): ' . $ticket_line_item->ID();
766
+                echo self::$nl.' . ticket_line_item->ID(): '.$ticket_line_item->ID();
767 767
             }
768 768
             if ($ticket_line_item instanceof EE_Line_Item && $ticket_line_item->OBJ_type() === 'Ticket') {
769 769
                 if (self::debug) {
770
-                    echo self::$nl . ' . . ticket_line_item->OBJ_ID(): ' . $ticket_line_item->OBJ_ID();
770
+                    echo self::$nl.' . . ticket_line_item->OBJ_ID(): '.$ticket_line_item->OBJ_ID();
771 771
                 }
772 772
                 $ticket = EEM_Ticket::instance()->get_one_by_ID($ticket_line_item->OBJ_ID());
773 773
                 if ($ticket instanceof EE_Ticket) {
774 774
                     if (self::debug) {
775
-                        echo self::$nl . ' . . ticket->ID(): ' . $ticket->ID();
776
-                        echo self::$nl . ' . . ticket_line_item->quantity(): ' . $ticket_line_item->quantity();
775
+                        echo self::$nl.' . . ticket->ID(): '.$ticket->ID();
776
+                        echo self::$nl.' . . ticket_line_item->quantity(): '.$ticket_line_item->quantity();
777 777
                     }
778 778
                     $ticket->add_extra_meta(
779 779
                         EE_Ticket::META_KEY_TICKET_RESERVATIONS,
780
-                        __LINE__ . ') ' . __METHOD__ . '() SID = ' . $session->id()
780
+                        __LINE__.') '.__METHOD__.'() SID = '.$session->id()
781 781
                     );
782 782
                     $this->_release_reserved_ticket($ticket, $ticket_line_item->quantity());
783 783
                 }
784 784
             }
785 785
         }
786 786
         if (self::debug) {
787
-            echo self::$nl . self::$nl . ' RESET COMPLETED ';
787
+            echo self::$nl.self::$nl.' RESET COMPLETED ';
788 788
         }
789 789
     }
790 790
 
@@ -805,7 +805,7 @@  discard block
 block discarded – undo
805 805
     public static function session_checkout_reset(EE_Session $session)
806 806
     {
807 807
         // don't release tickets if cart was already reset
808
-        if(did_action('AHEE__EE_Session__reset_cart__before_reset')) {
808
+        if (did_action('AHEE__EE_Session__reset_cart__before_reset')) {
809 809
             return;
810 810
         }
811 811
         $checkout = $session->checkout();
@@ -827,7 +827,7 @@  discard block
 block discarded – undo
827 827
     protected function _session_checkout_reset(EE_Checkout $checkout)
828 828
     {
829 829
         if (self::debug) {
830
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '() ';
830
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'() ';
831 831
         }
832 832
         // we want to release the each registration's reserved tickets if the session was cleared, but not if this is a revisit
833 833
         if ($checkout->revisit || ! $checkout->transaction instanceof EE_Transaction) {
@@ -877,7 +877,7 @@  discard block
 block discarded – undo
877 877
                     __LINE__,
878 878
                     array($transaction),
879 879
                     false,
880
-                    'EE_Transaction: ' . $transaction->ID()
880
+                    'EE_Transaction: '.$transaction->ID()
881 881
                 );
882 882
             }
883 883
             return;
@@ -894,7 +894,7 @@  discard block
 block discarded – undo
894 894
                         __LINE__,
895 895
                         array($payment),
896 896
                         false,
897
-                        'EE_Transaction: ' . $transaction->ID()
897
+                        'EE_Transaction: '.$transaction->ID()
898 898
                     );
899 899
                 }
900 900
                 return;
@@ -954,7 +954,7 @@  discard block
 block discarded – undo
954 954
             }
955 955
             $total_line_item = $transaction->total_line_item();
956 956
             // $transaction_in_progress->line
957
-            if (! $total_line_item instanceof EE_Line_Item) {
957
+            if ( ! $total_line_item instanceof EE_Line_Item) {
958 958
                 throw new DomainException(
959 959
                     esc_html__(
960 960
                         'Transaction does not have a valid Total Line Item associated with it.',
@@ -1015,18 +1015,18 @@  discard block
 block discarded – undo
1015 1015
         $source
1016 1016
     ) {
1017 1017
         if (self::debug) {
1018
-            echo self::$nl . self::$nl . __LINE__ . ') ' . __METHOD__ . '()';
1018
+            echo self::$nl.self::$nl.__LINE__.') '.__METHOD__.'()';
1019 1019
         }
1020 1020
         $total_tickets_released = 0;
1021 1021
         $sold_out_events = array();
1022 1022
         foreach ($tickets_with_reservations as $ticket_with_reservations) {
1023
-            if (! $ticket_with_reservations instanceof EE_Ticket) {
1023
+            if ( ! $ticket_with_reservations instanceof EE_Ticket) {
1024 1024
                 continue;
1025 1025
             }
1026 1026
             $reserved_qty = $ticket_with_reservations->reserved();
1027 1027
             if (self::debug) {
1028
-                echo self::$nl . ' . $ticket_with_reservations->ID(): ' . $ticket_with_reservations->ID();
1029
-                echo self::$nl . ' . $reserved_qty: ' . $reserved_qty;
1028
+                echo self::$nl.' . $ticket_with_reservations->ID(): '.$ticket_with_reservations->ID();
1029
+                echo self::$nl.' . $reserved_qty: '.$reserved_qty;
1030 1030
             }
1031 1031
             foreach ($valid_reserved_ticket_line_items as $valid_reserved_ticket_line_item) {
1032 1032
                 if (
@@ -1034,7 +1034,7 @@  discard block
 block discarded – undo
1034 1034
                     && $valid_reserved_ticket_line_item->OBJ_ID() === $ticket_with_reservations->ID()
1035 1035
                 ) {
1036 1036
                     if (self::debug) {
1037
-                        echo self::$nl . ' . $valid_reserved_ticket_line_item->quantity(): ' . $valid_reserved_ticket_line_item->quantity();
1037
+                        echo self::$nl.' . $valid_reserved_ticket_line_item->quantity(): '.$valid_reserved_ticket_line_item->quantity();
1038 1038
                     }
1039 1039
                     $reserved_qty -= $valid_reserved_ticket_line_item->quantity();
1040 1040
                 }
@@ -1042,9 +1042,9 @@  discard block
 block discarded – undo
1042 1042
             if ($reserved_qty > 0) {
1043 1043
                 $ticket_with_reservations->add_extra_meta(
1044 1044
                     EE_Ticket::META_KEY_TICKET_RESERVATIONS,
1045
-                    __LINE__ . ') ' . $source . '()'
1045
+                    __LINE__.') '.$source.'()'
1046 1046
                 );
1047
-                $ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:'. __LINE__);
1047
+                $ticket_with_reservations->decrease_reserved($reserved_qty, true, 'TicketSalesMonitor:'.__LINE__);
1048 1048
                 $ticket_with_reservations->save();
1049 1049
                 $total_tickets_released += $reserved_qty;
1050 1050
                 $event = $ticket_with_reservations->get_related_event();
@@ -1055,10 +1055,10 @@  discard block
 block discarded – undo
1055 1055
             }
1056 1056
         }
1057 1057
         if (self::debug) {
1058
-            echo self::$nl . ' . $total_tickets_released: ' . $total_tickets_released;
1058
+            echo self::$nl.' . $total_tickets_released: '.$total_tickets_released;
1059 1059
         }
1060 1060
         // double check whether sold out events should remain sold out after releasing tickets
1061
-        if($sold_out_events !== array()){
1061
+        if ($sold_out_events !== array()) {
1062 1062
             foreach ($sold_out_events as $sold_out_event) {
1063 1063
                 /** @var EE_Event $sold_out_event */
1064 1064
                 $sold_out_event->perform_sold_out_status_check();
@@ -1085,7 +1085,7 @@  discard block
 block discarded – undo
1085 1085
     {
1086 1086
        /** @type WPDB $wpdb */
1087 1087
         global $wpdb;
1088
-        if (! absint($timestamp)) {
1088
+        if ( ! absint($timestamp)) {
1089 1089
             /** @var EventEspresso\core\domain\values\session\SessionLifespan $session_lifespan */
1090 1090
             $session_lifespan = LoaderFactory::getLoader()->getShared(
1091 1091
                 'EventEspresso\core\domain\values\session\SessionLifespan'
@@ -1094,7 +1094,7 @@  discard block
 block discarded – undo
1094 1094
         }
1095 1095
          return $wpdb->query(
1096 1096
             $wpdb->prepare(
1097
-                'DELETE FROM ' . EEM_Line_Item::instance()->table() . '
1097
+                'DELETE FROM '.EEM_Line_Item::instance()->table().'
1098 1098
                 WHERE TXN_ID = 0 AND LIN_timestamp <= %s',
1099 1099
                 // use GMT time because that's what LIN_timestamps are in
1100 1100
                 date('Y-m-d H:i:s', $timestamp)
Please login to merge, or discard this patch.