Completed
Branch GDPR/consent (c6029e)
by
unknown
44:48 queued 29:41
created
libraries/form_sections/strategies/layout/EE_Template_Layout.strategy.php 1 patch
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -23,200 +23,200 @@
 block discarded – undo
23 23
 class EE_Template_Layout extends EE_Div_Per_Section_Layout
24 24
 {
25 25
 
26
-    protected $_layout_template_file       = null;
27
-
28
-    protected $_layout_begin_template_file = null;
29
-
30
-    protected $_input_template_file        = null;
31
-
32
-    protected $_subsection_template_file   = null;
33
-
34
-    protected $_layout_end_template_file   = null;
35
-
36
-    protected $_template_args              = array();
37
-
38
-
39
-
40
-    /**
41
-     * @param array $template_options {
42
-     * @type string $_layout_template_file
43
-     * @type string $_begin_template_file
44
-     * @type string $_input_template_file
45
-     * @type string $_subsection_template_file
46
-     * @type string $_end_template_file
47
-     * @type array  $_template_args
48
-     *                                }
49
-     */
50
-    public function __construct($template_options = array())
51
-    {
52
-        // loop through incoming options
53
-        foreach ($template_options as $key => $value) {
54
-            // add underscore to $key to match property names
55
-            $_key = '_' . $key;
56
-            if (property_exists($this, $_key)) {
57
-                $this->{$_key} = $value;
58
-            }
59
-        }
60
-        parent::__construct();
61
-    }
62
-
63
-
64
-
65
-    /**
66
-     * Also has the side effect of enqueuing any needed JS and CSS for
67
-     * this form.
68
-     * Creates all the HTML necessary for displaying this form, its inputs, and
69
-     * proper subsections.
70
-     * Returns the HTML
71
-     *
72
-     * @return string
73
-     */
74
-    public function layout_form()
75
-    {
76
-        if ($this->_layout_template_file) {
77
-            return EEH_Template::locate_template($this->_layout_template_file, $this->template_args(), true, true);
78
-        } else {
79
-            return parent::layout_form();
80
-        }
81
-    }
82
-
83
-
84
-
85
-    /**
86
-     * opening div tag for a form
87
-     *
88
-     * @return string
89
-     */
90
-    public function layout_form_begin()
91
-    {
92
-        if ($this->_layout_begin_template_file) {
93
-            return EEH_Template::locate_template(
94
-                $this->_layout_begin_template_file,
95
-                $this->template_args(),
96
-                true,
97
-                true
98
-            );
99
-        } else {
100
-            return parent::layout_form_begin();
101
-        }
102
-    }
103
-
104
-
105
-
106
-    /**
107
-     * If an input_template_file was provided upon construction, uses that to layout the input. Otherwise uses parent.
108
-     *
109
-     * @see EE_DIv_Per_Section_Layout::layout_input() for documentation
110
-     * @param EE_Form_Input_Base $input
111
-     * @return string
112
-     */
113
-    public function layout_input($input)
114
-    {
115
-        if ($this->_input_template_file) {
116
-            return EEH_Template::locate_template($this->_input_template_file, array('input' => $input), true, true);
117
-        }
118
-        return parent::layout_input($input);
119
-    }
120
-
121
-
122
-
123
-    /**
124
-     * If a subsection_template_file was provided upon construction, uses that to layout the subsection. Otherwise uses parent.
125
-     *
126
-     * @see EE_Div_Per_Section_Layout::layout_subsection() for documentation
127
-     * @param EE_Form_Section_Proper $form_section
128
-     * @return string
129
-     */
130
-    public function layout_subsection($form_section)
131
-    {
132
-        if ($this->_subsection_template_file) {
133
-            return EEH_Template::locate_template($this->_subsection_template_file, $this->template_args(), true, true);
134
-        }
135
-        return parent::layout_subsection($form_section);
136
-    }
137
-
138
-
139
-
140
-    /**
141
-     * closing div tag for a form
142
-     *
143
-     * @return string
144
-     */
145
-    public function layout_form_end()
146
-    {
147
-        if ($this->_layout_end_template_file) {
148
-            return EEH_Template::locate_template($this->_layout_end_template_file, $this->template_args(), true, true);
149
-        } else {
150
-            return parent::layout_form_end();
151
-        }
152
-    }
153
-
154
-
155
-
156
-    /**
157
-     * @param array $template_args
158
-     */
159
-    public function set_template_args($template_args = array())
160
-    {
161
-        $this->_template_args = $template_args;
162
-    }
163
-
164
-
165
-
166
-    /**
167
-     * @param array $template_args
168
-     */
169
-    public function add_template_args($template_args = array())
170
-    {
171
-        $this->_template_args = array_merge_recursive($this->_template_args, $template_args);
172
-    }
173
-
174
-
175
-
176
-    /**
177
-     * @return array
178
-     */
179
-    public function template_args()
180
-    {
181
-        foreach ($this->form_section()->subsections() as $subsection_name => $subsection) {
182
-            $subsection_name = self::prep_form_subsection_key_name($subsection_name);
183
-            if (strpos($subsection_name, '[') !== false) {
184
-                $sub_name = explode('[', $subsection_name);
185
-                $this->_template_args[ $sub_name[0] ][ rtrim($sub_name[1], ']') ] = $this->layout_subsection($subsection);
186
-            } else {
187
-                $this->_template_args[ $subsection_name ] = $this->layout_subsection($subsection);
188
-            }
189
-        }
190
-        //      d( $this->_template_args );
191
-        return $this->_template_args;
192
-    }
193
-
194
-
195
-
196
-    /**
197
-     * prep_form_section_key_name
198
-     *
199
-     * @access public
200
-     * @param string $subsection_name
201
-     * @return string
202
-     */
203
-    public static function prep_form_subsection_key_name($subsection_name = '')
204
-    {
205
-        $subsection_name = str_replace(array('-', ' '), array('', '_'), $subsection_name);
206
-        return is_numeric(substr($subsection_name, 0, 1)) ? 'form_' . $subsection_name : $subsection_name;
207
-    }
208
-
209
-
210
-
211
-    /**
212
-     * get_subform - just a wrapper for the above method
213
-     *
214
-     * @access public
215
-     * @param string $subsection_name
216
-     * @return string
217
-     */
218
-    public static function get_subform_name($subsection_name = '')
219
-    {
220
-        return EE_Template_Layout::prep_form_subsection_key_name($subsection_name);
221
-    }
26
+	protected $_layout_template_file       = null;
27
+
28
+	protected $_layout_begin_template_file = null;
29
+
30
+	protected $_input_template_file        = null;
31
+
32
+	protected $_subsection_template_file   = null;
33
+
34
+	protected $_layout_end_template_file   = null;
35
+
36
+	protected $_template_args              = array();
37
+
38
+
39
+
40
+	/**
41
+	 * @param array $template_options {
42
+	 * @type string $_layout_template_file
43
+	 * @type string $_begin_template_file
44
+	 * @type string $_input_template_file
45
+	 * @type string $_subsection_template_file
46
+	 * @type string $_end_template_file
47
+	 * @type array  $_template_args
48
+	 *                                }
49
+	 */
50
+	public function __construct($template_options = array())
51
+	{
52
+		// loop through incoming options
53
+		foreach ($template_options as $key => $value) {
54
+			// add underscore to $key to match property names
55
+			$_key = '_' . $key;
56
+			if (property_exists($this, $_key)) {
57
+				$this->{$_key} = $value;
58
+			}
59
+		}
60
+		parent::__construct();
61
+	}
62
+
63
+
64
+
65
+	/**
66
+	 * Also has the side effect of enqueuing any needed JS and CSS for
67
+	 * this form.
68
+	 * Creates all the HTML necessary for displaying this form, its inputs, and
69
+	 * proper subsections.
70
+	 * Returns the HTML
71
+	 *
72
+	 * @return string
73
+	 */
74
+	public function layout_form()
75
+	{
76
+		if ($this->_layout_template_file) {
77
+			return EEH_Template::locate_template($this->_layout_template_file, $this->template_args(), true, true);
78
+		} else {
79
+			return parent::layout_form();
80
+		}
81
+	}
82
+
83
+
84
+
85
+	/**
86
+	 * opening div tag for a form
87
+	 *
88
+	 * @return string
89
+	 */
90
+	public function layout_form_begin()
91
+	{
92
+		if ($this->_layout_begin_template_file) {
93
+			return EEH_Template::locate_template(
94
+				$this->_layout_begin_template_file,
95
+				$this->template_args(),
96
+				true,
97
+				true
98
+			);
99
+		} else {
100
+			return parent::layout_form_begin();
101
+		}
102
+	}
103
+
104
+
105
+
106
+	/**
107
+	 * If an input_template_file was provided upon construction, uses that to layout the input. Otherwise uses parent.
108
+	 *
109
+	 * @see EE_DIv_Per_Section_Layout::layout_input() for documentation
110
+	 * @param EE_Form_Input_Base $input
111
+	 * @return string
112
+	 */
113
+	public function layout_input($input)
114
+	{
115
+		if ($this->_input_template_file) {
116
+			return EEH_Template::locate_template($this->_input_template_file, array('input' => $input), true, true);
117
+		}
118
+		return parent::layout_input($input);
119
+	}
120
+
121
+
122
+
123
+	/**
124
+	 * If a subsection_template_file was provided upon construction, uses that to layout the subsection. Otherwise uses parent.
125
+	 *
126
+	 * @see EE_Div_Per_Section_Layout::layout_subsection() for documentation
127
+	 * @param EE_Form_Section_Proper $form_section
128
+	 * @return string
129
+	 */
130
+	public function layout_subsection($form_section)
131
+	{
132
+		if ($this->_subsection_template_file) {
133
+			return EEH_Template::locate_template($this->_subsection_template_file, $this->template_args(), true, true);
134
+		}
135
+		return parent::layout_subsection($form_section);
136
+	}
137
+
138
+
139
+
140
+	/**
141
+	 * closing div tag for a form
142
+	 *
143
+	 * @return string
144
+	 */
145
+	public function layout_form_end()
146
+	{
147
+		if ($this->_layout_end_template_file) {
148
+			return EEH_Template::locate_template($this->_layout_end_template_file, $this->template_args(), true, true);
149
+		} else {
150
+			return parent::layout_form_end();
151
+		}
152
+	}
153
+
154
+
155
+
156
+	/**
157
+	 * @param array $template_args
158
+	 */
159
+	public function set_template_args($template_args = array())
160
+	{
161
+		$this->_template_args = $template_args;
162
+	}
163
+
164
+
165
+
166
+	/**
167
+	 * @param array $template_args
168
+	 */
169
+	public function add_template_args($template_args = array())
170
+	{
171
+		$this->_template_args = array_merge_recursive($this->_template_args, $template_args);
172
+	}
173
+
174
+
175
+
176
+	/**
177
+	 * @return array
178
+	 */
179
+	public function template_args()
180
+	{
181
+		foreach ($this->form_section()->subsections() as $subsection_name => $subsection) {
182
+			$subsection_name = self::prep_form_subsection_key_name($subsection_name);
183
+			if (strpos($subsection_name, '[') !== false) {
184
+				$sub_name = explode('[', $subsection_name);
185
+				$this->_template_args[ $sub_name[0] ][ rtrim($sub_name[1], ']') ] = $this->layout_subsection($subsection);
186
+			} else {
187
+				$this->_template_args[ $subsection_name ] = $this->layout_subsection($subsection);
188
+			}
189
+		}
190
+		//      d( $this->_template_args );
191
+		return $this->_template_args;
192
+	}
193
+
194
+
195
+
196
+	/**
197
+	 * prep_form_section_key_name
198
+	 *
199
+	 * @access public
200
+	 * @param string $subsection_name
201
+	 * @return string
202
+	 */
203
+	public static function prep_form_subsection_key_name($subsection_name = '')
204
+	{
205
+		$subsection_name = str_replace(array('-', ' '), array('', '_'), $subsection_name);
206
+		return is_numeric(substr($subsection_name, 0, 1)) ? 'form_' . $subsection_name : $subsection_name;
207
+	}
208
+
209
+
210
+
211
+	/**
212
+	 * get_subform - just a wrapper for the above method
213
+	 *
214
+	 * @access public
215
+	 * @param string $subsection_name
216
+	 * @return string
217
+	 */
218
+	public static function get_subform_name($subsection_name = '')
219
+	{
220
+		return EE_Template_Layout::prep_form_subsection_key_name($subsection_name);
221
+	}
222 222
 }
Please login to merge, or discard this patch.
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 1 patch
Indentation   +1295 added lines, -1295 removed lines patch added patch discarded remove patch
@@ -14,1299 +14,1299 @@
 block discarded – undo
14 14
 class Extend_Registration_Form_Admin_Page extends Registration_Form_Admin_Page
15 15
 {
16 16
 
17
-    /**
18
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
19
-     */
20
-    public function __construct($routing = true)
21
-    {
22
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form' . DS);
23
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets' . DS);
24
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
25
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates' . DS);
26
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
27
-        parent::__construct($routing);
28
-    }
29
-
30
-
31
-    /**
32
-     * @return void
33
-     */
34
-    protected function _extend_page_config()
35
-    {
36
-        $this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
37
-        $qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
38
-            ? $this->_req_data['QST_ID'] : 0;
39
-        $qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
40
-            ? $this->_req_data['QSG_ID'] : 0;
41
-
42
-        $new_page_routes = array(
43
-            'question_groups'    => array(
44
-                'func'       => '_question_groups_overview_list_table',
45
-                'capability' => 'ee_read_question_groups',
46
-            ),
47
-            'add_question'       => array(
48
-                'func'       => '_edit_question',
49
-                'capability' => 'ee_edit_questions',
50
-            ),
51
-            'insert_question'    => array(
52
-                'func'       => '_insert_or_update_question',
53
-                'args'       => array('new_question' => true),
54
-                'capability' => 'ee_edit_questions',
55
-                'noheader'   => true,
56
-            ),
57
-            'duplicate_question' => array(
58
-                'func'       => '_duplicate_question',
59
-                'capability' => 'ee_edit_questions',
60
-                'noheader'   => true,
61
-            ),
62
-            'trash_question'     => array(
63
-                'func'       => '_trash_question',
64
-                'capability' => 'ee_delete_question',
65
-                'obj_id'     => $qst_id,
66
-                'noheader'   => true,
67
-            ),
68
-
69
-            'restore_question' => array(
70
-                'func'       => '_trash_or_restore_questions',
71
-                'capability' => 'ee_delete_question',
72
-                'obj_id'     => $qst_id,
73
-                'args'       => array('trash' => false),
74
-                'noheader'   => true,
75
-            ),
76
-
77
-            'delete_question' => array(
78
-                'func'       => '_delete_question',
79
-                'capability' => 'ee_delete_question',
80
-                'obj_id'     => $qst_id,
81
-                'noheader'   => true,
82
-            ),
83
-
84
-            'trash_questions' => array(
85
-                'func'       => '_trash_or_restore_questions',
86
-                'capability' => 'ee_delete_questions',
87
-                'args'       => array('trash' => true),
88
-                'noheader'   => true,
89
-            ),
90
-
91
-            'restore_questions' => array(
92
-                'func'       => '_trash_or_restore_questions',
93
-                'capability' => 'ee_delete_questions',
94
-                'args'       => array('trash' => false),
95
-                'noheader'   => true,
96
-            ),
97
-
98
-            'delete_questions' => array(
99
-                'func'       => '_delete_questions',
100
-                'args'       => array(),
101
-                'capability' => 'ee_delete_questions',
102
-                'noheader'   => true,
103
-            ),
104
-
105
-            'add_question_group' => array(
106
-                'func'       => '_edit_question_group',
107
-                'capability' => 'ee_edit_question_groups',
108
-            ),
109
-
110
-            'edit_question_group' => array(
111
-                'func'       => '_edit_question_group',
112
-                'capability' => 'ee_edit_question_group',
113
-                'obj_id'     => $qsg_id,
114
-                'args'       => array('edit'),
115
-            ),
116
-
117
-            'delete_question_groups' => array(
118
-                'func'       => '_delete_question_groups',
119
-                'capability' => 'ee_delete_question_groups',
120
-                'noheader'   => true,
121
-            ),
122
-
123
-            'delete_question_group' => array(
124
-                'func'       => '_delete_question_groups',
125
-                'capability' => 'ee_delete_question_group',
126
-                'obj_id'     => $qsg_id,
127
-                'noheader'   => true,
128
-            ),
129
-
130
-            'trash_question_group' => array(
131
-                'func'       => '_trash_or_restore_question_groups',
132
-                'args'       => array('trash' => true),
133
-                'capability' => 'ee_delete_question_group',
134
-                'obj_id'     => $qsg_id,
135
-                'noheader'   => true,
136
-            ),
137
-
138
-            'restore_question_group' => array(
139
-                'func'       => '_trash_or_restore_question_groups',
140
-                'args'       => array('trash' => false),
141
-                'capability' => 'ee_delete_question_group',
142
-                'obj_id'     => $qsg_id,
143
-                'noheader'   => true,
144
-            ),
145
-
146
-            'insert_question_group' => array(
147
-                'func'       => '_insert_or_update_question_group',
148
-                'args'       => array('new_question_group' => true),
149
-                'capability' => 'ee_edit_question_groups',
150
-                'noheader'   => true,
151
-            ),
152
-
153
-            'update_question_group' => array(
154
-                'func'       => '_insert_or_update_question_group',
155
-                'args'       => array('new_question_group' => false),
156
-                'capability' => 'ee_edit_question_group',
157
-                'obj_id'     => $qsg_id,
158
-                'noheader'   => true,
159
-            ),
160
-
161
-            'trash_question_groups' => array(
162
-                'func'       => '_trash_or_restore_question_groups',
163
-                'args'       => array('trash' => true),
164
-                'capability' => 'ee_delete_question_groups',
165
-                'noheader'   => array('trash' => false),
166
-            ),
167
-
168
-            'restore_question_groups' => array(
169
-                'func'       => '_trash_or_restore_question_groups',
170
-                'args'       => array('trash' => false),
171
-                'capability' => 'ee_delete_question_groups',
172
-                'noheader'   => true,
173
-            ),
174
-
175
-
176
-            'espresso_update_question_group_order' => array(
177
-                'func'       => 'update_question_group_order',
178
-                'capability' => 'ee_edit_question_groups',
179
-                'noheader'   => true,
180
-            ),
181
-
182
-            'view_reg_form_settings' => array(
183
-                'func'       => '_reg_form_settings',
184
-                'capability' => 'manage_options',
185
-            ),
186
-
187
-            'update_reg_form_settings' => array(
188
-                'func'       => '_update_reg_form_settings',
189
-                'capability' => 'manage_options',
190
-                'noheader'   => true,
191
-            ),
192
-        );
193
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
194
-
195
-        $new_page_config = array(
196
-
197
-            'question_groups' => array(
198
-                'nav'           => array(
199
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
200
-                    'order' => 20,
201
-                ),
202
-                'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
203
-                'help_tabs'     => array(
204
-                    'registration_form_question_groups_help_tab'                           => array(
205
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
206
-                        'filename' => 'registration_form_question_groups',
207
-                    ),
208
-                    'registration_form_question_groups_table_column_headings_help_tab'     => array(
209
-                        'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
210
-                        'filename' => 'registration_form_question_groups_table_column_headings',
211
-                    ),
212
-                    'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
213
-                        'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
214
-                        'filename' => 'registration_form_question_groups_views_bulk_actions_search',
215
-                    ),
216
-                ),
217
-                'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
218
-                'metaboxes'     => $this->_default_espresso_metaboxes,
219
-                'require_nonce' => false,
220
-                'qtips'         => array(
221
-                    'EE_Registration_Form_Tips',
222
-                ),
223
-            ),
224
-
225
-            'add_question' => array(
226
-                'nav'           => array(
227
-                    'label'      => esc_html__('Add Question', 'event_espresso'),
228
-                    'order'      => 5,
229
-                    'persistent' => false,
230
-                ),
231
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
232
-                'help_tabs'     => array(
233
-                    'registration_form_add_question_help_tab' => array(
234
-                        'title'    => esc_html__('Add Question', 'event_espresso'),
235
-                        'filename' => 'registration_form_add_question',
236
-                    ),
237
-                ),
238
-                'help_tour'     => array('Registration_Form_Add_Question_Help_Tour'),
239
-                'require_nonce' => false,
240
-            ),
241
-
242
-            'add_question_group' => array(
243
-                'nav'           => array(
244
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
245
-                    'order'      => 5,
246
-                    'persistent' => false,
247
-                ),
248
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
249
-                'help_tabs'     => array(
250
-                    'registration_form_add_question_group_help_tab' => array(
251
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
252
-                        'filename' => 'registration_form_add_question_group',
253
-                    ),
254
-                ),
255
-                'help_tour'     => array('Registration_Form_Add_Question_Group_Help_Tour'),
256
-                'require_nonce' => false,
257
-            ),
258
-
259
-            'edit_question_group' => array(
260
-                'nav'           => array(
261
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
262
-                    'order'      => 5,
263
-                    'persistent' => false,
264
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
265
-                        array('question_group_id' => $this->_req_data['question_group_id']),
266
-                        $this->_current_page_view_url
267
-                    ) : $this->_admin_base_url,
268
-                ),
269
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
270
-                'help_tabs'     => array(
271
-                    'registration_form_edit_question_group_help_tab' => array(
272
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
273
-                        'filename' => 'registration_form_edit_question_group',
274
-                    ),
275
-                ),
276
-                'help_tour'     => array('Registration_Form_Edit_Question_Group_Help_Tour'),
277
-                'require_nonce' => false,
278
-            ),
279
-
280
-            'view_reg_form_settings' => array(
281
-                'nav'           => array(
282
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
283
-                    'order' => 40,
284
-                ),
285
-                'labels'        => array(
286
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
287
-                ),
288
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
289
-                'help_tabs'     => array(
290
-                    'registration_form_reg_form_settings_help_tab' => array(
291
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
292
-                        'filename' => 'registration_form_reg_form_settings',
293
-                    ),
294
-                ),
295
-                'help_tour'     => array('Registration_Form_Settings_Help_Tour'),
296
-                'require_nonce' => false,
297
-            ),
298
-
299
-        );
300
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
301
-
302
-        // change the list table we're going to use so it's the NEW list table!
303
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
304
-
305
-
306
-        // additional labels
307
-        $new_labels = array(
308
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
309
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
310
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
311
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
312
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
313
-        );
314
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
315
-    }
316
-
317
-
318
-    /**
319
-     * @return void
320
-     */
321
-    protected function _ajax_hooks()
322
-    {
323
-        add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
324
-    }
325
-
326
-
327
-    /**
328
-     * @return void
329
-     */
330
-    public function load_scripts_styles_question_groups()
331
-    {
332
-        wp_enqueue_script('espresso_ajax_table_sorting');
333
-    }
334
-
335
-
336
-    /**
337
-     * @return void
338
-     */
339
-    public function load_scripts_styles_add_question_group()
340
-    {
341
-        $this->load_scripts_styles_forms();
342
-        $this->load_sortable_question_script();
343
-    }
344
-
345
-
346
-    /**
347
-     * @return void
348
-     */
349
-    public function load_scripts_styles_edit_question_group()
350
-    {
351
-        $this->load_scripts_styles_forms();
352
-        $this->load_sortable_question_script();
353
-    }
354
-
355
-
356
-    /**
357
-     * registers and enqueues script for questions
358
-     *
359
-     * @return void
360
-     */
361
-    public function load_sortable_question_script()
362
-    {
363
-        wp_register_script(
364
-            'ee-question-sortable',
365
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
366
-            array('jquery-ui-sortable'),
367
-            EVENT_ESPRESSO_VERSION,
368
-            true
369
-        );
370
-        wp_enqueue_script('ee-question-sortable');
371
-    }
372
-
373
-
374
-    /**
375
-     * @return void
376
-     */
377
-    protected function _set_list_table_views_default()
378
-    {
379
-        $this->_views = array(
380
-            'all' => array(
381
-                'slug'        => 'all',
382
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
383
-                'count'       => 0,
384
-                'bulk_action' => array(
385
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
386
-                ),
387
-            ),
388
-        );
389
-
390
-        if (EE_Registry::instance()->CAP->current_user_can(
391
-            'ee_delete_questions',
392
-            'espresso_registration_form_trash_questions'
393
-        )
394
-        ) {
395
-            $this->_views['trash'] = array(
396
-                'slug'        => 'trash',
397
-                'label'       => esc_html__('Trash', 'event_espresso'),
398
-                'count'       => 0,
399
-                'bulk_action' => array(
400
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
401
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
402
-                ),
403
-            );
404
-        }
405
-    }
406
-
407
-
408
-    /**
409
-     * @return void
410
-     */
411
-    protected function _set_list_table_views_question_groups()
412
-    {
413
-        $this->_views = array(
414
-            'all' => array(
415
-                'slug'        => 'all',
416
-                'label'       => esc_html__('All', 'event_espresso'),
417
-                'count'       => 0,
418
-                'bulk_action' => array(
419
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
420
-                ),
421
-            ),
422
-        );
423
-
424
-        if (EE_Registry::instance()->CAP->current_user_can(
425
-            'ee_delete_question_groups',
426
-            'espresso_registration_form_trash_question_groups'
427
-        )
428
-        ) {
429
-            $this->_views['trash'] = array(
430
-                'slug'        => 'trash',
431
-                'label'       => esc_html__('Trash', 'event_espresso'),
432
-                'count'       => 0,
433
-                'bulk_action' => array(
434
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
435
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
436
-                ),
437
-            );
438
-        }
439
-    }
440
-
441
-
442
-    /**
443
-     * @return void
444
-     * @throws EE_Error
445
-     * @throws InvalidArgumentException
446
-     * @throws InvalidDataTypeException
447
-     * @throws InvalidInterfaceException
448
-     */
449
-    protected function _questions_overview_list_table()
450
-    {
451
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
452
-            'add_question',
453
-            'add_question',
454
-            array(),
455
-            'add-new-h2'
456
-        );
457
-        parent::_questions_overview_list_table();
458
-    }
459
-
460
-
461
-    /**
462
-     * @return void
463
-     * @throws DomainException
464
-     * @throws EE_Error
465
-     * @throws InvalidArgumentException
466
-     * @throws InvalidDataTypeException
467
-     * @throws InvalidInterfaceException
468
-     */
469
-    protected function _question_groups_overview_list_table()
470
-    {
471
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
472
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
473
-            'add_question_group',
474
-            'add_question_group',
475
-            array(),
476
-            'add-new-h2'
477
-        );
478
-        $this->display_admin_list_table_page_with_sidebar();
479
-    }
480
-
481
-
482
-    /**
483
-     * @return void
484
-     * @throws EE_Error
485
-     * @throws InvalidArgumentException
486
-     * @throws InvalidDataTypeException
487
-     * @throws InvalidInterfaceException
488
-     */
489
-    protected function _delete_question()
490
-    {
491
-        $success = $this->_delete_items($this->_question_model);
492
-        $this->_redirect_after_action(
493
-            $success,
494
-            $this->_question_model->item_name($success),
495
-            'deleted',
496
-            array('action' => 'default', 'status' => 'all')
497
-        );
498
-    }
499
-
500
-
501
-    /**
502
-     * @return void
503
-     * @throws EE_Error
504
-     * @throws InvalidArgumentException
505
-     * @throws InvalidDataTypeException
506
-     * @throws InvalidInterfaceException
507
-     */
508
-    protected function _delete_questions()
509
-    {
510
-        $success = $this->_delete_items($this->_question_model);
511
-        $this->_redirect_after_action(
512
-            $success,
513
-            $this->_question_model->item_name($success),
514
-            'deleted permanently',
515
-            array('action' => 'default', 'status' => 'trash')
516
-        );
517
-    }
518
-
519
-
520
-    /**
521
-     * Performs the deletion of a single or multiple questions or question groups.
522
-     *
523
-     * @param EEM_Soft_Delete_Base $model
524
-     * @return int number of items deleted permanently
525
-     * @throws EE_Error
526
-     * @throws InvalidArgumentException
527
-     * @throws InvalidDataTypeException
528
-     * @throws InvalidInterfaceException
529
-     */
530
-    private function _delete_items(EEM_Soft_Delete_Base $model)
531
-    {
532
-        $success = 0;
533
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
534
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
535
-            // if array has more than one element than success message should be plural
536
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
537
-            // cycle thru bulk action checkboxes
538
-            while (list($ID, $value) = each($this->_req_data['checkbox'])) {
539
-                if (! $this->_delete_item($ID, $model)) {
540
-                    $success = 0;
541
-                }
542
-            }
543
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
544
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
545
-        } elseif (! empty($this->_req_data['QST_ID'])) {
546
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
547
-        } else {
548
-            EE_Error::add_error(
549
-                sprintf(
550
-                    esc_html__(
551
-                        "No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
552
-                        "event_espresso"
553
-                    )
554
-                ),
555
-                __FILE__,
556
-                __FUNCTION__,
557
-                __LINE__
558
-            );
559
-        }
560
-        return $success;
561
-    }
562
-
563
-
564
-    /**
565
-     * Deletes the specified question (and its associated question options) or question group
566
-     *
567
-     * @param int                  $id
568
-     * @param EEM_Soft_Delete_Base $model
569
-     * @return boolean
570
-     * @throws EE_Error
571
-     * @throws InvalidArgumentException
572
-     * @throws InvalidDataTypeException
573
-     * @throws InvalidInterfaceException
574
-     */
575
-    protected function _delete_item($id, $model)
576
-    {
577
-        if ($model instanceof EEM_Question) {
578
-            EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
579
-        }
580
-        return $model->delete_permanently_by_ID(absint($id));
581
-    }
582
-
583
-
584
-    /******************************    QUESTION GROUPS    ******************************/
585
-
586
-
587
-    /**
588
-     * @param string $type
589
-     * @return void
590
-     * @throws DomainException
591
-     * @throws EE_Error
592
-     * @throws InvalidArgumentException
593
-     * @throws InvalidDataTypeException
594
-     * @throws InvalidInterfaceException
595
-     */
596
-    protected function _edit_question_group($type = 'add')
597
-    {
598
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
599
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
600
-            ? absint($this->_req_data['QSG_ID'])
601
-            : false;
602
-
603
-        switch ($this->_req_action) {
604
-            case 'add_question_group':
605
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
606
-                break;
607
-            case 'edit_question_group':
608
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
609
-                break;
610
-            default:
611
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
612
-        }
613
-        // add ID to title if editing
614
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
615
-        if ($ID) {
616
-            /** @var EE_Question_Group $questionGroup */
617
-            $questionGroup = $this->_question_group_model->get_one_by_ID($ID);
618
-            $additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
619
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
620
-        } else {
621
-            /** @var EE_Question_Group $questionGroup */
622
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
623
-            $questionGroup->set_order_to_latest();
624
-            $this->_set_add_edit_form_tags('insert_question_group');
625
-        }
626
-        $this->_template_args['values'] = $this->_yes_no_values;
627
-        $this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
628
-        $this->_template_args['QSG_ID'] = $ID ? $ID : true;
629
-        $this->_template_args['question_group'] = $questionGroup;
630
-
631
-        $redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
632
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
633
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
634
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
635
-            $this->_template_args,
636
-            true
637
-        );
638
-
639
-        // the details template wrapper
640
-        $this->display_admin_page_with_sidebar();
641
-    }
642
-
643
-
644
-    /**
645
-     * @return void
646
-     * @throws EE_Error
647
-     * @throws InvalidArgumentException
648
-     * @throws InvalidDataTypeException
649
-     * @throws InvalidInterfaceException
650
-     */
651
-    protected function _delete_question_groups()
652
-    {
653
-        $success = $this->_delete_items($this->_question_group_model);
654
-        $this->_redirect_after_action(
655
-            $success,
656
-            $this->_question_group_model->item_name($success),
657
-            'deleted permanently',
658
-            array('action' => 'question_groups', 'status' => 'trash')
659
-        );
660
-    }
661
-
662
-
663
-    /**
664
-     * @param bool $new_question_group
665
-     * @throws EE_Error
666
-     * @throws InvalidArgumentException
667
-     * @throws InvalidDataTypeException
668
-     * @throws InvalidInterfaceException
669
-     */
670
-    protected function _insert_or_update_question_group($new_question_group = true)
671
-    {
672
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
673
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
674
-        if ($new_question_group) {
675
-            $QSG_ID = $this->_question_group_model->insert($set_column_values);
676
-            $success = $QSG_ID ? 1 : 0;
677
-        } else {
678
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
679
-            unset($set_column_values['QSG_ID']);
680
-            $success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
681
-        }
682
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
683
-            EEM_Attendee::system_question_phone
684
-        );
685
-        // update the existing related questions
686
-        // BUT FIRST...  delete the phone question from the Question_Group_Question
687
-        // if it is being added to this question group (therefore removed from the existing group)
688
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
689
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
690
-            EEM_Question_Group_Question::instance()->delete(
691
-                array(
692
-                    array(
693
-                        'QST_ID' => $phone_question_id,
694
-                        'QSG_ID' => array('!=', $QSG_ID),
695
-                    ),
696
-                )
697
-            );
698
-        }
699
-        /** @type EE_Question_Group $question_group */
700
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
701
-        $questions = $question_group->questions();
702
-        // make sure system phone question is added to list of questions for this group
703
-        if (! isset($questions[ $phone_question_id ])) {
704
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
705
-        }
706
-
707
-        foreach ($questions as $question_ID => $question) {
708
-            // first we always check for order.
709
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
710
-                // update question order
711
-                $question_group->update_question_order(
712
-                    $question_ID,
713
-                    $this->_req_data['question_orders'][ $question_ID ]
714
-                );
715
-            }
716
-
717
-            // then we always check if adding or removing.
718
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
719
-                $question_group->add_question($question_ID);
720
-            } else {
721
-                // not found, remove it (but only if not a system question for the personal group
722
-                // with the exception of lname system question - we allow removal of it)
723
-                if (in_array(
724
-                    $question->system_ID(),
725
-                    EEM_Question::instance()->required_system_questions_in_system_question_group(
726
-                        $question_group->system_group()
727
-                    )
728
-                )) {
729
-                    continue;
730
-                } else {
731
-                    $question_group->remove_question($question_ID);
732
-                }
733
-            }
734
-        }
735
-        // save new related questions
736
-        if (isset($this->_req_data['questions'])) {
737
-            foreach ($this->_req_data['questions'] as $QST_ID) {
738
-                $question_group->add_question($QST_ID);
739
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
740
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
741
-                }
742
-            }
743
-        }
744
-
745
-        if ($success !== false) {
746
-            $msg = $new_question_group
747
-                ? sprintf(
748
-                    esc_html__('The %s has been created', 'event_espresso'),
749
-                    $this->_question_group_model->item_name()
750
-                )
751
-                : sprintf(
752
-                    esc_html__(
753
-                        'The %s has been updated',
754
-                        'event_espresso'
755
-                    ),
756
-                    $this->_question_group_model->item_name()
757
-                );
758
-            EE_Error::add_success($msg);
759
-        }
760
-        $this->_redirect_after_action(
761
-            false,
762
-            '',
763
-            '',
764
-            array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
765
-            true
766
-        );
767
-    }
768
-
769
-
770
-    /**
771
-     * duplicates a question and all its question options and redirects to the new question.
772
-     *
773
-     * @return void
774
-     * @throws EE_Error
775
-     * @throws InvalidArgumentException
776
-     * @throws ReflectionException
777
-     * @throws InvalidDataTypeException
778
-     * @throws InvalidInterfaceException
779
-     */
780
-    public function _duplicate_question()
781
-    {
782
-        $question_ID = (int) $this->_req_data['QST_ID'];
783
-        $question = EEM_Question::instance()->get_one_by_ID($question_ID);
784
-        if ($question instanceof EE_Question) {
785
-            $new_question = $question->duplicate();
786
-            if ($new_question instanceof EE_Question) {
787
-                $this->_redirect_after_action(
788
-                    true,
789
-                    esc_html__('Question', 'event_espresso'),
790
-                    esc_html__('Duplicated', 'event_espresso'),
791
-                    array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
792
-                    true
793
-                );
794
-            } else {
795
-                global $wpdb;
796
-                EE_Error::add_error(
797
-                    sprintf(
798
-                        esc_html__(
799
-                            'Could not duplicate question with ID %1$d because: %2$s',
800
-                            'event_espresso'
801
-                        ),
802
-                        $question_ID,
803
-                        $wpdb->last_error
804
-                    ),
805
-                    __FILE__,
806
-                    __FUNCTION__,
807
-                    __LINE__
808
-                );
809
-                $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
810
-            }
811
-        } else {
812
-            EE_Error::add_error(
813
-                sprintf(
814
-                    esc_html__(
815
-                        'Could not duplicate question with ID %d because it didn\'t exist!',
816
-                        'event_espresso'
817
-                    ),
818
-                    $question_ID
819
-                ),
820
-                __FILE__,
821
-                __FUNCTION__,
822
-                __LINE__
823
-            );
824
-            $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
825
-        }
826
-    }
827
-
828
-
829
-    /**
830
-     * @param bool $trash
831
-     * @throws EE_Error
832
-     */
833
-    protected function _trash_or_restore_question_groups($trash = true)
834
-    {
835
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
836
-    }
837
-
838
-
839
-    /**
840
-     *_trash_question
841
-     *
842
-     * @return void
843
-     * @throws EE_Error
844
-     */
845
-    protected function _trash_question()
846
-    {
847
-        $success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
848
-        $query_args = array('action' => 'default', 'status' => 'all');
849
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
850
-    }
851
-
852
-
853
-    /**
854
-     * @param bool $trash
855
-     * @throws EE_Error
856
-     */
857
-    protected function _trash_or_restore_questions($trash = true)
858
-    {
859
-        $this->_trash_or_restore_items($this->_question_model, $trash);
860
-    }
861
-
862
-
863
-    /**
864
-     * Internally used to delete or restore items, using the request data. Meant to be
865
-     * flexible between question or question groups
866
-     *
867
-     * @param EEM_Soft_Delete_Base $model
868
-     * @param boolean              $trash whether to trash or restore
869
-     * @throws EE_Error
870
-     */
871
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
872
-    {
873
-
874
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
875
-
876
-        $success = 1;
877
-        // Checkboxes
878
-        // echo "trash $trash";
879
-        // var_dump($this->_req_data['checkbox']);die;
880
-        if (isset($this->_req_data['checkbox'])) {
881
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
882
-                // if array has more than one element than success message should be plural
883
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
884
-                // cycle thru bulk action checkboxes
885
-                while (list($ID, $value) = each($this->_req_data['checkbox'])) {
886
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
887
-                        $success = 0;
888
-                    }
889
-                }
890
-            } else {
891
-                // grab single id and delete
892
-                $ID = absint($this->_req_data['checkbox']);
893
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
894
-                    $success = 0;
895
-                }
896
-            }
897
-        } else {
898
-            // delete via trash link
899
-            // grab single id and delete
900
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
901
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
902
-                $success = 0;
903
-            }
904
-        }
905
-
906
-
907
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
908
-        // echo "action :$action";
909
-        // $action = 'questions' ? 'default' : $action;
910
-        if ($trash) {
911
-            $action_desc = 'trashed';
912
-            $status = 'trash';
913
-        } else {
914
-            $action_desc = 'restored';
915
-            $status = 'all';
916
-        }
917
-        $this->_redirect_after_action(
918
-            $success,
919
-            $model->item_name($success),
920
-            $action_desc,
921
-            array('action' => $action, 'status' => $status)
922
-        );
923
-    }
924
-
925
-
926
-    /**
927
-     * @param            $per_page
928
-     * @param int        $current_page
929
-     * @param bool|false $count
930
-     * @return EE_Soft_Delete_Base_Class[]|int
931
-     * @throws EE_Error
932
-     * @throws InvalidArgumentException
933
-     * @throws InvalidDataTypeException
934
-     * @throws InvalidInterfaceException
935
-     */
936
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
937
-    {
938
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
939
-
940
-        if ($count) {
941
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
942
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
943
-            $results = $this->_question_model->count_deleted($where);
944
-        } else {
945
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
946
-            $results = $this->_question_model->get_all_deleted($query_params);
947
-        }
948
-        return $results;
949
-    }
950
-
951
-
952
-    /**
953
-     * @param            $per_page
954
-     * @param int        $current_page
955
-     * @param bool|false $count
956
-     * @return EE_Soft_Delete_Base_Class[]|int
957
-     * @throws EE_Error
958
-     * @throws InvalidArgumentException
959
-     * @throws InvalidDataTypeException
960
-     * @throws InvalidInterfaceException
961
-     */
962
-    public function get_question_groups($per_page, $current_page = 1, $count = false)
963
-    {
964
-        $questionGroupModel = EEM_Question_Group::instance();
965
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
966
-        if ($count) {
967
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
968
-            $results = $questionGroupModel->count($where);
969
-        } else {
970
-            $results = $questionGroupModel->get_all($query_params);
971
-        }
972
-        return $results;
973
-    }
974
-
975
-
976
-    /**
977
-     * @param      $per_page
978
-     * @param int  $current_page
979
-     * @param bool $count
980
-     * @return EE_Soft_Delete_Base_Class[]|int
981
-     * @throws EE_Error
982
-     * @throws InvalidArgumentException
983
-     * @throws InvalidDataTypeException
984
-     * @throws InvalidInterfaceException
985
-     */
986
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
987
-    {
988
-        $questionGroupModel = EEM_Question_Group::instance();
989
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
990
-        if ($count) {
991
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
992
-            $query_params['limit'] = null;
993
-            $results = $questionGroupModel->count_deleted($where);
994
-        } else {
995
-            $results = $questionGroupModel->get_all_deleted($query_params);
996
-        }
997
-        return $results;
998
-    }
999
-
1000
-
1001
-    /**
1002
-     * method for performing updates to question order
1003
-     *
1004
-     * @return void results array
1005
-     * @throws EE_Error
1006
-     * @throws InvalidArgumentException
1007
-     * @throws InvalidDataTypeException
1008
-     * @throws InvalidInterfaceException
1009
-     */
1010
-    public function update_question_group_order()
1011
-    {
1012
-
1013
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1014
-
1015
-        // grab our row IDs
1016
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1017
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
1018
-            : array();
1019
-
1020
-        $perpage = ! empty($this->_req_data['perpage'])
1021
-            ? (int) $this->_req_data['perpage']
1022
-            : null;
1023
-        $curpage = ! empty($this->_req_data['curpage'])
1024
-            ? (int) $this->_req_data['curpage']
1025
-            : null;
1026
-
1027
-        if (! empty($row_ids)) {
1028
-            // figure out where we start the row_id count at for the current page.
1029
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1030
-
1031
-            $row_count = count($row_ids);
1032
-            for ($i = 0; $i < $row_count; $i++) {
1033
-                // Update the questions when re-ordering
1034
-                $updated = EEM_Question_Group::instance()->update(
1035
-                    array('QSG_order' => $qsgcount),
1036
-                    array(array('QSG_ID' => $row_ids[ $i ]))
1037
-                );
1038
-                if ($updated === false) {
1039
-                    $success = false;
1040
-                }
1041
-                $qsgcount++;
1042
-            }
1043
-        } else {
1044
-            $success = false;
1045
-        }
1046
-
1047
-        $errors = ! $success
1048
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1049
-            : false;
1050
-
1051
-        echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1052
-        die();
1053
-    }
1054
-
1055
-
1056
-
1057
-    /***************************************       REGISTRATION SETTINGS       ***************************************/
1058
-
1059
-
1060
-    /**
1061
-     * @throws DomainException
1062
-     * @throws EE_Error
1063
-     * @throws InvalidArgumentException
1064
-     * @throws InvalidDataTypeException
1065
-     * @throws InvalidInterfaceException
1066
-     */
1067
-    protected function _reg_form_settings()
1068
-    {
1069
-        $this->_template_args['values'] = $this->_yes_no_values;
1070
-        add_action(
1071
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1072
-            array($this, 'email_validation_settings_form'),
1073
-            2
1074
-        );
1075
-        $this->_template_args = (array) apply_filters(
1076
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1077
-            $this->_template_args
1078
-        );
1079
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
1080
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1081
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1082
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1083
-            $this->_template_args,
1084
-            true
1085
-        );
1086
-        $this->display_admin_page_with_sidebar();
1087
-    }
1088
-
1089
-
1090
-    /**
1091
-     * @return void
1092
-     * @throws EE_Error
1093
-     * @throws InvalidArgumentException
1094
-     * @throws ReflectionException
1095
-     * @throws InvalidDataTypeException
1096
-     * @throws InvalidInterfaceException
1097
-     */
1098
-    protected function _update_reg_form_settings()
1099
-    {
1100
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1101
-            EE_Registry::instance()->CFG->registration
1102
-        );
1103
-        EE_Registry::instance()->CFG->registration = apply_filters(
1104
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1105
-            EE_Registry::instance()->CFG->registration
1106
-        );
1107
-        $success = $this->_update_espresso_configuration(
1108
-            esc_html__('Registration Form Options', 'event_espresso'),
1109
-            EE_Registry::instance()->CFG,
1110
-            __FILE__,
1111
-            __FUNCTION__,
1112
-            __LINE__
1113
-        );
1114
-        $this->_redirect_after_action(
1115
-            $success,
1116
-            esc_html__('Registration Form Options', 'event_espresso'),
1117
-            'updated',
1118
-            array('action' => 'view_reg_form_settings')
1119
-        );
1120
-    }
1121
-
1122
-
1123
-    /**
1124
-     * @return void
1125
-     * @throws EE_Error
1126
-     * @throws InvalidArgumentException
1127
-     * @throws InvalidDataTypeException
1128
-     * @throws InvalidInterfaceException
1129
-     */
1130
-    public function email_validation_settings_form()
1131
-    {
1132
-        echo $this->_email_validation_settings_form()->get_html();
1133
-    }
1134
-
1135
-
1136
-    /**
1137
-     * _email_validation_settings_form
1138
-     *
1139
-     * @access protected
1140
-     * @return EE_Form_Section_Proper
1141
-     * @throws \EE_Error
1142
-     */
1143
-    protected function _email_validation_settings_form()
1144
-    {
1145
-        return new EE_Form_Section_Proper(
1146
-            array(
1147
-                'name'            => 'email_validation_settings',
1148
-                'html_id'         => 'email_validation_settings',
1149
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1150
-                'subsections'     => apply_filters(
1151
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1152
-                    array(
1153
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
1154
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1155
-                        ),
1156
-                        'email_validation_level' => new EE_Select_Input(
1157
-                            array(
1158
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
1159
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1160
-                                'i18n'       => esc_html__('International', 'event_espresso'),
1161
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1162
-                            ),
1163
-                            array(
1164
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1165
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
1166
-                                'html_help_text'  => esc_html__(
1167
-                                    'These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
1168
-                                    'event_espresso'
1169
-                                ),
1170
-                                'default'         => isset(
1171
-                                    EE_Registry::instance()->CFG->registration->email_validation_level
1172
-                                )
1173
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
1174
-                                    : 'wp_default',
1175
-                                'required'        => false,
1176
-                            )
1177
-                        ),
1178
-                    )
1179
-                ),
1180
-            )
1181
-        );
1182
-    }
1183
-
1184
-
1185
-    /**
1186
-     * @param EE_Registration_Config $EE_Registration_Config
1187
-     * @return EE_Registration_Config
1188
-     * @throws EE_Error
1189
-     * @throws InvalidArgumentException
1190
-     * @throws ReflectionException
1191
-     * @throws InvalidDataTypeException
1192
-     * @throws InvalidInterfaceException
1193
-     */
1194
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1195
-    {
1196
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1197
-        try {
1198
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1199
-            // if not displaying a form, then check for form submission
1200
-            if ($email_validation_settings_form->was_submitted()) {
1201
-                // capture form data
1202
-                $email_validation_settings_form->receive_form_submission();
1203
-                // validate form data
1204
-                if ($email_validation_settings_form->is_valid()) {
1205
-                    // grab validated data from form
1206
-                    $valid_data = $email_validation_settings_form->valid_data();
1207
-                    if (isset($valid_data['email_validation_level'])) {
1208
-                        $email_validation_level = $valid_data['email_validation_level'];
1209
-                        // now if they want to use international email addresses
1210
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1211
-                            // in case we need to reset their email validation level,
1212
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1213
-                            if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1214
-                                // if so, then reset it back to "basic" since that is the only other option that,
1215
-                                // despite offering poor validation, supports i18n email addresses
1216
-                                $prev_email_validation_level = 'basic';
1217
-                            }
1218
-                            // confirm our i18n email validation will work on the server
1219
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1220
-                                // or reset email validation level to previous value
1221
-                                $email_validation_level = $prev_email_validation_level;
1222
-                            }
1223
-                        }
1224
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1225
-                    } else {
1226
-                        EE_Error::add_error(
1227
-                            esc_html__(
1228
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1229
-                                'event_espresso'
1230
-                            ),
1231
-                            __FILE__,
1232
-                            __FUNCTION__,
1233
-                            __LINE__
1234
-                        );
1235
-                    }
1236
-                } else {
1237
-                    if ($email_validation_settings_form->submission_error_message() !== '') {
1238
-                        EE_Error::add_error(
1239
-                            $email_validation_settings_form->submission_error_message(),
1240
-                            __FILE__,
1241
-                            __FUNCTION__,
1242
-                            __LINE__
1243
-                        );
1244
-                    }
1245
-                }
1246
-            }
1247
-        } catch (EE_Error $e) {
1248
-            $e->get_error();
1249
-        }
1250
-        return $EE_Registration_Config;
1251
-    }
1252
-
1253
-
1254
-    /**
1255
-     * confirms that the server's PHP version has the PCRE module enabled,
1256
-     * and that the PCRE version works with our i18n email validation
1257
-     *
1258
-     * @param EE_Registration_Config $EE_Registration_Config
1259
-     * @param string                 $email_validation_level
1260
-     * @return bool
1261
-     */
1262
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1263
-    {
1264
-        // first check that PCRE is enabled
1265
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1266
-            EE_Error::add_error(
1267
-                sprintf(
1268
-                    esc_html__(
1269
-                        'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1270
-                        'event_espresso'
1271
-                    ),
1272
-                    '<br />'
1273
-                ),
1274
-                __FILE__,
1275
-                __FUNCTION__,
1276
-                __LINE__
1277
-            );
1278
-            return false;
1279
-        } else {
1280
-            // PCRE support is enabled, but let's still
1281
-            // perform a test to see if the server will support it.
1282
-            // but first, save the updated validation level to the config,
1283
-            // so that the validation strategy picks it up.
1284
-            // this will get bumped back down if it doesn't work
1285
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1286
-            try {
1287
-                $email_validator = new EE_Email_Validation_Strategy();
1288
-                $i18n_email_address = apply_filters(
1289
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1290
-                    'jägerjü[email protected]'
1291
-                );
1292
-                $email_validator->validate($i18n_email_address);
1293
-            } catch (Exception $e) {
1294
-                EE_Error::add_error(
1295
-                    sprintf(
1296
-                        esc_html__(
1297
-                            'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1298
-                            'event_espresso'
1299
-                        ),
1300
-                        '<br />',
1301
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank">http://php.net/manual/en/pcre.installation.php</a>'
1302
-                    ),
1303
-                    __FILE__,
1304
-                    __FUNCTION__,
1305
-                    __LINE__
1306
-                );
1307
-                return false;
1308
-            }
1309
-        }
1310
-        return true;
1311
-    }
17
+	/**
18
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
19
+	 */
20
+	public function __construct($routing = true)
21
+	{
22
+		define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form' . DS);
23
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets' . DS);
24
+		define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
25
+		define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates' . DS);
26
+		define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
27
+		parent::__construct($routing);
28
+	}
29
+
30
+
31
+	/**
32
+	 * @return void
33
+	 */
34
+	protected function _extend_page_config()
35
+	{
36
+		$this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
37
+		$qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
38
+			? $this->_req_data['QST_ID'] : 0;
39
+		$qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
40
+			? $this->_req_data['QSG_ID'] : 0;
41
+
42
+		$new_page_routes = array(
43
+			'question_groups'    => array(
44
+				'func'       => '_question_groups_overview_list_table',
45
+				'capability' => 'ee_read_question_groups',
46
+			),
47
+			'add_question'       => array(
48
+				'func'       => '_edit_question',
49
+				'capability' => 'ee_edit_questions',
50
+			),
51
+			'insert_question'    => array(
52
+				'func'       => '_insert_or_update_question',
53
+				'args'       => array('new_question' => true),
54
+				'capability' => 'ee_edit_questions',
55
+				'noheader'   => true,
56
+			),
57
+			'duplicate_question' => array(
58
+				'func'       => '_duplicate_question',
59
+				'capability' => 'ee_edit_questions',
60
+				'noheader'   => true,
61
+			),
62
+			'trash_question'     => array(
63
+				'func'       => '_trash_question',
64
+				'capability' => 'ee_delete_question',
65
+				'obj_id'     => $qst_id,
66
+				'noheader'   => true,
67
+			),
68
+
69
+			'restore_question' => array(
70
+				'func'       => '_trash_or_restore_questions',
71
+				'capability' => 'ee_delete_question',
72
+				'obj_id'     => $qst_id,
73
+				'args'       => array('trash' => false),
74
+				'noheader'   => true,
75
+			),
76
+
77
+			'delete_question' => array(
78
+				'func'       => '_delete_question',
79
+				'capability' => 'ee_delete_question',
80
+				'obj_id'     => $qst_id,
81
+				'noheader'   => true,
82
+			),
83
+
84
+			'trash_questions' => array(
85
+				'func'       => '_trash_or_restore_questions',
86
+				'capability' => 'ee_delete_questions',
87
+				'args'       => array('trash' => true),
88
+				'noheader'   => true,
89
+			),
90
+
91
+			'restore_questions' => array(
92
+				'func'       => '_trash_or_restore_questions',
93
+				'capability' => 'ee_delete_questions',
94
+				'args'       => array('trash' => false),
95
+				'noheader'   => true,
96
+			),
97
+
98
+			'delete_questions' => array(
99
+				'func'       => '_delete_questions',
100
+				'args'       => array(),
101
+				'capability' => 'ee_delete_questions',
102
+				'noheader'   => true,
103
+			),
104
+
105
+			'add_question_group' => array(
106
+				'func'       => '_edit_question_group',
107
+				'capability' => 'ee_edit_question_groups',
108
+			),
109
+
110
+			'edit_question_group' => array(
111
+				'func'       => '_edit_question_group',
112
+				'capability' => 'ee_edit_question_group',
113
+				'obj_id'     => $qsg_id,
114
+				'args'       => array('edit'),
115
+			),
116
+
117
+			'delete_question_groups' => array(
118
+				'func'       => '_delete_question_groups',
119
+				'capability' => 'ee_delete_question_groups',
120
+				'noheader'   => true,
121
+			),
122
+
123
+			'delete_question_group' => array(
124
+				'func'       => '_delete_question_groups',
125
+				'capability' => 'ee_delete_question_group',
126
+				'obj_id'     => $qsg_id,
127
+				'noheader'   => true,
128
+			),
129
+
130
+			'trash_question_group' => array(
131
+				'func'       => '_trash_or_restore_question_groups',
132
+				'args'       => array('trash' => true),
133
+				'capability' => 'ee_delete_question_group',
134
+				'obj_id'     => $qsg_id,
135
+				'noheader'   => true,
136
+			),
137
+
138
+			'restore_question_group' => array(
139
+				'func'       => '_trash_or_restore_question_groups',
140
+				'args'       => array('trash' => false),
141
+				'capability' => 'ee_delete_question_group',
142
+				'obj_id'     => $qsg_id,
143
+				'noheader'   => true,
144
+			),
145
+
146
+			'insert_question_group' => array(
147
+				'func'       => '_insert_or_update_question_group',
148
+				'args'       => array('new_question_group' => true),
149
+				'capability' => 'ee_edit_question_groups',
150
+				'noheader'   => true,
151
+			),
152
+
153
+			'update_question_group' => array(
154
+				'func'       => '_insert_or_update_question_group',
155
+				'args'       => array('new_question_group' => false),
156
+				'capability' => 'ee_edit_question_group',
157
+				'obj_id'     => $qsg_id,
158
+				'noheader'   => true,
159
+			),
160
+
161
+			'trash_question_groups' => array(
162
+				'func'       => '_trash_or_restore_question_groups',
163
+				'args'       => array('trash' => true),
164
+				'capability' => 'ee_delete_question_groups',
165
+				'noheader'   => array('trash' => false),
166
+			),
167
+
168
+			'restore_question_groups' => array(
169
+				'func'       => '_trash_or_restore_question_groups',
170
+				'args'       => array('trash' => false),
171
+				'capability' => 'ee_delete_question_groups',
172
+				'noheader'   => true,
173
+			),
174
+
175
+
176
+			'espresso_update_question_group_order' => array(
177
+				'func'       => 'update_question_group_order',
178
+				'capability' => 'ee_edit_question_groups',
179
+				'noheader'   => true,
180
+			),
181
+
182
+			'view_reg_form_settings' => array(
183
+				'func'       => '_reg_form_settings',
184
+				'capability' => 'manage_options',
185
+			),
186
+
187
+			'update_reg_form_settings' => array(
188
+				'func'       => '_update_reg_form_settings',
189
+				'capability' => 'manage_options',
190
+				'noheader'   => true,
191
+			),
192
+		);
193
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
194
+
195
+		$new_page_config = array(
196
+
197
+			'question_groups' => array(
198
+				'nav'           => array(
199
+					'label' => esc_html__('Question Groups', 'event_espresso'),
200
+					'order' => 20,
201
+				),
202
+				'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
203
+				'help_tabs'     => array(
204
+					'registration_form_question_groups_help_tab'                           => array(
205
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
206
+						'filename' => 'registration_form_question_groups',
207
+					),
208
+					'registration_form_question_groups_table_column_headings_help_tab'     => array(
209
+						'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
210
+						'filename' => 'registration_form_question_groups_table_column_headings',
211
+					),
212
+					'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
213
+						'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
214
+						'filename' => 'registration_form_question_groups_views_bulk_actions_search',
215
+					),
216
+				),
217
+				'help_tour'     => array('Registration_Form_Question_Groups_Help_Tour'),
218
+				'metaboxes'     => $this->_default_espresso_metaboxes,
219
+				'require_nonce' => false,
220
+				'qtips'         => array(
221
+					'EE_Registration_Form_Tips',
222
+				),
223
+			),
224
+
225
+			'add_question' => array(
226
+				'nav'           => array(
227
+					'label'      => esc_html__('Add Question', 'event_espresso'),
228
+					'order'      => 5,
229
+					'persistent' => false,
230
+				),
231
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
232
+				'help_tabs'     => array(
233
+					'registration_form_add_question_help_tab' => array(
234
+						'title'    => esc_html__('Add Question', 'event_espresso'),
235
+						'filename' => 'registration_form_add_question',
236
+					),
237
+				),
238
+				'help_tour'     => array('Registration_Form_Add_Question_Help_Tour'),
239
+				'require_nonce' => false,
240
+			),
241
+
242
+			'add_question_group' => array(
243
+				'nav'           => array(
244
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
245
+					'order'      => 5,
246
+					'persistent' => false,
247
+				),
248
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
249
+				'help_tabs'     => array(
250
+					'registration_form_add_question_group_help_tab' => array(
251
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
252
+						'filename' => 'registration_form_add_question_group',
253
+					),
254
+				),
255
+				'help_tour'     => array('Registration_Form_Add_Question_Group_Help_Tour'),
256
+				'require_nonce' => false,
257
+			),
258
+
259
+			'edit_question_group' => array(
260
+				'nav'           => array(
261
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
262
+					'order'      => 5,
263
+					'persistent' => false,
264
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
265
+						array('question_group_id' => $this->_req_data['question_group_id']),
266
+						$this->_current_page_view_url
267
+					) : $this->_admin_base_url,
268
+				),
269
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
270
+				'help_tabs'     => array(
271
+					'registration_form_edit_question_group_help_tab' => array(
272
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
273
+						'filename' => 'registration_form_edit_question_group',
274
+					),
275
+				),
276
+				'help_tour'     => array('Registration_Form_Edit_Question_Group_Help_Tour'),
277
+				'require_nonce' => false,
278
+			),
279
+
280
+			'view_reg_form_settings' => array(
281
+				'nav'           => array(
282
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
283
+					'order' => 40,
284
+				),
285
+				'labels'        => array(
286
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
287
+				),
288
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
289
+				'help_tabs'     => array(
290
+					'registration_form_reg_form_settings_help_tab' => array(
291
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
292
+						'filename' => 'registration_form_reg_form_settings',
293
+					),
294
+				),
295
+				'help_tour'     => array('Registration_Form_Settings_Help_Tour'),
296
+				'require_nonce' => false,
297
+			),
298
+
299
+		);
300
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
301
+
302
+		// change the list table we're going to use so it's the NEW list table!
303
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
304
+
305
+
306
+		// additional labels
307
+		$new_labels = array(
308
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
309
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
310
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
311
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
312
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
313
+		);
314
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
315
+	}
316
+
317
+
318
+	/**
319
+	 * @return void
320
+	 */
321
+	protected function _ajax_hooks()
322
+	{
323
+		add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
324
+	}
325
+
326
+
327
+	/**
328
+	 * @return void
329
+	 */
330
+	public function load_scripts_styles_question_groups()
331
+	{
332
+		wp_enqueue_script('espresso_ajax_table_sorting');
333
+	}
334
+
335
+
336
+	/**
337
+	 * @return void
338
+	 */
339
+	public function load_scripts_styles_add_question_group()
340
+	{
341
+		$this->load_scripts_styles_forms();
342
+		$this->load_sortable_question_script();
343
+	}
344
+
345
+
346
+	/**
347
+	 * @return void
348
+	 */
349
+	public function load_scripts_styles_edit_question_group()
350
+	{
351
+		$this->load_scripts_styles_forms();
352
+		$this->load_sortable_question_script();
353
+	}
354
+
355
+
356
+	/**
357
+	 * registers and enqueues script for questions
358
+	 *
359
+	 * @return void
360
+	 */
361
+	public function load_sortable_question_script()
362
+	{
363
+		wp_register_script(
364
+			'ee-question-sortable',
365
+			REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
366
+			array('jquery-ui-sortable'),
367
+			EVENT_ESPRESSO_VERSION,
368
+			true
369
+		);
370
+		wp_enqueue_script('ee-question-sortable');
371
+	}
372
+
373
+
374
+	/**
375
+	 * @return void
376
+	 */
377
+	protected function _set_list_table_views_default()
378
+	{
379
+		$this->_views = array(
380
+			'all' => array(
381
+				'slug'        => 'all',
382
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
383
+				'count'       => 0,
384
+				'bulk_action' => array(
385
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
386
+				),
387
+			),
388
+		);
389
+
390
+		if (EE_Registry::instance()->CAP->current_user_can(
391
+			'ee_delete_questions',
392
+			'espresso_registration_form_trash_questions'
393
+		)
394
+		) {
395
+			$this->_views['trash'] = array(
396
+				'slug'        => 'trash',
397
+				'label'       => esc_html__('Trash', 'event_espresso'),
398
+				'count'       => 0,
399
+				'bulk_action' => array(
400
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
401
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
402
+				),
403
+			);
404
+		}
405
+	}
406
+
407
+
408
+	/**
409
+	 * @return void
410
+	 */
411
+	protected function _set_list_table_views_question_groups()
412
+	{
413
+		$this->_views = array(
414
+			'all' => array(
415
+				'slug'        => 'all',
416
+				'label'       => esc_html__('All', 'event_espresso'),
417
+				'count'       => 0,
418
+				'bulk_action' => array(
419
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
420
+				),
421
+			),
422
+		);
423
+
424
+		if (EE_Registry::instance()->CAP->current_user_can(
425
+			'ee_delete_question_groups',
426
+			'espresso_registration_form_trash_question_groups'
427
+		)
428
+		) {
429
+			$this->_views['trash'] = array(
430
+				'slug'        => 'trash',
431
+				'label'       => esc_html__('Trash', 'event_espresso'),
432
+				'count'       => 0,
433
+				'bulk_action' => array(
434
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
435
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
436
+				),
437
+			);
438
+		}
439
+	}
440
+
441
+
442
+	/**
443
+	 * @return void
444
+	 * @throws EE_Error
445
+	 * @throws InvalidArgumentException
446
+	 * @throws InvalidDataTypeException
447
+	 * @throws InvalidInterfaceException
448
+	 */
449
+	protected function _questions_overview_list_table()
450
+	{
451
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
452
+			'add_question',
453
+			'add_question',
454
+			array(),
455
+			'add-new-h2'
456
+		);
457
+		parent::_questions_overview_list_table();
458
+	}
459
+
460
+
461
+	/**
462
+	 * @return void
463
+	 * @throws DomainException
464
+	 * @throws EE_Error
465
+	 * @throws InvalidArgumentException
466
+	 * @throws InvalidDataTypeException
467
+	 * @throws InvalidInterfaceException
468
+	 */
469
+	protected function _question_groups_overview_list_table()
470
+	{
471
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
472
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
473
+			'add_question_group',
474
+			'add_question_group',
475
+			array(),
476
+			'add-new-h2'
477
+		);
478
+		$this->display_admin_list_table_page_with_sidebar();
479
+	}
480
+
481
+
482
+	/**
483
+	 * @return void
484
+	 * @throws EE_Error
485
+	 * @throws InvalidArgumentException
486
+	 * @throws InvalidDataTypeException
487
+	 * @throws InvalidInterfaceException
488
+	 */
489
+	protected function _delete_question()
490
+	{
491
+		$success = $this->_delete_items($this->_question_model);
492
+		$this->_redirect_after_action(
493
+			$success,
494
+			$this->_question_model->item_name($success),
495
+			'deleted',
496
+			array('action' => 'default', 'status' => 'all')
497
+		);
498
+	}
499
+
500
+
501
+	/**
502
+	 * @return void
503
+	 * @throws EE_Error
504
+	 * @throws InvalidArgumentException
505
+	 * @throws InvalidDataTypeException
506
+	 * @throws InvalidInterfaceException
507
+	 */
508
+	protected function _delete_questions()
509
+	{
510
+		$success = $this->_delete_items($this->_question_model);
511
+		$this->_redirect_after_action(
512
+			$success,
513
+			$this->_question_model->item_name($success),
514
+			'deleted permanently',
515
+			array('action' => 'default', 'status' => 'trash')
516
+		);
517
+	}
518
+
519
+
520
+	/**
521
+	 * Performs the deletion of a single or multiple questions or question groups.
522
+	 *
523
+	 * @param EEM_Soft_Delete_Base $model
524
+	 * @return int number of items deleted permanently
525
+	 * @throws EE_Error
526
+	 * @throws InvalidArgumentException
527
+	 * @throws InvalidDataTypeException
528
+	 * @throws InvalidInterfaceException
529
+	 */
530
+	private function _delete_items(EEM_Soft_Delete_Base $model)
531
+	{
532
+		$success = 0;
533
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
534
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
535
+			// if array has more than one element than success message should be plural
536
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
537
+			// cycle thru bulk action checkboxes
538
+			while (list($ID, $value) = each($this->_req_data['checkbox'])) {
539
+				if (! $this->_delete_item($ID, $model)) {
540
+					$success = 0;
541
+				}
542
+			}
543
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
544
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
545
+		} elseif (! empty($this->_req_data['QST_ID'])) {
546
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
547
+		} else {
548
+			EE_Error::add_error(
549
+				sprintf(
550
+					esc_html__(
551
+						"No Questions or Question Groups were selected for deleting. This error usually shows when you've attempted to delete via bulk action but there were no selections.",
552
+						"event_espresso"
553
+					)
554
+				),
555
+				__FILE__,
556
+				__FUNCTION__,
557
+				__LINE__
558
+			);
559
+		}
560
+		return $success;
561
+	}
562
+
563
+
564
+	/**
565
+	 * Deletes the specified question (and its associated question options) or question group
566
+	 *
567
+	 * @param int                  $id
568
+	 * @param EEM_Soft_Delete_Base $model
569
+	 * @return boolean
570
+	 * @throws EE_Error
571
+	 * @throws InvalidArgumentException
572
+	 * @throws InvalidDataTypeException
573
+	 * @throws InvalidInterfaceException
574
+	 */
575
+	protected function _delete_item($id, $model)
576
+	{
577
+		if ($model instanceof EEM_Question) {
578
+			EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
579
+		}
580
+		return $model->delete_permanently_by_ID(absint($id));
581
+	}
582
+
583
+
584
+	/******************************    QUESTION GROUPS    ******************************/
585
+
586
+
587
+	/**
588
+	 * @param string $type
589
+	 * @return void
590
+	 * @throws DomainException
591
+	 * @throws EE_Error
592
+	 * @throws InvalidArgumentException
593
+	 * @throws InvalidDataTypeException
594
+	 * @throws InvalidInterfaceException
595
+	 */
596
+	protected function _edit_question_group($type = 'add')
597
+	{
598
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
599
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
600
+			? absint($this->_req_data['QSG_ID'])
601
+			: false;
602
+
603
+		switch ($this->_req_action) {
604
+			case 'add_question_group':
605
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
606
+				break;
607
+			case 'edit_question_group':
608
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
609
+				break;
610
+			default:
611
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
612
+		}
613
+		// add ID to title if editing
614
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
615
+		if ($ID) {
616
+			/** @var EE_Question_Group $questionGroup */
617
+			$questionGroup = $this->_question_group_model->get_one_by_ID($ID);
618
+			$additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
619
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
620
+		} else {
621
+			/** @var EE_Question_Group $questionGroup */
622
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
623
+			$questionGroup->set_order_to_latest();
624
+			$this->_set_add_edit_form_tags('insert_question_group');
625
+		}
626
+		$this->_template_args['values'] = $this->_yes_no_values;
627
+		$this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
628
+		$this->_template_args['QSG_ID'] = $ID ? $ID : true;
629
+		$this->_template_args['question_group'] = $questionGroup;
630
+
631
+		$redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
632
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
633
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
634
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
635
+			$this->_template_args,
636
+			true
637
+		);
638
+
639
+		// the details template wrapper
640
+		$this->display_admin_page_with_sidebar();
641
+	}
642
+
643
+
644
+	/**
645
+	 * @return void
646
+	 * @throws EE_Error
647
+	 * @throws InvalidArgumentException
648
+	 * @throws InvalidDataTypeException
649
+	 * @throws InvalidInterfaceException
650
+	 */
651
+	protected function _delete_question_groups()
652
+	{
653
+		$success = $this->_delete_items($this->_question_group_model);
654
+		$this->_redirect_after_action(
655
+			$success,
656
+			$this->_question_group_model->item_name($success),
657
+			'deleted permanently',
658
+			array('action' => 'question_groups', 'status' => 'trash')
659
+		);
660
+	}
661
+
662
+
663
+	/**
664
+	 * @param bool $new_question_group
665
+	 * @throws EE_Error
666
+	 * @throws InvalidArgumentException
667
+	 * @throws InvalidDataTypeException
668
+	 * @throws InvalidInterfaceException
669
+	 */
670
+	protected function _insert_or_update_question_group($new_question_group = true)
671
+	{
672
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
673
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
674
+		if ($new_question_group) {
675
+			$QSG_ID = $this->_question_group_model->insert($set_column_values);
676
+			$success = $QSG_ID ? 1 : 0;
677
+		} else {
678
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
679
+			unset($set_column_values['QSG_ID']);
680
+			$success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
681
+		}
682
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
683
+			EEM_Attendee::system_question_phone
684
+		);
685
+		// update the existing related questions
686
+		// BUT FIRST...  delete the phone question from the Question_Group_Question
687
+		// if it is being added to this question group (therefore removed from the existing group)
688
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
689
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
690
+			EEM_Question_Group_Question::instance()->delete(
691
+				array(
692
+					array(
693
+						'QST_ID' => $phone_question_id,
694
+						'QSG_ID' => array('!=', $QSG_ID),
695
+					),
696
+				)
697
+			);
698
+		}
699
+		/** @type EE_Question_Group $question_group */
700
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
701
+		$questions = $question_group->questions();
702
+		// make sure system phone question is added to list of questions for this group
703
+		if (! isset($questions[ $phone_question_id ])) {
704
+			$questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
705
+		}
706
+
707
+		foreach ($questions as $question_ID => $question) {
708
+			// first we always check for order.
709
+			if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
710
+				// update question order
711
+				$question_group->update_question_order(
712
+					$question_ID,
713
+					$this->_req_data['question_orders'][ $question_ID ]
714
+				);
715
+			}
716
+
717
+			// then we always check if adding or removing.
718
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
719
+				$question_group->add_question($question_ID);
720
+			} else {
721
+				// not found, remove it (but only if not a system question for the personal group
722
+				// with the exception of lname system question - we allow removal of it)
723
+				if (in_array(
724
+					$question->system_ID(),
725
+					EEM_Question::instance()->required_system_questions_in_system_question_group(
726
+						$question_group->system_group()
727
+					)
728
+				)) {
729
+					continue;
730
+				} else {
731
+					$question_group->remove_question($question_ID);
732
+				}
733
+			}
734
+		}
735
+		// save new related questions
736
+		if (isset($this->_req_data['questions'])) {
737
+			foreach ($this->_req_data['questions'] as $QST_ID) {
738
+				$question_group->add_question($QST_ID);
739
+				if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
740
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
741
+				}
742
+			}
743
+		}
744
+
745
+		if ($success !== false) {
746
+			$msg = $new_question_group
747
+				? sprintf(
748
+					esc_html__('The %s has been created', 'event_espresso'),
749
+					$this->_question_group_model->item_name()
750
+				)
751
+				: sprintf(
752
+					esc_html__(
753
+						'The %s has been updated',
754
+						'event_espresso'
755
+					),
756
+					$this->_question_group_model->item_name()
757
+				);
758
+			EE_Error::add_success($msg);
759
+		}
760
+		$this->_redirect_after_action(
761
+			false,
762
+			'',
763
+			'',
764
+			array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
765
+			true
766
+		);
767
+	}
768
+
769
+
770
+	/**
771
+	 * duplicates a question and all its question options and redirects to the new question.
772
+	 *
773
+	 * @return void
774
+	 * @throws EE_Error
775
+	 * @throws InvalidArgumentException
776
+	 * @throws ReflectionException
777
+	 * @throws InvalidDataTypeException
778
+	 * @throws InvalidInterfaceException
779
+	 */
780
+	public function _duplicate_question()
781
+	{
782
+		$question_ID = (int) $this->_req_data['QST_ID'];
783
+		$question = EEM_Question::instance()->get_one_by_ID($question_ID);
784
+		if ($question instanceof EE_Question) {
785
+			$new_question = $question->duplicate();
786
+			if ($new_question instanceof EE_Question) {
787
+				$this->_redirect_after_action(
788
+					true,
789
+					esc_html__('Question', 'event_espresso'),
790
+					esc_html__('Duplicated', 'event_espresso'),
791
+					array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
792
+					true
793
+				);
794
+			} else {
795
+				global $wpdb;
796
+				EE_Error::add_error(
797
+					sprintf(
798
+						esc_html__(
799
+							'Could not duplicate question with ID %1$d because: %2$s',
800
+							'event_espresso'
801
+						),
802
+						$question_ID,
803
+						$wpdb->last_error
804
+					),
805
+					__FILE__,
806
+					__FUNCTION__,
807
+					__LINE__
808
+				);
809
+				$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
810
+			}
811
+		} else {
812
+			EE_Error::add_error(
813
+				sprintf(
814
+					esc_html__(
815
+						'Could not duplicate question with ID %d because it didn\'t exist!',
816
+						'event_espresso'
817
+					),
818
+					$question_ID
819
+				),
820
+				__FILE__,
821
+				__FUNCTION__,
822
+				__LINE__
823
+			);
824
+			$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
825
+		}
826
+	}
827
+
828
+
829
+	/**
830
+	 * @param bool $trash
831
+	 * @throws EE_Error
832
+	 */
833
+	protected function _trash_or_restore_question_groups($trash = true)
834
+	{
835
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
836
+	}
837
+
838
+
839
+	/**
840
+	 *_trash_question
841
+	 *
842
+	 * @return void
843
+	 * @throws EE_Error
844
+	 */
845
+	protected function _trash_question()
846
+	{
847
+		$success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
848
+		$query_args = array('action' => 'default', 'status' => 'all');
849
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
850
+	}
851
+
852
+
853
+	/**
854
+	 * @param bool $trash
855
+	 * @throws EE_Error
856
+	 */
857
+	protected function _trash_or_restore_questions($trash = true)
858
+	{
859
+		$this->_trash_or_restore_items($this->_question_model, $trash);
860
+	}
861
+
862
+
863
+	/**
864
+	 * Internally used to delete or restore items, using the request data. Meant to be
865
+	 * flexible between question or question groups
866
+	 *
867
+	 * @param EEM_Soft_Delete_Base $model
868
+	 * @param boolean              $trash whether to trash or restore
869
+	 * @throws EE_Error
870
+	 */
871
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
872
+	{
873
+
874
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
875
+
876
+		$success = 1;
877
+		// Checkboxes
878
+		// echo "trash $trash";
879
+		// var_dump($this->_req_data['checkbox']);die;
880
+		if (isset($this->_req_data['checkbox'])) {
881
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
882
+				// if array has more than one element than success message should be plural
883
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
884
+				// cycle thru bulk action checkboxes
885
+				while (list($ID, $value) = each($this->_req_data['checkbox'])) {
886
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
887
+						$success = 0;
888
+					}
889
+				}
890
+			} else {
891
+				// grab single id and delete
892
+				$ID = absint($this->_req_data['checkbox']);
893
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
894
+					$success = 0;
895
+				}
896
+			}
897
+		} else {
898
+			// delete via trash link
899
+			// grab single id and delete
900
+			$ID = absint($this->_req_data[ $model->primary_key_name() ]);
901
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
902
+				$success = 0;
903
+			}
904
+		}
905
+
906
+
907
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
908
+		// echo "action :$action";
909
+		// $action = 'questions' ? 'default' : $action;
910
+		if ($trash) {
911
+			$action_desc = 'trashed';
912
+			$status = 'trash';
913
+		} else {
914
+			$action_desc = 'restored';
915
+			$status = 'all';
916
+		}
917
+		$this->_redirect_after_action(
918
+			$success,
919
+			$model->item_name($success),
920
+			$action_desc,
921
+			array('action' => $action, 'status' => $status)
922
+		);
923
+	}
924
+
925
+
926
+	/**
927
+	 * @param            $per_page
928
+	 * @param int        $current_page
929
+	 * @param bool|false $count
930
+	 * @return EE_Soft_Delete_Base_Class[]|int
931
+	 * @throws EE_Error
932
+	 * @throws InvalidArgumentException
933
+	 * @throws InvalidDataTypeException
934
+	 * @throws InvalidInterfaceException
935
+	 */
936
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
937
+	{
938
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
939
+
940
+		if ($count) {
941
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
942
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
943
+			$results = $this->_question_model->count_deleted($where);
944
+		} else {
945
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
946
+			$results = $this->_question_model->get_all_deleted($query_params);
947
+		}
948
+		return $results;
949
+	}
950
+
951
+
952
+	/**
953
+	 * @param            $per_page
954
+	 * @param int        $current_page
955
+	 * @param bool|false $count
956
+	 * @return EE_Soft_Delete_Base_Class[]|int
957
+	 * @throws EE_Error
958
+	 * @throws InvalidArgumentException
959
+	 * @throws InvalidDataTypeException
960
+	 * @throws InvalidInterfaceException
961
+	 */
962
+	public function get_question_groups($per_page, $current_page = 1, $count = false)
963
+	{
964
+		$questionGroupModel = EEM_Question_Group::instance();
965
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
966
+		if ($count) {
967
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
968
+			$results = $questionGroupModel->count($where);
969
+		} else {
970
+			$results = $questionGroupModel->get_all($query_params);
971
+		}
972
+		return $results;
973
+	}
974
+
975
+
976
+	/**
977
+	 * @param      $per_page
978
+	 * @param int  $current_page
979
+	 * @param bool $count
980
+	 * @return EE_Soft_Delete_Base_Class[]|int
981
+	 * @throws EE_Error
982
+	 * @throws InvalidArgumentException
983
+	 * @throws InvalidDataTypeException
984
+	 * @throws InvalidInterfaceException
985
+	 */
986
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
987
+	{
988
+		$questionGroupModel = EEM_Question_Group::instance();
989
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
990
+		if ($count) {
991
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
992
+			$query_params['limit'] = null;
993
+			$results = $questionGroupModel->count_deleted($where);
994
+		} else {
995
+			$results = $questionGroupModel->get_all_deleted($query_params);
996
+		}
997
+		return $results;
998
+	}
999
+
1000
+
1001
+	/**
1002
+	 * method for performing updates to question order
1003
+	 *
1004
+	 * @return void results array
1005
+	 * @throws EE_Error
1006
+	 * @throws InvalidArgumentException
1007
+	 * @throws InvalidDataTypeException
1008
+	 * @throws InvalidInterfaceException
1009
+	 */
1010
+	public function update_question_group_order()
1011
+	{
1012
+
1013
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1014
+
1015
+		// grab our row IDs
1016
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1017
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
1018
+			: array();
1019
+
1020
+		$perpage = ! empty($this->_req_data['perpage'])
1021
+			? (int) $this->_req_data['perpage']
1022
+			: null;
1023
+		$curpage = ! empty($this->_req_data['curpage'])
1024
+			? (int) $this->_req_data['curpage']
1025
+			: null;
1026
+
1027
+		if (! empty($row_ids)) {
1028
+			// figure out where we start the row_id count at for the current page.
1029
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1030
+
1031
+			$row_count = count($row_ids);
1032
+			for ($i = 0; $i < $row_count; $i++) {
1033
+				// Update the questions when re-ordering
1034
+				$updated = EEM_Question_Group::instance()->update(
1035
+					array('QSG_order' => $qsgcount),
1036
+					array(array('QSG_ID' => $row_ids[ $i ]))
1037
+				);
1038
+				if ($updated === false) {
1039
+					$success = false;
1040
+				}
1041
+				$qsgcount++;
1042
+			}
1043
+		} else {
1044
+			$success = false;
1045
+		}
1046
+
1047
+		$errors = ! $success
1048
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1049
+			: false;
1050
+
1051
+		echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1052
+		die();
1053
+	}
1054
+
1055
+
1056
+
1057
+	/***************************************       REGISTRATION SETTINGS       ***************************************/
1058
+
1059
+
1060
+	/**
1061
+	 * @throws DomainException
1062
+	 * @throws EE_Error
1063
+	 * @throws InvalidArgumentException
1064
+	 * @throws InvalidDataTypeException
1065
+	 * @throws InvalidInterfaceException
1066
+	 */
1067
+	protected function _reg_form_settings()
1068
+	{
1069
+		$this->_template_args['values'] = $this->_yes_no_values;
1070
+		add_action(
1071
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1072
+			array($this, 'email_validation_settings_form'),
1073
+			2
1074
+		);
1075
+		$this->_template_args = (array) apply_filters(
1076
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1077
+			$this->_template_args
1078
+		);
1079
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
1080
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1081
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1082
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1083
+			$this->_template_args,
1084
+			true
1085
+		);
1086
+		$this->display_admin_page_with_sidebar();
1087
+	}
1088
+
1089
+
1090
+	/**
1091
+	 * @return void
1092
+	 * @throws EE_Error
1093
+	 * @throws InvalidArgumentException
1094
+	 * @throws ReflectionException
1095
+	 * @throws InvalidDataTypeException
1096
+	 * @throws InvalidInterfaceException
1097
+	 */
1098
+	protected function _update_reg_form_settings()
1099
+	{
1100
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1101
+			EE_Registry::instance()->CFG->registration
1102
+		);
1103
+		EE_Registry::instance()->CFG->registration = apply_filters(
1104
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1105
+			EE_Registry::instance()->CFG->registration
1106
+		);
1107
+		$success = $this->_update_espresso_configuration(
1108
+			esc_html__('Registration Form Options', 'event_espresso'),
1109
+			EE_Registry::instance()->CFG,
1110
+			__FILE__,
1111
+			__FUNCTION__,
1112
+			__LINE__
1113
+		);
1114
+		$this->_redirect_after_action(
1115
+			$success,
1116
+			esc_html__('Registration Form Options', 'event_espresso'),
1117
+			'updated',
1118
+			array('action' => 'view_reg_form_settings')
1119
+		);
1120
+	}
1121
+
1122
+
1123
+	/**
1124
+	 * @return void
1125
+	 * @throws EE_Error
1126
+	 * @throws InvalidArgumentException
1127
+	 * @throws InvalidDataTypeException
1128
+	 * @throws InvalidInterfaceException
1129
+	 */
1130
+	public function email_validation_settings_form()
1131
+	{
1132
+		echo $this->_email_validation_settings_form()->get_html();
1133
+	}
1134
+
1135
+
1136
+	/**
1137
+	 * _email_validation_settings_form
1138
+	 *
1139
+	 * @access protected
1140
+	 * @return EE_Form_Section_Proper
1141
+	 * @throws \EE_Error
1142
+	 */
1143
+	protected function _email_validation_settings_form()
1144
+	{
1145
+		return new EE_Form_Section_Proper(
1146
+			array(
1147
+				'name'            => 'email_validation_settings',
1148
+				'html_id'         => 'email_validation_settings',
1149
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1150
+				'subsections'     => apply_filters(
1151
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1152
+					array(
1153
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
1154
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1155
+						),
1156
+						'email_validation_level' => new EE_Select_Input(
1157
+							array(
1158
+								'basic'      => esc_html__('Basic', 'event_espresso'),
1159
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1160
+								'i18n'       => esc_html__('International', 'event_espresso'),
1161
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1162
+							),
1163
+							array(
1164
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1165
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
1166
+								'html_help_text'  => esc_html__(
1167
+									'These levels range from basic validation ( ie: [email protected] ) to more advanced checks against international email addresses (ie: üñîçøðé@example.com ) with additional MX and A record checks to confirm the domain actually exists. More information on on each level can be found within the help section.',
1168
+									'event_espresso'
1169
+								),
1170
+								'default'         => isset(
1171
+									EE_Registry::instance()->CFG->registration->email_validation_level
1172
+								)
1173
+									? EE_Registry::instance()->CFG->registration->email_validation_level
1174
+									: 'wp_default',
1175
+								'required'        => false,
1176
+							)
1177
+						),
1178
+					)
1179
+				),
1180
+			)
1181
+		);
1182
+	}
1183
+
1184
+
1185
+	/**
1186
+	 * @param EE_Registration_Config $EE_Registration_Config
1187
+	 * @return EE_Registration_Config
1188
+	 * @throws EE_Error
1189
+	 * @throws InvalidArgumentException
1190
+	 * @throws ReflectionException
1191
+	 * @throws InvalidDataTypeException
1192
+	 * @throws InvalidInterfaceException
1193
+	 */
1194
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1195
+	{
1196
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1197
+		try {
1198
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1199
+			// if not displaying a form, then check for form submission
1200
+			if ($email_validation_settings_form->was_submitted()) {
1201
+				// capture form data
1202
+				$email_validation_settings_form->receive_form_submission();
1203
+				// validate form data
1204
+				if ($email_validation_settings_form->is_valid()) {
1205
+					// grab validated data from form
1206
+					$valid_data = $email_validation_settings_form->valid_data();
1207
+					if (isset($valid_data['email_validation_level'])) {
1208
+						$email_validation_level = $valid_data['email_validation_level'];
1209
+						// now if they want to use international email addresses
1210
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1211
+							// in case we need to reset their email validation level,
1212
+							// make sure that the previous value wasn't already set to one of the i18n options.
1213
+							if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1214
+								// if so, then reset it back to "basic" since that is the only other option that,
1215
+								// despite offering poor validation, supports i18n email addresses
1216
+								$prev_email_validation_level = 'basic';
1217
+							}
1218
+							// confirm our i18n email validation will work on the server
1219
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1220
+								// or reset email validation level to previous value
1221
+								$email_validation_level = $prev_email_validation_level;
1222
+							}
1223
+						}
1224
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1225
+					} else {
1226
+						EE_Error::add_error(
1227
+							esc_html__(
1228
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1229
+								'event_espresso'
1230
+							),
1231
+							__FILE__,
1232
+							__FUNCTION__,
1233
+							__LINE__
1234
+						);
1235
+					}
1236
+				} else {
1237
+					if ($email_validation_settings_form->submission_error_message() !== '') {
1238
+						EE_Error::add_error(
1239
+							$email_validation_settings_form->submission_error_message(),
1240
+							__FILE__,
1241
+							__FUNCTION__,
1242
+							__LINE__
1243
+						);
1244
+					}
1245
+				}
1246
+			}
1247
+		} catch (EE_Error $e) {
1248
+			$e->get_error();
1249
+		}
1250
+		return $EE_Registration_Config;
1251
+	}
1252
+
1253
+
1254
+	/**
1255
+	 * confirms that the server's PHP version has the PCRE module enabled,
1256
+	 * and that the PCRE version works with our i18n email validation
1257
+	 *
1258
+	 * @param EE_Registration_Config $EE_Registration_Config
1259
+	 * @param string                 $email_validation_level
1260
+	 * @return bool
1261
+	 */
1262
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1263
+	{
1264
+		// first check that PCRE is enabled
1265
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1266
+			EE_Error::add_error(
1267
+				sprintf(
1268
+					esc_html__(
1269
+						'We\'re sorry, but it appears that your server\'s version of PHP was not compiled with PCRE unicode support.%1$sPlease contact your hosting company and ask them whether the PCRE compiled with your version of PHP on your server can be been built with the "--enable-unicode-properties" and "--enable-utf8" configuration switches to enable more complex regex expressions.%1$sIf they are unable, or unwilling to do so, then your server will not support international email addresses using UTF-8 unicode characters. This means you will either have to lower your email validation level to "Basic" or "WordPress Default", or switch to a hosting company that has/can enable PCRE unicode support on the server.',
1270
+						'event_espresso'
1271
+					),
1272
+					'<br />'
1273
+				),
1274
+				__FILE__,
1275
+				__FUNCTION__,
1276
+				__LINE__
1277
+			);
1278
+			return false;
1279
+		} else {
1280
+			// PCRE support is enabled, but let's still
1281
+			// perform a test to see if the server will support it.
1282
+			// but first, save the updated validation level to the config,
1283
+			// so that the validation strategy picks it up.
1284
+			// this will get bumped back down if it doesn't work
1285
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1286
+			try {
1287
+				$email_validator = new EE_Email_Validation_Strategy();
1288
+				$i18n_email_address = apply_filters(
1289
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1290
+					'jägerjü[email protected]'
1291
+				);
1292
+				$email_validator->validate($i18n_email_address);
1293
+			} catch (Exception $e) {
1294
+				EE_Error::add_error(
1295
+					sprintf(
1296
+						esc_html__(
1297
+							'We\'re sorry, but it appears that your server\'s configuration will not support the "International" or "International + DNS Check" email validation levels.%1$sTo correct this issue, please consult with your hosting company regarding your server\'s PCRE settings.%1$sIt is recommended that your PHP version be configured to use PCRE 8.10 or newer.%1$sMore information regarding PCRE versions and installation can be found here: %2$s',
1298
+							'event_espresso'
1299
+						),
1300
+						'<br />',
1301
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank">http://php.net/manual/en/pcre.installation.php</a>'
1302
+					),
1303
+					__FILE__,
1304
+					__FUNCTION__,
1305
+					__LINE__
1306
+				);
1307
+				return false;
1308
+			}
1309
+		}
1310
+		return true;
1311
+	}
1312 1312
 }
Please login to merge, or discard this patch.
core/db_models/EEM_CPT_Base.model.php 1 patch
Indentation   +558 added lines, -558 removed lines patch added patch discarded remove patch
@@ -16,562 +16,562 @@
 block discarded – undo
16 16
 abstract class EEM_CPT_Base extends EEM_Soft_Delete_Base
17 17
 {
18 18
 
19
-    const EVENT_CATEGORY_TAXONOMY = 'espresso_event_categories';
20
-
21
-    /**
22
-     * @var string post_status_publish - the wp post status for published cpts
23
-     */
24
-    const post_status_publish = 'publish';
25
-
26
-    /**
27
-     * @var string post_status_future - the wp post status for scheduled cpts
28
-     */
29
-    const post_status_future = 'future';
30
-
31
-    /**
32
-     * @var string post_status_draft - the wp post status for draft cpts
33
-     */
34
-    const post_status_draft = 'draft';
35
-
36
-    /**
37
-     * @var string post_status_pending - the wp post status for pending cpts
38
-     */
39
-    const post_status_pending = 'pending';
40
-
41
-    /**
42
-     * @var string post_status_private - the wp post status for private cpts
43
-     */
44
-    const post_status_private = 'private';
45
-
46
-    /**
47
-     * @var string post_status_trashed - the wp post status for trashed cpts
48
-     */
49
-    const post_status_trashed = 'trash';
50
-
51
-    /**
52
-     * This is an array of custom statuses for the given CPT model (modified by children)
53
-     * format:
54
-     * array(
55
-     *        'status_name' => array(
56
-     *            'label' => __('Status Name', 'event_espresso'),
57
-     *            'public' => TRUE //whether a public status or not.
58
-     *        )
59
-     * )
60
-     *
61
-     * @var array
62
-     */
63
-    protected $_custom_stati = array();
64
-
65
-
66
-    /**
67
-     * Adds a relationship to Term_Taxonomy for each CPT_Base
68
-     *
69
-     * @param string $timezone
70
-     * @throws \EE_Error
71
-     */
72
-    protected function __construct($timezone = null)
73
-    {
74
-        // adds a relationship to Term_Taxonomy for all these models. For this to work
75
-        // Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly
76
-        // eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry
77
-        // with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value
78
-        // must also be new EE_HABTM_Relation('Term_Relationship');
79
-        $this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship');
80
-        $primary_table_name = null;
81
-        // add  the common _status field to all CPT primary tables.
82
-        foreach ($this->_tables as $alias => $table_obj) {
83
-            if ($table_obj instanceof EE_Primary_Table) {
84
-                $primary_table_name = $alias;
85
-            }
86
-        }
87
-        // set default wp post statuses if child has not already set.
88
-        if (! isset($this->_fields[ $primary_table_name ]['status'])) {
89
-            $this->_fields[ $primary_table_name ]['status'] = new EE_WP_Post_Status_Field(
90
-                'post_status',
91
-                __("Event Status", "event_espresso"),
92
-                false,
93
-                'draft'
94
-            );
95
-        }
96
-        if (! isset($this->_fields[ $primary_table_name ]['to_ping'])) {
97
-            $this->_fields[ $primary_table_name ]['to_ping'] = new EE_DB_Only_Text_Field(
98
-                'to_ping',
99
-                __('To Ping', 'event_espresso'),
100
-                false,
101
-                ''
102
-            );
103
-        }
104
-        if (! isset($this->_fields[ $primary_table_name ]['pinged'])) {
105
-            $this->_fields[ $primary_table_name ]['pinged'] = new EE_DB_Only_Text_Field(
106
-                'pinged',
107
-                __('Pinged', 'event_espresso'),
108
-                false,
109
-                ''
110
-            );
111
-        }
112
-        if (! isset($this->_fields[ $primary_table_name ]['comment_status'])) {
113
-            $this->_fields[ $primary_table_name ]['comment_status'] = new EE_Plain_Text_Field(
114
-                'comment_status',
115
-                __('Comment Status', 'event_espresso'),
116
-                false,
117
-                'open'
118
-            );
119
-        }
120
-        if (! isset($this->_fields[ $primary_table_name ]['ping_status'])) {
121
-            $this->_fields[ $primary_table_name ]['ping_status'] = new EE_Plain_Text_Field(
122
-                'ping_status',
123
-                __('Ping Status', 'event_espresso'),
124
-                false,
125
-                'open'
126
-            );
127
-        }
128
-        if (! isset($this->_fields[ $primary_table_name ]['post_content_filtered'])) {
129
-            $this->_fields[ $primary_table_name ]['post_content_filtered'] = new EE_DB_Only_Text_Field(
130
-                'post_content_filtered',
131
-                __('Post Content Filtered', 'event_espresso'),
132
-                false,
133
-                ''
134
-            );
135
-        }
136
-        if (! isset($this->_model_relations['Post_Meta'])) {
137
-            // don't block deletes though because we want to maintain the current behaviour
138
-            $this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false);
139
-        }
140
-        if (! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
141
-            // nothing was set during child constructor, so set default
142
-            $this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type());
143
-        }
144
-        if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
145
-            // nothing was set during child constructor, so set default
146
-            // it's ok for child classes to specify this, but generally this is more DRY
147
-            $this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type());
148
-        }
149
-        parent::__construct($timezone);
150
-    }
151
-
152
-
153
-    /**
154
-     * @return array
155
-     */
156
-    public function public_event_stati()
157
-    {
158
-        // @see wp-includes/post.php
159
-        return get_post_stati(array('public' => true));
160
-    }
161
-
162
-
163
-    /**
164
-     * Searches for field on this model of type 'deleted_flag'. if it is found,
165
-     * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name
166
-     *
167
-     * @return string
168
-     * @throws EE_Error
169
-     */
170
-    public function deleted_field_name()
171
-    {
172
-        throw new EE_Error(
173
-            sprintf(
174
-                __(
175
-                    "EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name",
176
-                    "event_espresso"
177
-                )
178
-            )
179
-        );
180
-    }
181
-
182
-
183
-    /**
184
-     * Gets the field's name that sets the post status
185
-     *
186
-     * @return string
187
-     * @throws EE_Error
188
-     */
189
-    public function post_status_field_name()
190
-    {
191
-        $field = $this->get_a_field_of_type('EE_WP_Post_Status_Field');
192
-        if ($field) {
193
-            return $field->get_name();
194
-        } else {
195
-            throw new EE_Error(
196
-                sprintf(
197
-                    __(
198
-                        'We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
199
-                        'event_espresso'
200
-                    ),
201
-                    get_class($this),
202
-                    get_class($this)
203
-                )
204
-            );
205
-        }
206
-    }
207
-
208
-
209
-    /**
210
-     * Alters the query params so that only trashed/soft-deleted items are considered
211
-     *
212
-     * @param array $query_params like EEM_Base::get_all's $query_params
213
-     * @return array like EEM_Base::get_all's $query_params
214
-     */
215
-    protected function _alter_query_params_so_only_trashed_items_included($query_params)
216
-    {
217
-        $post_status_field_name = $this->post_status_field_name();
218
-        $query_params[0][ $post_status_field_name ] = self::post_status_trashed;
219
-        return $query_params;
220
-    }
221
-
222
-
223
-    /**
224
-     * Alters the query params so each item's deleted status is ignored.
225
-     *
226
-     * @param array $query_params
227
-     * @return array
228
-     */
229
-    protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
230
-    {
231
-        $query_params['default_where_conditions'] = 'minimum';
232
-        return $query_params;
233
-    }
234
-
235
-
236
-    /**
237
-     * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
238
-     *
239
-     * @param boolean $delete       true to indicate deletion, false to indicate restoration
240
-     * @param array   $query_params like EEM_Base::get_all
241
-     * @return boolean success
242
-     */
243
-    public function delete_or_restore($delete = true, $query_params = array())
244
-    {
245
-        $post_status_field_name = $this->post_status_field_name();
246
-        $query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
247
-        $new_status = $delete ? self::post_status_trashed : 'draft';
248
-        if ($this->update(array($post_status_field_name => $new_status), $query_params)) {
249
-            return true;
250
-        } else {
251
-            return false;
252
-        }
253
-    }
254
-
255
-
256
-    /**
257
-     * meta_table
258
-     * returns first EE_Secondary_Table table name
259
-     *
260
-     * @access public
261
-     * @return string
262
-     */
263
-    public function meta_table()
264
-    {
265
-        $meta_table = $this->_get_other_tables();
266
-        $meta_table = reset($meta_table);
267
-        return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null;
268
-    }
269
-
270
-
271
-    /**
272
-     * This simply returns an array of the meta table fields (useful for when we just need to update those fields)
273
-     *
274
-     * @param  bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields.  Defaults to false (no
275
-     *                   db only fields)
276
-     * @return array
277
-     */
278
-    public function get_meta_table_fields($all = false)
279
-    {
280
-        $all_fields = $fields_to_return = array();
281
-        foreach ($this->_tables as $alias => $table_obj) {
282
-            if ($table_obj instanceof EE_Secondary_Table) {
283
-                $all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields);
284
-            }
285
-        }
286
-        if (! $all) {
287
-            foreach ($all_fields as $name => $obj) {
288
-                if ($obj instanceof EE_DB_Only_Field_Base) {
289
-                    continue;
290
-                }
291
-                $fields_to_return[] = $name;
292
-            }
293
-        } else {
294
-            $fields_to_return = array_keys($all_fields);
295
-        }
296
-        return $fields_to_return;
297
-    }
298
-
299
-
300
-    /**
301
-     * Adds an event category with the specified name and description to the specified
302
-     * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary,
303
-     * and adds an entry in the term_relationship if necessary.
304
-     *
305
-     * @param EE_CPT_Base $cpt_model_object
306
-     * @param string      $category_name (used to derive the term slug too)
307
-     * @param string      $category_description
308
-     * @param int         $parent_term_taxonomy_id
309
-     * @return EE_Term_Taxonomy
310
-     */
311
-    public function add_event_category(
312
-        EE_CPT_Base $cpt_model_object,
313
-        $category_name,
314
-        $category_description = '',
315
-        $parent_term_taxonomy_id = null
316
-    ) {
317
-        // create term
318
-        require_once(EE_MODELS . 'EEM_Term.model.php');
319
-        // first, check for a term by the same name or slug
320
-        $category_slug = sanitize_title($category_name);
321
-        $term = EEM_Term::instance()->get_one(
322
-            array(
323
-                array(
324
-                    'OR' => array(
325
-                        'name' => $category_name,
326
-                        'slug' => $category_slug,
327
-                    ),
328
-                    'Term_Taxonomy.taxonomy' => self::EVENT_CATEGORY_TAXONOMY
329
-                ),
330
-            )
331
-        );
332
-        if (! $term) {
333
-            $term = EE_Term::new_instance(
334
-                array(
335
-                    'name' => $category_name,
336
-                    'slug' => $category_slug,
337
-                )
338
-            );
339
-            $term->save();
340
-        }
341
-        // make sure there's a term-taxonomy entry too
342
-        require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
343
-        $term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(
344
-            array(
345
-                array(
346
-                    'term_id'  => $term->ID(),
347
-                    'taxonomy' => self::EVENT_CATEGORY_TAXONOMY,
348
-                ),
349
-            )
350
-        );
351
-        /** @var $term_taxonomy EE_Term_Taxonomy */
352
-        if (! $term_taxonomy) {
353
-            $term_taxonomy = EE_Term_Taxonomy::new_instance(
354
-                array(
355
-                    'term_id'     => $term->ID(),
356
-                    'taxonomy'    => self::EVENT_CATEGORY_TAXONOMY,
357
-                    'description' => $category_description,
358
-                    'term_count'       => 1,
359
-                    'parent'      => $parent_term_taxonomy_id,
360
-                )
361
-            );
362
-            $term_taxonomy->save();
363
-        } else {
364
-            $term_taxonomy->set_count($term_taxonomy->count() + 1);
365
-            $term_taxonomy->save();
366
-        }
367
-        return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy');
368
-    }
369
-
370
-
371
-    /**
372
-     * Removed the category specified by name as having a relation to this event.
373
-     * Does not remove the term or term_taxonomy.
374
-     *
375
-     * @param EE_CPT_Base $cpt_model_object_event
376
-     * @param string      $category_name name of the event category (term)
377
-     * @return bool
378
-     */
379
-    public function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name)
380
-    {
381
-        // find the term_taxonomy by that name
382
-        $term_taxonomy = $this->get_first_related(
383
-            $cpt_model_object_event,
384
-            'Term_Taxonomy',
385
-            array(array('Term.name' => $category_name, 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY))
386
-        );
387
-        /** @var $term_taxonomy EE_Term_Taxonomy */
388
-        if ($term_taxonomy) {
389
-            $term_taxonomy->set_count($term_taxonomy->count() - 1);
390
-            $term_taxonomy->save();
391
-        }
392
-        return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy');
393
-    }
394
-
395
-
396
-    /**
397
-     * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the
398
-     * given CPT ID.  It accepts the same params as what get_the_post_thumbnail() accepts.
399
-     *
400
-     * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
401
-     * @access public
402
-     * @param int          $id   the ID for the cpt we want the feature image for
403
-     * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array
404
-     *                           representing width and height in pixels (i.e. array(32,32) ).
405
-     * @param string|array $attr Optional. Query string or array of attributes.
406
-     * @return string HTML image element
407
-     */
408
-    public function get_feature_image($id, $size = 'thumbnail', $attr = '')
409
-    {
410
-        return get_the_post_thumbnail($id, $size, $attr);
411
-    }
412
-
413
-
414
-    /**
415
-     * Just a handy way to get the list of post statuses currently registered with WP.
416
-     *
417
-     * @global array $wp_post_statuses set in wp core for storing all the post stati
418
-     * @return array
419
-     */
420
-    public function get_post_statuses()
421
-    {
422
-        global $wp_post_statuses;
423
-        $statuses = array();
424
-        foreach ($wp_post_statuses as $post_status => $args_object) {
425
-            $statuses[ $post_status ] = $args_object->label;
426
-        }
427
-        return $statuses;
428
-    }
429
-
430
-
431
-    /**
432
-     * public method that can be used to retrieve the protected status array on the instantiated cpt model
433
-     *
434
-     * @return array array of statuses.
435
-     */
436
-    public function get_status_array()
437
-    {
438
-        $statuses = $this->get_post_statuses();
439
-        // first the global filter
440
-        $statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
441
-        // now the class specific filter
442
-        $statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
443
-        return $statuses;
444
-    }
445
-
446
-
447
-    /**
448
-     * this returns the post statuses that are NOT the default wordpress status
449
-     *
450
-     * @return array
451
-     */
452
-    public function get_custom_post_statuses()
453
-    {
454
-        $new_stati = array();
455
-        foreach ($this->_custom_stati as $status => $props) {
456
-            $new_stati[ $status ] = $props['label'];
457
-        }
458
-        return $new_stati;
459
-    }
460
-
461
-
462
-    /**
463
-     * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which
464
-     * are a row from the posts table. If we're missing any fields required for the model,
465
-     * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries,
466
-     * make sure you are attaching all the model's fields onto the post)
467
-     *
468
-     * @param WP_Post|array $post
469
-     * @return EE_Base_Class|EE_Soft_Delete_Base_Class
470
-     */
471
-    public function instantiate_class_from_post_object_orig($post)
472
-    {
473
-        $post = (array) $post;
474
-        $has_all_necessary_fields_for_table = true;
475
-        // check if the post has fields on the meta table already
476
-        foreach ($this->_get_other_tables() as $table_obj) {
477
-            $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
478
-            foreach ($fields_for_that_table as $field_obj) {
479
-                if (! isset($post[ $field_obj->get_table_column() ])
480
-                    && ! isset($post[ $field_obj->get_qualified_column() ])
481
-                ) {
482
-                    $has_all_necessary_fields_for_table = false;
483
-                }
484
-            }
485
-        }
486
-        // if we don't have all the fields we need, then just fetch the proper model from the DB
487
-        if (! $has_all_necessary_fields_for_table) {
488
-            return $this->get_one_by_ID($post['ID']);
489
-        } else {
490
-            return $this->instantiate_class_from_array_or_object($post);
491
-        }
492
-    }
493
-
494
-
495
-    /**
496
-     * @param null $post
497
-     * @return EE_Base_Class|EE_Soft_Delete_Base_Class
498
-     */
499
-    public function instantiate_class_from_post_object($post = null)
500
-    {
501
-        if (empty($post)) {
502
-            global $post;
503
-        }
504
-        $post = (array) $post;
505
-        $tables_needing_to_be_queried = array();
506
-        // check if the post has fields on the meta table already
507
-        foreach ($this->get_tables() as $table_obj) {
508
-            $fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
509
-            foreach ($fields_for_that_table as $field_obj) {
510
-                if (! isset($post[ $field_obj->get_table_column() ])
511
-                    && ! isset($post[ $field_obj->get_qualified_column() ])
512
-                ) {
513
-                    $tables_needing_to_be_queried[ $table_obj->get_table_alias() ] = $table_obj;
514
-                }
515
-            }
516
-        }
517
-        // if we don't have all the fields we need, then just fetch the proper model from the DB
518
-        if ($tables_needing_to_be_queried) {
519
-            if (count($tables_needing_to_be_queried) == 1
520
-                && reset($tables_needing_to_be_queried)
521
-                   instanceof
522
-                   EE_Secondary_Table
523
-            ) {
524
-                // so we're only missing data from a secondary table. Well that's not too hard to query for
525
-                $table_to_query = reset($tables_needing_to_be_queried);
526
-                $missing_data = $this->_do_wpdb_query(
527
-                    'get_row',
528
-                    array(
529
-                        'SELECT * FROM '
530
-                        . $table_to_query->get_table_name()
531
-                        . ' WHERE '
532
-                        . $table_to_query->get_fk_on_table()
533
-                        . ' = '
534
-                        . $post['ID'],
535
-                        ARRAY_A,
536
-                    )
537
-                );
538
-                if (! empty($missing_data)) {
539
-                    $post = array_merge($post, $missing_data);
540
-                }
541
-            } else {
542
-                return $this->get_one_by_ID($post['ID']);
543
-            }
544
-        }
545
-        return $this->instantiate_class_from_array_or_object($post);
546
-    }
547
-
548
-
549
-    /**
550
-     * Gets the post type associated with this
551
-     *
552
-     * @throws EE_Error
553
-     * @return string
554
-     */
555
-    public function post_type()
556
-    {
557
-        $post_type_field = null;
558
-        foreach ($this->field_settings(true) as $field_obj) {
559
-            if ($field_obj instanceof EE_WP_Post_Type_Field) {
560
-                $post_type_field = $field_obj;
561
-                break;
562
-            }
563
-        }
564
-        if ($post_type_field == null) {
565
-            throw new EE_Error(
566
-                sprintf(
567
-                    __(
568
-                        "CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt",
569
-                        "event_espresso"
570
-                    ),
571
-                    get_class($this)
572
-                )
573
-            );
574
-        }
575
-        return $post_type_field->get_default_value();
576
-    }
19
+	const EVENT_CATEGORY_TAXONOMY = 'espresso_event_categories';
20
+
21
+	/**
22
+	 * @var string post_status_publish - the wp post status for published cpts
23
+	 */
24
+	const post_status_publish = 'publish';
25
+
26
+	/**
27
+	 * @var string post_status_future - the wp post status for scheduled cpts
28
+	 */
29
+	const post_status_future = 'future';
30
+
31
+	/**
32
+	 * @var string post_status_draft - the wp post status for draft cpts
33
+	 */
34
+	const post_status_draft = 'draft';
35
+
36
+	/**
37
+	 * @var string post_status_pending - the wp post status for pending cpts
38
+	 */
39
+	const post_status_pending = 'pending';
40
+
41
+	/**
42
+	 * @var string post_status_private - the wp post status for private cpts
43
+	 */
44
+	const post_status_private = 'private';
45
+
46
+	/**
47
+	 * @var string post_status_trashed - the wp post status for trashed cpts
48
+	 */
49
+	const post_status_trashed = 'trash';
50
+
51
+	/**
52
+	 * This is an array of custom statuses for the given CPT model (modified by children)
53
+	 * format:
54
+	 * array(
55
+	 *        'status_name' => array(
56
+	 *            'label' => __('Status Name', 'event_espresso'),
57
+	 *            'public' => TRUE //whether a public status or not.
58
+	 *        )
59
+	 * )
60
+	 *
61
+	 * @var array
62
+	 */
63
+	protected $_custom_stati = array();
64
+
65
+
66
+	/**
67
+	 * Adds a relationship to Term_Taxonomy for each CPT_Base
68
+	 *
69
+	 * @param string $timezone
70
+	 * @throws \EE_Error
71
+	 */
72
+	protected function __construct($timezone = null)
73
+	{
74
+		// adds a relationship to Term_Taxonomy for all these models. For this to work
75
+		// Term_Relationship must have a relation to each model subclassing EE_CPT_Base explicitly
76
+		// eg, in EEM_Term_Relationship, inside the _model_relations array, there must be an entry
77
+		// with key equalling the subclassing model's model name (eg 'Event' or 'Venue'), and the value
78
+		// must also be new EE_HABTM_Relation('Term_Relationship');
79
+		$this->_model_relations['Term_Taxonomy'] = new EE_HABTM_Relation('Term_Relationship');
80
+		$primary_table_name = null;
81
+		// add  the common _status field to all CPT primary tables.
82
+		foreach ($this->_tables as $alias => $table_obj) {
83
+			if ($table_obj instanceof EE_Primary_Table) {
84
+				$primary_table_name = $alias;
85
+			}
86
+		}
87
+		// set default wp post statuses if child has not already set.
88
+		if (! isset($this->_fields[ $primary_table_name ]['status'])) {
89
+			$this->_fields[ $primary_table_name ]['status'] = new EE_WP_Post_Status_Field(
90
+				'post_status',
91
+				__("Event Status", "event_espresso"),
92
+				false,
93
+				'draft'
94
+			);
95
+		}
96
+		if (! isset($this->_fields[ $primary_table_name ]['to_ping'])) {
97
+			$this->_fields[ $primary_table_name ]['to_ping'] = new EE_DB_Only_Text_Field(
98
+				'to_ping',
99
+				__('To Ping', 'event_espresso'),
100
+				false,
101
+				''
102
+			);
103
+		}
104
+		if (! isset($this->_fields[ $primary_table_name ]['pinged'])) {
105
+			$this->_fields[ $primary_table_name ]['pinged'] = new EE_DB_Only_Text_Field(
106
+				'pinged',
107
+				__('Pinged', 'event_espresso'),
108
+				false,
109
+				''
110
+			);
111
+		}
112
+		if (! isset($this->_fields[ $primary_table_name ]['comment_status'])) {
113
+			$this->_fields[ $primary_table_name ]['comment_status'] = new EE_Plain_Text_Field(
114
+				'comment_status',
115
+				__('Comment Status', 'event_espresso'),
116
+				false,
117
+				'open'
118
+			);
119
+		}
120
+		if (! isset($this->_fields[ $primary_table_name ]['ping_status'])) {
121
+			$this->_fields[ $primary_table_name ]['ping_status'] = new EE_Plain_Text_Field(
122
+				'ping_status',
123
+				__('Ping Status', 'event_espresso'),
124
+				false,
125
+				'open'
126
+			);
127
+		}
128
+		if (! isset($this->_fields[ $primary_table_name ]['post_content_filtered'])) {
129
+			$this->_fields[ $primary_table_name ]['post_content_filtered'] = new EE_DB_Only_Text_Field(
130
+				'post_content_filtered',
131
+				__('Post Content Filtered', 'event_espresso'),
132
+				false,
133
+				''
134
+			);
135
+		}
136
+		if (! isset($this->_model_relations['Post_Meta'])) {
137
+			// don't block deletes though because we want to maintain the current behaviour
138
+			$this->_model_relations['Post_Meta'] = new EE_Has_Many_Relation(false);
139
+		}
140
+		if (! $this->_minimum_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
141
+			// nothing was set during child constructor, so set default
142
+			$this->_minimum_where_conditions_strategy = new EE_CPT_Minimum_Where_Conditions($this->post_type());
143
+		}
144
+		if (! $this->_default_where_conditions_strategy instanceof EE_Default_Where_Conditions) {
145
+			// nothing was set during child constructor, so set default
146
+			// it's ok for child classes to specify this, but generally this is more DRY
147
+			$this->_default_where_conditions_strategy = new EE_CPT_Where_Conditions($this->post_type());
148
+		}
149
+		parent::__construct($timezone);
150
+	}
151
+
152
+
153
+	/**
154
+	 * @return array
155
+	 */
156
+	public function public_event_stati()
157
+	{
158
+		// @see wp-includes/post.php
159
+		return get_post_stati(array('public' => true));
160
+	}
161
+
162
+
163
+	/**
164
+	 * Searches for field on this model of type 'deleted_flag'. if it is found,
165
+	 * returns it's name. BUT That doesn't apply to CPTs. We should instead use post_status_field_name
166
+	 *
167
+	 * @return string
168
+	 * @throws EE_Error
169
+	 */
170
+	public function deleted_field_name()
171
+	{
172
+		throw new EE_Error(
173
+			sprintf(
174
+				__(
175
+					"EEM_CPT_Base should nto call deleted_field_name! It should instead use post_status_field_name",
176
+					"event_espresso"
177
+				)
178
+			)
179
+		);
180
+	}
181
+
182
+
183
+	/**
184
+	 * Gets the field's name that sets the post status
185
+	 *
186
+	 * @return string
187
+	 * @throws EE_Error
188
+	 */
189
+	public function post_status_field_name()
190
+	{
191
+		$field = $this->get_a_field_of_type('EE_WP_Post_Status_Field');
192
+		if ($field) {
193
+			return $field->get_name();
194
+		} else {
195
+			throw new EE_Error(
196
+				sprintf(
197
+					__(
198
+						'We are trying to find the post status flag field on %s, but none was found. Are you sure there is a field of type EE_Trashed_Flag_Field in %s constructor?',
199
+						'event_espresso'
200
+					),
201
+					get_class($this),
202
+					get_class($this)
203
+				)
204
+			);
205
+		}
206
+	}
207
+
208
+
209
+	/**
210
+	 * Alters the query params so that only trashed/soft-deleted items are considered
211
+	 *
212
+	 * @param array $query_params like EEM_Base::get_all's $query_params
213
+	 * @return array like EEM_Base::get_all's $query_params
214
+	 */
215
+	protected function _alter_query_params_so_only_trashed_items_included($query_params)
216
+	{
217
+		$post_status_field_name = $this->post_status_field_name();
218
+		$query_params[0][ $post_status_field_name ] = self::post_status_trashed;
219
+		return $query_params;
220
+	}
221
+
222
+
223
+	/**
224
+	 * Alters the query params so each item's deleted status is ignored.
225
+	 *
226
+	 * @param array $query_params
227
+	 * @return array
228
+	 */
229
+	protected function _alter_query_params_so_deleted_and_undeleted_items_included($query_params)
230
+	{
231
+		$query_params['default_where_conditions'] = 'minimum';
232
+		return $query_params;
233
+	}
234
+
235
+
236
+	/**
237
+	 * Performs deletes or restores on items. Both soft-deleted and non-soft-deleted items considered.
238
+	 *
239
+	 * @param boolean $delete       true to indicate deletion, false to indicate restoration
240
+	 * @param array   $query_params like EEM_Base::get_all
241
+	 * @return boolean success
242
+	 */
243
+	public function delete_or_restore($delete = true, $query_params = array())
244
+	{
245
+		$post_status_field_name = $this->post_status_field_name();
246
+		$query_params = $this->_alter_query_params_so_deleted_and_undeleted_items_included($query_params);
247
+		$new_status = $delete ? self::post_status_trashed : 'draft';
248
+		if ($this->update(array($post_status_field_name => $new_status), $query_params)) {
249
+			return true;
250
+		} else {
251
+			return false;
252
+		}
253
+	}
254
+
255
+
256
+	/**
257
+	 * meta_table
258
+	 * returns first EE_Secondary_Table table name
259
+	 *
260
+	 * @access public
261
+	 * @return string
262
+	 */
263
+	public function meta_table()
264
+	{
265
+		$meta_table = $this->_get_other_tables();
266
+		$meta_table = reset($meta_table);
267
+		return $meta_table instanceof EE_Secondary_Table ? $meta_table->get_table_name() : null;
268
+	}
269
+
270
+
271
+	/**
272
+	 * This simply returns an array of the meta table fields (useful for when we just need to update those fields)
273
+	 *
274
+	 * @param  bool $all triggers whether we include DB_Only fields or JUST non DB_Only fields.  Defaults to false (no
275
+	 *                   db only fields)
276
+	 * @return array
277
+	 */
278
+	public function get_meta_table_fields($all = false)
279
+	{
280
+		$all_fields = $fields_to_return = array();
281
+		foreach ($this->_tables as $alias => $table_obj) {
282
+			if ($table_obj instanceof EE_Secondary_Table) {
283
+				$all_fields = array_merge($this->_get_fields_for_table($alias), $all_fields);
284
+			}
285
+		}
286
+		if (! $all) {
287
+			foreach ($all_fields as $name => $obj) {
288
+				if ($obj instanceof EE_DB_Only_Field_Base) {
289
+					continue;
290
+				}
291
+				$fields_to_return[] = $name;
292
+			}
293
+		} else {
294
+			$fields_to_return = array_keys($all_fields);
295
+		}
296
+		return $fields_to_return;
297
+	}
298
+
299
+
300
+	/**
301
+	 * Adds an event category with the specified name and description to the specified
302
+	 * $cpt_model_object. Intelligently adds a term if necessary, and adds a term_taxonomy if necessary,
303
+	 * and adds an entry in the term_relationship if necessary.
304
+	 *
305
+	 * @param EE_CPT_Base $cpt_model_object
306
+	 * @param string      $category_name (used to derive the term slug too)
307
+	 * @param string      $category_description
308
+	 * @param int         $parent_term_taxonomy_id
309
+	 * @return EE_Term_Taxonomy
310
+	 */
311
+	public function add_event_category(
312
+		EE_CPT_Base $cpt_model_object,
313
+		$category_name,
314
+		$category_description = '',
315
+		$parent_term_taxonomy_id = null
316
+	) {
317
+		// create term
318
+		require_once(EE_MODELS . 'EEM_Term.model.php');
319
+		// first, check for a term by the same name or slug
320
+		$category_slug = sanitize_title($category_name);
321
+		$term = EEM_Term::instance()->get_one(
322
+			array(
323
+				array(
324
+					'OR' => array(
325
+						'name' => $category_name,
326
+						'slug' => $category_slug,
327
+					),
328
+					'Term_Taxonomy.taxonomy' => self::EVENT_CATEGORY_TAXONOMY
329
+				),
330
+			)
331
+		);
332
+		if (! $term) {
333
+			$term = EE_Term::new_instance(
334
+				array(
335
+					'name' => $category_name,
336
+					'slug' => $category_slug,
337
+				)
338
+			);
339
+			$term->save();
340
+		}
341
+		// make sure there's a term-taxonomy entry too
342
+		require_once(EE_MODELS . 'EEM_Term_Taxonomy.model.php');
343
+		$term_taxonomy = EEM_Term_Taxonomy::instance()->get_one(
344
+			array(
345
+				array(
346
+					'term_id'  => $term->ID(),
347
+					'taxonomy' => self::EVENT_CATEGORY_TAXONOMY,
348
+				),
349
+			)
350
+		);
351
+		/** @var $term_taxonomy EE_Term_Taxonomy */
352
+		if (! $term_taxonomy) {
353
+			$term_taxonomy = EE_Term_Taxonomy::new_instance(
354
+				array(
355
+					'term_id'     => $term->ID(),
356
+					'taxonomy'    => self::EVENT_CATEGORY_TAXONOMY,
357
+					'description' => $category_description,
358
+					'term_count'       => 1,
359
+					'parent'      => $parent_term_taxonomy_id,
360
+				)
361
+			);
362
+			$term_taxonomy->save();
363
+		} else {
364
+			$term_taxonomy->set_count($term_taxonomy->count() + 1);
365
+			$term_taxonomy->save();
366
+		}
367
+		return $this->add_relationship_to($cpt_model_object, $term_taxonomy, 'Term_Taxonomy');
368
+	}
369
+
370
+
371
+	/**
372
+	 * Removed the category specified by name as having a relation to this event.
373
+	 * Does not remove the term or term_taxonomy.
374
+	 *
375
+	 * @param EE_CPT_Base $cpt_model_object_event
376
+	 * @param string      $category_name name of the event category (term)
377
+	 * @return bool
378
+	 */
379
+	public function remove_event_category(EE_CPT_Base $cpt_model_object_event, $category_name)
380
+	{
381
+		// find the term_taxonomy by that name
382
+		$term_taxonomy = $this->get_first_related(
383
+			$cpt_model_object_event,
384
+			'Term_Taxonomy',
385
+			array(array('Term.name' => $category_name, 'taxonomy' => self::EVENT_CATEGORY_TAXONOMY))
386
+		);
387
+		/** @var $term_taxonomy EE_Term_Taxonomy */
388
+		if ($term_taxonomy) {
389
+			$term_taxonomy->set_count($term_taxonomy->count() - 1);
390
+			$term_taxonomy->save();
391
+		}
392
+		return $this->remove_relationship_to($cpt_model_object_event, $term_taxonomy, 'Term_Taxonomy');
393
+	}
394
+
395
+
396
+	/**
397
+	 * This is a wrapper for the WordPress get_the_post_thumbnail() function that returns the feature image for the
398
+	 * given CPT ID.  It accepts the same params as what get_the_post_thumbnail() accepts.
399
+	 *
400
+	 * @link   http://codex.wordpress.org/Function_Reference/get_the_post_thumbnail
401
+	 * @access public
402
+	 * @param int          $id   the ID for the cpt we want the feature image for
403
+	 * @param string|array $size (optional) Image size. Defaults to 'post-thumbnail' but can also be a 2-item array
404
+	 *                           representing width and height in pixels (i.e. array(32,32) ).
405
+	 * @param string|array $attr Optional. Query string or array of attributes.
406
+	 * @return string HTML image element
407
+	 */
408
+	public function get_feature_image($id, $size = 'thumbnail', $attr = '')
409
+	{
410
+		return get_the_post_thumbnail($id, $size, $attr);
411
+	}
412
+
413
+
414
+	/**
415
+	 * Just a handy way to get the list of post statuses currently registered with WP.
416
+	 *
417
+	 * @global array $wp_post_statuses set in wp core for storing all the post stati
418
+	 * @return array
419
+	 */
420
+	public function get_post_statuses()
421
+	{
422
+		global $wp_post_statuses;
423
+		$statuses = array();
424
+		foreach ($wp_post_statuses as $post_status => $args_object) {
425
+			$statuses[ $post_status ] = $args_object->label;
426
+		}
427
+		return $statuses;
428
+	}
429
+
430
+
431
+	/**
432
+	 * public method that can be used to retrieve the protected status array on the instantiated cpt model
433
+	 *
434
+	 * @return array array of statuses.
435
+	 */
436
+	public function get_status_array()
437
+	{
438
+		$statuses = $this->get_post_statuses();
439
+		// first the global filter
440
+		$statuses = apply_filters('FHEE_EEM_CPT_Base__get_status_array', $statuses);
441
+		// now the class specific filter
442
+		$statuses = apply_filters('FHEE_EEM_' . get_class($this) . '__get_status_array', $statuses);
443
+		return $statuses;
444
+	}
445
+
446
+
447
+	/**
448
+	 * this returns the post statuses that are NOT the default wordpress status
449
+	 *
450
+	 * @return array
451
+	 */
452
+	public function get_custom_post_statuses()
453
+	{
454
+		$new_stati = array();
455
+		foreach ($this->_custom_stati as $status => $props) {
456
+			$new_stati[ $status ] = $props['label'];
457
+		}
458
+		return $new_stati;
459
+	}
460
+
461
+
462
+	/**
463
+	 * Creates a child of EE_CPT_Base given a WP_Post or array of wpdb results which
464
+	 * are a row from the posts table. If we're missing any fields required for the model,
465
+	 * we just fetch the entire entry from the DB (ie, if you want to use this to save DB queries,
466
+	 * make sure you are attaching all the model's fields onto the post)
467
+	 *
468
+	 * @param WP_Post|array $post
469
+	 * @return EE_Base_Class|EE_Soft_Delete_Base_Class
470
+	 */
471
+	public function instantiate_class_from_post_object_orig($post)
472
+	{
473
+		$post = (array) $post;
474
+		$has_all_necessary_fields_for_table = true;
475
+		// check if the post has fields on the meta table already
476
+		foreach ($this->_get_other_tables() as $table_obj) {
477
+			$fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
478
+			foreach ($fields_for_that_table as $field_obj) {
479
+				if (! isset($post[ $field_obj->get_table_column() ])
480
+					&& ! isset($post[ $field_obj->get_qualified_column() ])
481
+				) {
482
+					$has_all_necessary_fields_for_table = false;
483
+				}
484
+			}
485
+		}
486
+		// if we don't have all the fields we need, then just fetch the proper model from the DB
487
+		if (! $has_all_necessary_fields_for_table) {
488
+			return $this->get_one_by_ID($post['ID']);
489
+		} else {
490
+			return $this->instantiate_class_from_array_or_object($post);
491
+		}
492
+	}
493
+
494
+
495
+	/**
496
+	 * @param null $post
497
+	 * @return EE_Base_Class|EE_Soft_Delete_Base_Class
498
+	 */
499
+	public function instantiate_class_from_post_object($post = null)
500
+	{
501
+		if (empty($post)) {
502
+			global $post;
503
+		}
504
+		$post = (array) $post;
505
+		$tables_needing_to_be_queried = array();
506
+		// check if the post has fields on the meta table already
507
+		foreach ($this->get_tables() as $table_obj) {
508
+			$fields_for_that_table = $this->_get_fields_for_table($table_obj->get_table_alias());
509
+			foreach ($fields_for_that_table as $field_obj) {
510
+				if (! isset($post[ $field_obj->get_table_column() ])
511
+					&& ! isset($post[ $field_obj->get_qualified_column() ])
512
+				) {
513
+					$tables_needing_to_be_queried[ $table_obj->get_table_alias() ] = $table_obj;
514
+				}
515
+			}
516
+		}
517
+		// if we don't have all the fields we need, then just fetch the proper model from the DB
518
+		if ($tables_needing_to_be_queried) {
519
+			if (count($tables_needing_to_be_queried) == 1
520
+				&& reset($tables_needing_to_be_queried)
521
+				   instanceof
522
+				   EE_Secondary_Table
523
+			) {
524
+				// so we're only missing data from a secondary table. Well that's not too hard to query for
525
+				$table_to_query = reset($tables_needing_to_be_queried);
526
+				$missing_data = $this->_do_wpdb_query(
527
+					'get_row',
528
+					array(
529
+						'SELECT * FROM '
530
+						. $table_to_query->get_table_name()
531
+						. ' WHERE '
532
+						. $table_to_query->get_fk_on_table()
533
+						. ' = '
534
+						. $post['ID'],
535
+						ARRAY_A,
536
+					)
537
+				);
538
+				if (! empty($missing_data)) {
539
+					$post = array_merge($post, $missing_data);
540
+				}
541
+			} else {
542
+				return $this->get_one_by_ID($post['ID']);
543
+			}
544
+		}
545
+		return $this->instantiate_class_from_array_or_object($post);
546
+	}
547
+
548
+
549
+	/**
550
+	 * Gets the post type associated with this
551
+	 *
552
+	 * @throws EE_Error
553
+	 * @return string
554
+	 */
555
+	public function post_type()
556
+	{
557
+		$post_type_field = null;
558
+		foreach ($this->field_settings(true) as $field_obj) {
559
+			if ($field_obj instanceof EE_WP_Post_Type_Field) {
560
+				$post_type_field = $field_obj;
561
+				break;
562
+			}
563
+		}
564
+		if ($post_type_field == null) {
565
+			throw new EE_Error(
566
+				sprintf(
567
+					__(
568
+						"CPT Model %s should have a field of type EE_WP_Post_Type, but doesnt",
569
+						"event_espresso"
570
+					),
571
+					get_class($this)
572
+				)
573
+			);
574
+		}
575
+		return $post_type_field->get_default_value();
576
+	}
577 577
 }
Please login to merge, or discard this patch.
core/EE_Cron_Tasks.core.php 3 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -2,7 +2,6 @@
 block discarded – undo
2 2
 
3 3
 use EventEspresso\core\exceptions\InvalidDataTypeException;
4 4
 use EventEspresso\core\exceptions\InvalidInterfaceException;
5
-use EventEspresso\core\services\loaders\Loader;
6 5
 use EventEspresso\core\services\loaders\LoaderFactory;
7 6
 
8 7
 /**
Please login to merge, or discard this patch.
Indentation   +586 added lines, -586 removed lines patch added patch discarded remove patch
@@ -15,590 +15,590 @@
 block discarded – undo
15 15
 class EE_Cron_Tasks extends EE_Base
16 16
 {
17 17
 
18
-    /**
19
-     * WordPress doesn't allow duplicate crons within 10 minutes of the original,
20
-     * so we'll set our retry time for just over 10 minutes to avoid that
21
-     */
22
-    const reschedule_timeout = 605;
23
-
24
-
25
-    /**
26
-     * @var EE_Cron_Tasks
27
-     */
28
-    private static $_instance;
29
-
30
-
31
-    /**
32
-     * @return EE_Cron_Tasks
33
-     * @throws ReflectionException
34
-     * @throws EE_Error
35
-     * @throws InvalidArgumentException
36
-     * @throws InvalidInterfaceException
37
-     * @throws InvalidDataTypeException
38
-     */
39
-    public static function instance()
40
-    {
41
-        if (! self::$_instance instanceof EE_Cron_Tasks) {
42
-            self::$_instance = new self();
43
-        }
44
-        return self::$_instance;
45
-    }
46
-
47
-
48
-    /**
49
-     * @access private
50
-     * @throws InvalidDataTypeException
51
-     * @throws InvalidInterfaceException
52
-     * @throws InvalidArgumentException
53
-     * @throws EE_Error
54
-     * @throws ReflectionException
55
-     */
56
-    private function __construct()
57
-    {
58
-        do_action('AHEE_log', __CLASS__, __FUNCTION__);
59
-        // verify that WP Cron is enabled
60
-        if (defined('DISABLE_WP_CRON')
61
-            && DISABLE_WP_CRON
62
-            && is_admin()
63
-            && ! get_option('ee_disabled_wp_cron_check')
64
-        ) {
65
-            /**
66
-             * This needs to be delayed until after the config is loaded because EE_Cron_Tasks is constructed before
67
-             * config is loaded.
68
-             * This is intentionally using a anonymous function so that its not easily de-registered.  Client code
69
-             * wanting to not have this functionality can just register its own action at a priority after this one to
70
-             * reverse any changes.
71
-             */
72
-            add_action(
73
-                'AHEE__EE_System__load_core_configuration__complete',
74
-                function () {
75
-                    EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request = true;
76
-                    EE_Registry::instance()->NET_CFG->update_config(true, false);
77
-                    add_option('ee_disabled_wp_cron_check', 1, '', false);
78
-                }
79
-            );
80
-        }
81
-        // UPDATE TRANSACTION WITH PAYMENT
82
-        add_action(
83
-            'AHEE__EE_Cron_Tasks__update_transaction_with_payment_2',
84
-            array('EE_Cron_Tasks', 'setup_update_for_transaction_with_payment'),
85
-            10,
86
-            2
87
-        );
88
-        // ABANDONED / EXPIRED TRANSACTION CHECK
89
-        add_action(
90
-            'AHEE__EE_Cron_Tasks__expired_transaction_check',
91
-            array('EE_Cron_Tasks', 'expired_transaction_check'),
92
-            10,
93
-            1
94
-        );
95
-        // CLEAN OUT JUNK TRANSACTIONS AND RELATED DATA
96
-        add_action(
97
-            'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
98
-            array('EE_Cron_Tasks', 'clean_out_junk_transactions')
99
-        );
100
-        // logging
101
-        add_action(
102
-            'AHEE__EE_System__load_core_configuration__complete',
103
-            array('EE_Cron_Tasks', 'log_scheduled_ee_crons')
104
-        );
105
-        EE_Registry::instance()->load_lib('Messages_Scheduler');
106
-        // clean out old gateway logs
107
-        add_action(
108
-            'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs',
109
-            array('EE_Cron_Tasks', 'clean_out_old_gateway_logs')
110
-        );
111
-    }
112
-
113
-
114
-    /**
115
-     * @access protected
116
-     * @return void
117
-     */
118
-    public static function log_scheduled_ee_crons()
119
-    {
120
-        $ee_crons = array(
121
-            'AHEE__EE_Cron_Tasks__update_transaction_with_payment',
122
-            'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions',
123
-            'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
124
-        );
125
-        $crons = (array) get_option('cron');
126
-        if (! is_array($crons)) {
127
-            return;
128
-        }
129
-        foreach ($crons as $timestamp => $cron) {
130
-            /** @var array[] $cron */
131
-            foreach ($ee_crons as $ee_cron) {
132
-                if (isset($cron[ $ee_cron ]) && is_array($cron[ $ee_cron ])) {
133
-                    do_action('AHEE_log', __CLASS__, __FUNCTION__, $ee_cron, 'scheduled EE cron');
134
-                    foreach ($cron[ $ee_cron ] as $ee_cron_details) {
135
-                        if (! empty($ee_cron_details['args'])) {
136
-                            do_action(
137
-                                'AHEE_log',
138
-                                __CLASS__,
139
-                                __FUNCTION__,
140
-                                print_r($ee_cron_details['args'], true),
141
-                                "{$ee_cron} args"
142
-                            );
143
-                        }
144
-                    }
145
-                }
146
-            }
147
-        }
148
-    }
149
-
150
-
151
-    /**
152
-     * reschedule_cron_for_transactions_if_maintenance_mode
153
-     * if Maintenance Mode is active, this will reschedule a cron to run again in 10 minutes
154
-     *
155
-     * @param string $cron_task
156
-     * @param array  $TXN_IDs
157
-     * @return bool
158
-     * @throws DomainException
159
-     */
160
-    public static function reschedule_cron_for_transactions_if_maintenance_mode($cron_task, array $TXN_IDs)
161
-    {
162
-        if (! method_exists('EE_Cron_Tasks', $cron_task)) {
163
-            throw new DomainException(
164
-                sprintf(
165
-                    __('"%1$s" is not valid method on EE_Cron_Tasks.', 'event_espresso'),
166
-                    $cron_task
167
-                )
168
-            );
169
-        }
170
-        // reschedule the cron if we can't hit the db right now
171
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
172
-            foreach ($TXN_IDs as $TXN_ID => $additional_vars) {
173
-                // ensure $additional_vars is an array
174
-                $additional_vars = is_array($additional_vars) ? $additional_vars : array($additional_vars);
175
-                // reset cron job for the TXN
176
-                call_user_func_array(
177
-                    array('EE_Cron_Tasks', $cron_task),
178
-                    array_merge(
179
-                        array(
180
-                            time() + (10 * MINUTE_IN_SECONDS),
181
-                            $TXN_ID,
182
-                        ),
183
-                        $additional_vars
184
-                    )
185
-                );
186
-            }
187
-            return true;
188
-        }
189
-        return false;
190
-    }
191
-
192
-
193
-
194
-
195
-    /****************  UPDATE TRANSACTION WITH PAYMENT ****************/
196
-
197
-
198
-    /**
199
-     * array of TXN IDs and the payment
200
-     *
201
-     * @var array
202
-     */
203
-    protected static $_update_transactions_with_payment = array();
204
-
205
-
206
-    /**
207
-     * schedule_update_transaction_with_payment
208
-     * sets a wp_schedule_single_event() for updating any TXNs that may
209
-     * require updating due to recently received payments
210
-     *
211
-     * @param int $timestamp
212
-     * @param int $TXN_ID
213
-     * @param int $PAY_ID
214
-     */
215
-    public static function schedule_update_transaction_with_payment(
216
-        $timestamp,
217
-        $TXN_ID,
218
-        $PAY_ID
219
-    ) {
220
-        do_action('AHEE_log', __CLASS__, __FUNCTION__);
221
-        // validate $TXN_ID and $timestamp
222
-        $TXN_ID = absint($TXN_ID);
223
-        $timestamp = absint($timestamp);
224
-        if ($TXN_ID && $timestamp) {
225
-            wp_schedule_single_event(
226
-                $timestamp,
227
-                'AHEE__EE_Cron_Tasks__update_transaction_with_payment_2',
228
-                array($TXN_ID, $PAY_ID)
229
-            );
230
-        }
231
-    }
232
-
233
-
234
-    /**
235
-     * setup_update_for_transaction_with_payment
236
-     * this is the callback for the action hook:
237
-     * 'AHEE__EE_Cron_Tasks__update_transaction_with_payment'
238
-     * which is setup by EE_Cron_Tasks::schedule_update_transaction_with_payment().
239
-     * The passed TXN_ID and associated payment gets added to an array, and then
240
-     * the EE_Cron_Tasks::update_transaction_with_payment() function is hooked into
241
-     * 'shutdown' which will actually handle the processing of any
242
-     * transactions requiring updating, because doing so now would be too early
243
-     * and the required resources may not be available
244
-     *
245
-     * @param int $TXN_ID
246
-     * @param int $PAY_ID
247
-     */
248
-    public static function setup_update_for_transaction_with_payment($TXN_ID = 0, $PAY_ID = 0)
249
-    {
250
-        do_action('AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID');
251
-        if (absint($TXN_ID)) {
252
-            self::$_update_transactions_with_payment[ $TXN_ID ] = $PAY_ID;
253
-            add_action(
254
-                'shutdown',
255
-                array('EE_Cron_Tasks', 'update_transaction_with_payment'),
256
-                5
257
-            );
258
-        }
259
-    }
260
-
261
-
262
-    /**
263
-     * update_transaction_with_payment
264
-     * loops through the self::$_abandoned_transactions array
265
-     * and attempts to finalize any TXNs that have not been completed
266
-     * but have had their sessions expired, most likely due to a user not
267
-     * returning from an off-site payment gateway
268
-     *
269
-     * @throws EE_Error
270
-     * @throws DomainException
271
-     * @throws InvalidDataTypeException
272
-     * @throws InvalidInterfaceException
273
-     * @throws InvalidArgumentException
274
-     * @throws ReflectionException
275
-     * @throws RuntimeException
276
-     */
277
-    public static function update_transaction_with_payment()
278
-    {
279
-        do_action('AHEE_log', __CLASS__, __FUNCTION__);
280
-        if (// are there any TXNs that need cleaning up ?
281
-            empty(self::$_update_transactions_with_payment)
282
-            // reschedule the cron if we can't hit the db right now
283
-            || EE_Cron_Tasks::reschedule_cron_for_transactions_if_maintenance_mode(
284
-                'schedule_update_transaction_with_payment',
285
-                self::$_update_transactions_with_payment
286
-            )
287
-        ) {
288
-            return;
289
-        }
290
-        /** @type EE_Payment_Processor $payment_processor */
291
-        $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
292
-        // set revisit flag for payment processor
293
-        $payment_processor->set_revisit();
294
-        // load EEM_Transaction
295
-        EE_Registry::instance()->load_model('Transaction');
296
-        foreach (self::$_update_transactions_with_payment as $TXN_ID => $PAY_ID) {
297
-            // reschedule the cron if we can't hit the db right now
298
-            if (! EE_Maintenance_Mode::instance()->models_can_query()) {
299
-                // reset cron job for updating the TXN
300
-                EE_Cron_Tasks::schedule_update_transaction_with_payment(
301
-                    time() + EE_Cron_Tasks::reschedule_timeout,
302
-                    $TXN_ID,
303
-                    $PAY_ID
304
-                );
305
-                continue;
306
-            }
307
-            $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
308
-            $payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
309
-            // verify transaction
310
-            if ($transaction instanceof EE_Transaction && $payment instanceof EE_Payment) {
311
-                // now try to update the TXN with any payments
312
-                $payment_processor->update_txn_based_on_payment($transaction, $payment, true, true);
313
-            }
314
-            unset(self::$_update_transactions_with_payment[ $TXN_ID ]);
315
-        }
316
-    }
317
-
318
-
319
-
320
-    /************  END OF UPDATE TRANSACTION WITH PAYMENT  ************/
321
-
322
-
323
-    /*****************  EXPIRED TRANSACTION CHECK *****************/
324
-
325
-
326
-    /**
327
-     * array of TXN IDs
328
-     *
329
-     * @var array
330
-     */
331
-    protected static $_expired_transactions = array();
332
-
333
-
334
-    /**
335
-     * schedule_expired_transaction_check
336
-     * sets a wp_schedule_single_event() for following up on TXNs after their session has expired
337
-     *
338
-     * @param int $timestamp
339
-     * @param int $TXN_ID
340
-     */
341
-    public static function schedule_expired_transaction_check(
342
-        $timestamp,
343
-        $TXN_ID
344
-    ) {
345
-        // validate $TXN_ID and $timestamp
346
-        $TXN_ID = absint($TXN_ID);
347
-        $timestamp = absint($timestamp);
348
-        if ($TXN_ID && $timestamp) {
349
-            wp_schedule_single_event(
350
-                $timestamp,
351
-                'AHEE__EE_Cron_Tasks__expired_transaction_check',
352
-                array($TXN_ID)
353
-            );
354
-        }
355
-    }
356
-
357
-
358
-    /**
359
-     * expired_transaction_check
360
-     * this is the callback for the action hook:
361
-     * 'AHEE__EE_Cron_Tasks__transaction_session_expiration_check'
362
-     * which is utilized by wp_schedule_single_event()
363
-     * in \EED_Single_Page_Checkout::_initialize_transaction().
364
-     * The passed TXN_ID gets added to an array, and then the
365
-     * process_expired_transactions() function is hooked into
366
-     * 'AHEE__EE_System__core_loaded_and_ready' which will actually handle the
367
-     * processing of any failed transactions, because doing so now would be
368
-     * too early and the required resources may not be available
369
-     *
370
-     * @param int $TXN_ID
371
-     */
372
-    public static function expired_transaction_check($TXN_ID = 0)
373
-    {
374
-        if (absint($TXN_ID)) {
375
-            self::$_expired_transactions[ $TXN_ID ] = $TXN_ID;
376
-            add_action(
377
-                'shutdown',
378
-                array('EE_Cron_Tasks', 'process_expired_transactions'),
379
-                5
380
-            );
381
-        }
382
-    }
383
-
384
-
385
-    /**
386
-     * process_expired_transactions
387
-     * loops through the self::$_expired_transactions array and processes any failed TXNs
388
-     *
389
-     * @throws EE_Error
390
-     * @throws InvalidDataTypeException
391
-     * @throws InvalidInterfaceException
392
-     * @throws InvalidArgumentException
393
-     * @throws ReflectionException
394
-     * @throws DomainException
395
-     * @throws RuntimeException
396
-     */
397
-    public static function process_expired_transactions()
398
-    {
399
-        if (// are there any TXNs that need cleaning up ?
400
-            empty(self::$_expired_transactions)
401
-            // reschedule the cron if we can't hit the db right now
402
-            || EE_Cron_Tasks::reschedule_cron_for_transactions_if_maintenance_mode(
403
-                'schedule_expired_transaction_check',
404
-                self::$_expired_transactions
405
-            )
406
-        ) {
407
-            return;
408
-        }
409
-        /** @type EE_Transaction_Processor $transaction_processor */
410
-        $transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
411
-        // set revisit flag for txn processor
412
-        $transaction_processor->set_revisit();
413
-        // load EEM_Transaction
414
-        EE_Registry::instance()->load_model('Transaction');
415
-        foreach (self::$_expired_transactions as $TXN_ID) {
416
-            $transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
417
-            // verify transaction and whether it is failed or not
418
-            if ($transaction instanceof EE_Transaction) {
419
-                switch ($transaction->status_ID()) {
420
-                    // Completed TXNs
421
-                    case EEM_Transaction::complete_status_code:
422
-                        do_action(
423
-                            'AHEE__EE_Cron_Tasks__process_expired_transactions__completed_transaction',
424
-                            $transaction
425
-                        );
426
-                        break;
427
-                    // Overpaid TXNs
428
-                    case EEM_Transaction::overpaid_status_code:
429
-                        do_action(
430
-                            'AHEE__EE_Cron_Tasks__process_expired_transactions__overpaid_transaction',
431
-                            $transaction
432
-                        );
433
-                        break;
434
-                    // Incomplete TXNs
435
-                    case EEM_Transaction::incomplete_status_code:
436
-                        do_action(
437
-                            'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
438
-                            $transaction
439
-                        );
440
-                        // todo : move business logic into EE_Transaction_Processor for finalizing abandoned transactions
441
-                        break;
442
-                    // Abandoned TXNs
443
-                    case EEM_Transaction::abandoned_status_code:
444
-                        // run hook before updating transaction, primarily so
445
-                        // EED_Ticket_Sales_Monitor::process_abandoned_transactions() can release reserved tickets
446
-                        do_action(
447
-                            'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
448
-                            $transaction
449
-                        );
450
-                        // don't finalize the TXN if it has already been completed
451
-                        if ($transaction->all_reg_steps_completed() !== true) {
452
-                            /** @type EE_Payment_Processor $payment_processor */
453
-                            $payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
454
-                            // let's simulate an IPN here which will trigger any notifications that need to go out
455
-                            $payment_processor->update_txn_based_on_payment(
456
-                                $transaction,
457
-                                $transaction->last_payment(),
458
-                                true,
459
-                                true
460
-                            );
461
-                        }
462
-                        break;
463
-                    // Failed TXNs
464
-                    case EEM_Transaction::failed_status_code:
465
-                        do_action(
466
-                            'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
467
-                            $transaction
468
-                        );
469
-                        // todo :
470
-                        // perform garbage collection here and remove clean_out_junk_transactions()
471
-                        // $registrations = $transaction->registrations();
472
-                        // if (! empty($registrations)) {
473
-                        //     foreach ($registrations as $registration) {
474
-                        //         if ($registration instanceof EE_Registration) {
475
-                        //             $delete_registration = true;
476
-                        //             if ($registration->attendee() instanceof EE_Attendee) {
477
-                        //                 $delete_registration = false;
478
-                        //             }
479
-                        //             if ($delete_registration) {
480
-                        //                 $registration->delete_permanently();
481
-                        //                 $registration->delete_related_permanently();
482
-                        //             }
483
-                        //         }
484
-                        //     }
485
-                        // }
486
-                        break;
487
-                }
488
-            }
489
-            unset(self::$_expired_transactions[ $TXN_ID ]);
490
-        }
491
-    }
492
-
493
-
494
-
495
-    /*************  END OF EXPIRED TRANSACTION CHECK  *************/
496
-
497
-
498
-    /************* START CLEAN UP BOT TRANSACTIONS **********************/
499
-
500
-
501
-    /**
502
-     * callback for 'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'
503
-     * which is setup during activation to run on an hourly cron
504
-     *
505
-     * @throws EE_Error
506
-     * @throws InvalidArgumentException
507
-     * @throws InvalidDataTypeException
508
-     * @throws InvalidInterfaceException
509
-     * @throws DomainException
510
-     */
511
-    public static function clean_out_junk_transactions()
512
-    {
513
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
514
-            EED_Ticket_Sales_Monitor::reset_reservation_counts();
515
-            EEM_Transaction::instance('')->delete_junk_transactions();
516
-            EEM_Registration::instance('')->delete_registrations_with_no_transaction();
517
-            EEM_Line_Item::instance('')->delete_line_items_with_no_transaction();
518
-        }
519
-    }
520
-
521
-
522
-    /**
523
-     * Deletes old gateway logs. After about a week we usually don't need them for debugging. But folks can filter that.
524
-     *
525
-     * @throws EE_Error
526
-     * @throws InvalidDataTypeException
527
-     * @throws InvalidInterfaceException
528
-     * @throws InvalidArgumentException
529
-     */
530
-    public static function clean_out_old_gateway_logs()
531
-    {
532
-        if (EE_Maintenance_Mode::instance()->models_can_query()) {
533
-            $reg_config = LoaderFactory::getLoader()->load('EE_Registration_Config');
534
-            $time_diff_for_comparison = apply_filters(
535
-                'FHEE__EE_Cron_Tasks__clean_out_old_gateway_logs__time_diff_for_comparison',
536
-                '-' . $reg_config->gateway_log_lifespan
537
-            );
538
-            EEM_Change_Log::instance()->delete_gateway_logs_older_than(new DateTime($time_diff_for_comparison));
539
-        }
540
-    }
541
-
542
-
543
-    /*****************  FINALIZE ABANDONED TRANSACTIONS *****************/
544
-
545
-
546
-    /**
547
-     * @var array
548
-     */
549
-    protected static $_abandoned_transactions = array();
550
-
551
-
552
-    /**
553
-     * @deprecated
554
-     * @param int $timestamp
555
-     * @param int $TXN_ID
556
-     */
557
-    public static function schedule_finalize_abandoned_transactions_check($timestamp, $TXN_ID)
558
-    {
559
-        EE_Cron_Tasks::schedule_expired_transaction_check($timestamp, $TXN_ID);
560
-    }
561
-
562
-
563
-    /**
564
-     * @deprecated
565
-     * @param int $TXN_ID
566
-     */
567
-    public static function check_for_abandoned_transactions($TXN_ID = 0)
568
-    {
569
-        EE_Cron_Tasks::expired_transaction_check($TXN_ID);
570
-    }
571
-
572
-
573
-    /**
574
-     * @deprecated
575
-     * @throws EE_Error
576
-     * @throws DomainException
577
-     * @throws InvalidDataTypeException
578
-     * @throws InvalidInterfaceException
579
-     * @throws InvalidArgumentException
580
-     * @throws ReflectionException
581
-     * @throws RuntimeException
582
-     */
583
-    public static function finalize_abandoned_transactions()
584
-    {
585
-        do_action('AHEE_log', __CLASS__, __FUNCTION__);
586
-        if (// are there any TXNs that need cleaning up ?
587
-            empty(self::$_abandoned_transactions)
588
-            // reschedule the cron if we can't hit the db right now
589
-            || EE_Cron_Tasks::reschedule_cron_for_transactions_if_maintenance_mode(
590
-                'schedule_expired_transaction_check',
591
-                self::$_abandoned_transactions
592
-            )
593
-        ) {
594
-            return;
595
-        }
596
-        // combine our arrays of transaction IDs
597
-        self::$_expired_transactions = self::$_abandoned_transactions + self::$_expired_transactions;
598
-        // and deal with abandoned transactions here now...
599
-        EE_Cron_Tasks::process_expired_transactions();
600
-    }
601
-
602
-
603
-    /*************  END OF FINALIZE ABANDONED TRANSACTIONS  *************/
18
+	/**
19
+	 * WordPress doesn't allow duplicate crons within 10 minutes of the original,
20
+	 * so we'll set our retry time for just over 10 minutes to avoid that
21
+	 */
22
+	const reschedule_timeout = 605;
23
+
24
+
25
+	/**
26
+	 * @var EE_Cron_Tasks
27
+	 */
28
+	private static $_instance;
29
+
30
+
31
+	/**
32
+	 * @return EE_Cron_Tasks
33
+	 * @throws ReflectionException
34
+	 * @throws EE_Error
35
+	 * @throws InvalidArgumentException
36
+	 * @throws InvalidInterfaceException
37
+	 * @throws InvalidDataTypeException
38
+	 */
39
+	public static function instance()
40
+	{
41
+		if (! self::$_instance instanceof EE_Cron_Tasks) {
42
+			self::$_instance = new self();
43
+		}
44
+		return self::$_instance;
45
+	}
46
+
47
+
48
+	/**
49
+	 * @access private
50
+	 * @throws InvalidDataTypeException
51
+	 * @throws InvalidInterfaceException
52
+	 * @throws InvalidArgumentException
53
+	 * @throws EE_Error
54
+	 * @throws ReflectionException
55
+	 */
56
+	private function __construct()
57
+	{
58
+		do_action('AHEE_log', __CLASS__, __FUNCTION__);
59
+		// verify that WP Cron is enabled
60
+		if (defined('DISABLE_WP_CRON')
61
+			&& DISABLE_WP_CRON
62
+			&& is_admin()
63
+			&& ! get_option('ee_disabled_wp_cron_check')
64
+		) {
65
+			/**
66
+			 * This needs to be delayed until after the config is loaded because EE_Cron_Tasks is constructed before
67
+			 * config is loaded.
68
+			 * This is intentionally using a anonymous function so that its not easily de-registered.  Client code
69
+			 * wanting to not have this functionality can just register its own action at a priority after this one to
70
+			 * reverse any changes.
71
+			 */
72
+			add_action(
73
+				'AHEE__EE_System__load_core_configuration__complete',
74
+				function () {
75
+					EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request = true;
76
+					EE_Registry::instance()->NET_CFG->update_config(true, false);
77
+					add_option('ee_disabled_wp_cron_check', 1, '', false);
78
+				}
79
+			);
80
+		}
81
+		// UPDATE TRANSACTION WITH PAYMENT
82
+		add_action(
83
+			'AHEE__EE_Cron_Tasks__update_transaction_with_payment_2',
84
+			array('EE_Cron_Tasks', 'setup_update_for_transaction_with_payment'),
85
+			10,
86
+			2
87
+		);
88
+		// ABANDONED / EXPIRED TRANSACTION CHECK
89
+		add_action(
90
+			'AHEE__EE_Cron_Tasks__expired_transaction_check',
91
+			array('EE_Cron_Tasks', 'expired_transaction_check'),
92
+			10,
93
+			1
94
+		);
95
+		// CLEAN OUT JUNK TRANSACTIONS AND RELATED DATA
96
+		add_action(
97
+			'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
98
+			array('EE_Cron_Tasks', 'clean_out_junk_transactions')
99
+		);
100
+		// logging
101
+		add_action(
102
+			'AHEE__EE_System__load_core_configuration__complete',
103
+			array('EE_Cron_Tasks', 'log_scheduled_ee_crons')
104
+		);
105
+		EE_Registry::instance()->load_lib('Messages_Scheduler');
106
+		// clean out old gateway logs
107
+		add_action(
108
+			'AHEE_EE_Cron_Tasks__clean_out_old_gateway_logs',
109
+			array('EE_Cron_Tasks', 'clean_out_old_gateway_logs')
110
+		);
111
+	}
112
+
113
+
114
+	/**
115
+	 * @access protected
116
+	 * @return void
117
+	 */
118
+	public static function log_scheduled_ee_crons()
119
+	{
120
+		$ee_crons = array(
121
+			'AHEE__EE_Cron_Tasks__update_transaction_with_payment',
122
+			'AHEE__EE_Cron_Tasks__finalize_abandoned_transactions',
123
+			'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
124
+		);
125
+		$crons = (array) get_option('cron');
126
+		if (! is_array($crons)) {
127
+			return;
128
+		}
129
+		foreach ($crons as $timestamp => $cron) {
130
+			/** @var array[] $cron */
131
+			foreach ($ee_crons as $ee_cron) {
132
+				if (isset($cron[ $ee_cron ]) && is_array($cron[ $ee_cron ])) {
133
+					do_action('AHEE_log', __CLASS__, __FUNCTION__, $ee_cron, 'scheduled EE cron');
134
+					foreach ($cron[ $ee_cron ] as $ee_cron_details) {
135
+						if (! empty($ee_cron_details['args'])) {
136
+							do_action(
137
+								'AHEE_log',
138
+								__CLASS__,
139
+								__FUNCTION__,
140
+								print_r($ee_cron_details['args'], true),
141
+								"{$ee_cron} args"
142
+							);
143
+						}
144
+					}
145
+				}
146
+			}
147
+		}
148
+	}
149
+
150
+
151
+	/**
152
+	 * reschedule_cron_for_transactions_if_maintenance_mode
153
+	 * if Maintenance Mode is active, this will reschedule a cron to run again in 10 minutes
154
+	 *
155
+	 * @param string $cron_task
156
+	 * @param array  $TXN_IDs
157
+	 * @return bool
158
+	 * @throws DomainException
159
+	 */
160
+	public static function reschedule_cron_for_transactions_if_maintenance_mode($cron_task, array $TXN_IDs)
161
+	{
162
+		if (! method_exists('EE_Cron_Tasks', $cron_task)) {
163
+			throw new DomainException(
164
+				sprintf(
165
+					__('"%1$s" is not valid method on EE_Cron_Tasks.', 'event_espresso'),
166
+					$cron_task
167
+				)
168
+			);
169
+		}
170
+		// reschedule the cron if we can't hit the db right now
171
+		if (! EE_Maintenance_Mode::instance()->models_can_query()) {
172
+			foreach ($TXN_IDs as $TXN_ID => $additional_vars) {
173
+				// ensure $additional_vars is an array
174
+				$additional_vars = is_array($additional_vars) ? $additional_vars : array($additional_vars);
175
+				// reset cron job for the TXN
176
+				call_user_func_array(
177
+					array('EE_Cron_Tasks', $cron_task),
178
+					array_merge(
179
+						array(
180
+							time() + (10 * MINUTE_IN_SECONDS),
181
+							$TXN_ID,
182
+						),
183
+						$additional_vars
184
+					)
185
+				);
186
+			}
187
+			return true;
188
+		}
189
+		return false;
190
+	}
191
+
192
+
193
+
194
+
195
+	/****************  UPDATE TRANSACTION WITH PAYMENT ****************/
196
+
197
+
198
+	/**
199
+	 * array of TXN IDs and the payment
200
+	 *
201
+	 * @var array
202
+	 */
203
+	protected static $_update_transactions_with_payment = array();
204
+
205
+
206
+	/**
207
+	 * schedule_update_transaction_with_payment
208
+	 * sets a wp_schedule_single_event() for updating any TXNs that may
209
+	 * require updating due to recently received payments
210
+	 *
211
+	 * @param int $timestamp
212
+	 * @param int $TXN_ID
213
+	 * @param int $PAY_ID
214
+	 */
215
+	public static function schedule_update_transaction_with_payment(
216
+		$timestamp,
217
+		$TXN_ID,
218
+		$PAY_ID
219
+	) {
220
+		do_action('AHEE_log', __CLASS__, __FUNCTION__);
221
+		// validate $TXN_ID and $timestamp
222
+		$TXN_ID = absint($TXN_ID);
223
+		$timestamp = absint($timestamp);
224
+		if ($TXN_ID && $timestamp) {
225
+			wp_schedule_single_event(
226
+				$timestamp,
227
+				'AHEE__EE_Cron_Tasks__update_transaction_with_payment_2',
228
+				array($TXN_ID, $PAY_ID)
229
+			);
230
+		}
231
+	}
232
+
233
+
234
+	/**
235
+	 * setup_update_for_transaction_with_payment
236
+	 * this is the callback for the action hook:
237
+	 * 'AHEE__EE_Cron_Tasks__update_transaction_with_payment'
238
+	 * which is setup by EE_Cron_Tasks::schedule_update_transaction_with_payment().
239
+	 * The passed TXN_ID and associated payment gets added to an array, and then
240
+	 * the EE_Cron_Tasks::update_transaction_with_payment() function is hooked into
241
+	 * 'shutdown' which will actually handle the processing of any
242
+	 * transactions requiring updating, because doing so now would be too early
243
+	 * and the required resources may not be available
244
+	 *
245
+	 * @param int $TXN_ID
246
+	 * @param int $PAY_ID
247
+	 */
248
+	public static function setup_update_for_transaction_with_payment($TXN_ID = 0, $PAY_ID = 0)
249
+	{
250
+		do_action('AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID');
251
+		if (absint($TXN_ID)) {
252
+			self::$_update_transactions_with_payment[ $TXN_ID ] = $PAY_ID;
253
+			add_action(
254
+				'shutdown',
255
+				array('EE_Cron_Tasks', 'update_transaction_with_payment'),
256
+				5
257
+			);
258
+		}
259
+	}
260
+
261
+
262
+	/**
263
+	 * update_transaction_with_payment
264
+	 * loops through the self::$_abandoned_transactions array
265
+	 * and attempts to finalize any TXNs that have not been completed
266
+	 * but have had their sessions expired, most likely due to a user not
267
+	 * returning from an off-site payment gateway
268
+	 *
269
+	 * @throws EE_Error
270
+	 * @throws DomainException
271
+	 * @throws InvalidDataTypeException
272
+	 * @throws InvalidInterfaceException
273
+	 * @throws InvalidArgumentException
274
+	 * @throws ReflectionException
275
+	 * @throws RuntimeException
276
+	 */
277
+	public static function update_transaction_with_payment()
278
+	{
279
+		do_action('AHEE_log', __CLASS__, __FUNCTION__);
280
+		if (// are there any TXNs that need cleaning up ?
281
+			empty(self::$_update_transactions_with_payment)
282
+			// reschedule the cron if we can't hit the db right now
283
+			|| EE_Cron_Tasks::reschedule_cron_for_transactions_if_maintenance_mode(
284
+				'schedule_update_transaction_with_payment',
285
+				self::$_update_transactions_with_payment
286
+			)
287
+		) {
288
+			return;
289
+		}
290
+		/** @type EE_Payment_Processor $payment_processor */
291
+		$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
292
+		// set revisit flag for payment processor
293
+		$payment_processor->set_revisit();
294
+		// load EEM_Transaction
295
+		EE_Registry::instance()->load_model('Transaction');
296
+		foreach (self::$_update_transactions_with_payment as $TXN_ID => $PAY_ID) {
297
+			// reschedule the cron if we can't hit the db right now
298
+			if (! EE_Maintenance_Mode::instance()->models_can_query()) {
299
+				// reset cron job for updating the TXN
300
+				EE_Cron_Tasks::schedule_update_transaction_with_payment(
301
+					time() + EE_Cron_Tasks::reschedule_timeout,
302
+					$TXN_ID,
303
+					$PAY_ID
304
+				);
305
+				continue;
306
+			}
307
+			$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
308
+			$payment = EEM_Payment::instance()->get_one_by_ID($PAY_ID);
309
+			// verify transaction
310
+			if ($transaction instanceof EE_Transaction && $payment instanceof EE_Payment) {
311
+				// now try to update the TXN with any payments
312
+				$payment_processor->update_txn_based_on_payment($transaction, $payment, true, true);
313
+			}
314
+			unset(self::$_update_transactions_with_payment[ $TXN_ID ]);
315
+		}
316
+	}
317
+
318
+
319
+
320
+	/************  END OF UPDATE TRANSACTION WITH PAYMENT  ************/
321
+
322
+
323
+	/*****************  EXPIRED TRANSACTION CHECK *****************/
324
+
325
+
326
+	/**
327
+	 * array of TXN IDs
328
+	 *
329
+	 * @var array
330
+	 */
331
+	protected static $_expired_transactions = array();
332
+
333
+
334
+	/**
335
+	 * schedule_expired_transaction_check
336
+	 * sets a wp_schedule_single_event() for following up on TXNs after their session has expired
337
+	 *
338
+	 * @param int $timestamp
339
+	 * @param int $TXN_ID
340
+	 */
341
+	public static function schedule_expired_transaction_check(
342
+		$timestamp,
343
+		$TXN_ID
344
+	) {
345
+		// validate $TXN_ID and $timestamp
346
+		$TXN_ID = absint($TXN_ID);
347
+		$timestamp = absint($timestamp);
348
+		if ($TXN_ID && $timestamp) {
349
+			wp_schedule_single_event(
350
+				$timestamp,
351
+				'AHEE__EE_Cron_Tasks__expired_transaction_check',
352
+				array($TXN_ID)
353
+			);
354
+		}
355
+	}
356
+
357
+
358
+	/**
359
+	 * expired_transaction_check
360
+	 * this is the callback for the action hook:
361
+	 * 'AHEE__EE_Cron_Tasks__transaction_session_expiration_check'
362
+	 * which is utilized by wp_schedule_single_event()
363
+	 * in \EED_Single_Page_Checkout::_initialize_transaction().
364
+	 * The passed TXN_ID gets added to an array, and then the
365
+	 * process_expired_transactions() function is hooked into
366
+	 * 'AHEE__EE_System__core_loaded_and_ready' which will actually handle the
367
+	 * processing of any failed transactions, because doing so now would be
368
+	 * too early and the required resources may not be available
369
+	 *
370
+	 * @param int $TXN_ID
371
+	 */
372
+	public static function expired_transaction_check($TXN_ID = 0)
373
+	{
374
+		if (absint($TXN_ID)) {
375
+			self::$_expired_transactions[ $TXN_ID ] = $TXN_ID;
376
+			add_action(
377
+				'shutdown',
378
+				array('EE_Cron_Tasks', 'process_expired_transactions'),
379
+				5
380
+			);
381
+		}
382
+	}
383
+
384
+
385
+	/**
386
+	 * process_expired_transactions
387
+	 * loops through the self::$_expired_transactions array and processes any failed TXNs
388
+	 *
389
+	 * @throws EE_Error
390
+	 * @throws InvalidDataTypeException
391
+	 * @throws InvalidInterfaceException
392
+	 * @throws InvalidArgumentException
393
+	 * @throws ReflectionException
394
+	 * @throws DomainException
395
+	 * @throws RuntimeException
396
+	 */
397
+	public static function process_expired_transactions()
398
+	{
399
+		if (// are there any TXNs that need cleaning up ?
400
+			empty(self::$_expired_transactions)
401
+			// reschedule the cron if we can't hit the db right now
402
+			|| EE_Cron_Tasks::reschedule_cron_for_transactions_if_maintenance_mode(
403
+				'schedule_expired_transaction_check',
404
+				self::$_expired_transactions
405
+			)
406
+		) {
407
+			return;
408
+		}
409
+		/** @type EE_Transaction_Processor $transaction_processor */
410
+		$transaction_processor = EE_Registry::instance()->load_class('Transaction_Processor');
411
+		// set revisit flag for txn processor
412
+		$transaction_processor->set_revisit();
413
+		// load EEM_Transaction
414
+		EE_Registry::instance()->load_model('Transaction');
415
+		foreach (self::$_expired_transactions as $TXN_ID) {
416
+			$transaction = EEM_Transaction::instance()->get_one_by_ID($TXN_ID);
417
+			// verify transaction and whether it is failed or not
418
+			if ($transaction instanceof EE_Transaction) {
419
+				switch ($transaction->status_ID()) {
420
+					// Completed TXNs
421
+					case EEM_Transaction::complete_status_code:
422
+						do_action(
423
+							'AHEE__EE_Cron_Tasks__process_expired_transactions__completed_transaction',
424
+							$transaction
425
+						);
426
+						break;
427
+					// Overpaid TXNs
428
+					case EEM_Transaction::overpaid_status_code:
429
+						do_action(
430
+							'AHEE__EE_Cron_Tasks__process_expired_transactions__overpaid_transaction',
431
+							$transaction
432
+						);
433
+						break;
434
+					// Incomplete TXNs
435
+					case EEM_Transaction::incomplete_status_code:
436
+						do_action(
437
+							'AHEE__EE_Cron_Tasks__process_expired_transactions__incomplete_transaction',
438
+							$transaction
439
+						);
440
+						// todo : move business logic into EE_Transaction_Processor for finalizing abandoned transactions
441
+						break;
442
+					// Abandoned TXNs
443
+					case EEM_Transaction::abandoned_status_code:
444
+						// run hook before updating transaction, primarily so
445
+						// EED_Ticket_Sales_Monitor::process_abandoned_transactions() can release reserved tickets
446
+						do_action(
447
+							'AHEE__EE_Cron_Tasks__process_expired_transactions__abandoned_transaction',
448
+							$transaction
449
+						);
450
+						// don't finalize the TXN if it has already been completed
451
+						if ($transaction->all_reg_steps_completed() !== true) {
452
+							/** @type EE_Payment_Processor $payment_processor */
453
+							$payment_processor = EE_Registry::instance()->load_core('Payment_Processor');
454
+							// let's simulate an IPN here which will trigger any notifications that need to go out
455
+							$payment_processor->update_txn_based_on_payment(
456
+								$transaction,
457
+								$transaction->last_payment(),
458
+								true,
459
+								true
460
+							);
461
+						}
462
+						break;
463
+					// Failed TXNs
464
+					case EEM_Transaction::failed_status_code:
465
+						do_action(
466
+							'AHEE__EE_Cron_Tasks__process_expired_transactions__failed_transaction',
467
+							$transaction
468
+						);
469
+						// todo :
470
+						// perform garbage collection here and remove clean_out_junk_transactions()
471
+						// $registrations = $transaction->registrations();
472
+						// if (! empty($registrations)) {
473
+						//     foreach ($registrations as $registration) {
474
+						//         if ($registration instanceof EE_Registration) {
475
+						//             $delete_registration = true;
476
+						//             if ($registration->attendee() instanceof EE_Attendee) {
477
+						//                 $delete_registration = false;
478
+						//             }
479
+						//             if ($delete_registration) {
480
+						//                 $registration->delete_permanently();
481
+						//                 $registration->delete_related_permanently();
482
+						//             }
483
+						//         }
484
+						//     }
485
+						// }
486
+						break;
487
+				}
488
+			}
489
+			unset(self::$_expired_transactions[ $TXN_ID ]);
490
+		}
491
+	}
492
+
493
+
494
+
495
+	/*************  END OF EXPIRED TRANSACTION CHECK  *************/
496
+
497
+
498
+	/************* START CLEAN UP BOT TRANSACTIONS **********************/
499
+
500
+
501
+	/**
502
+	 * callback for 'AHEE__EE_Cron_Tasks__clean_up_junk_transactions'
503
+	 * which is setup during activation to run on an hourly cron
504
+	 *
505
+	 * @throws EE_Error
506
+	 * @throws InvalidArgumentException
507
+	 * @throws InvalidDataTypeException
508
+	 * @throws InvalidInterfaceException
509
+	 * @throws DomainException
510
+	 */
511
+	public static function clean_out_junk_transactions()
512
+	{
513
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
514
+			EED_Ticket_Sales_Monitor::reset_reservation_counts();
515
+			EEM_Transaction::instance('')->delete_junk_transactions();
516
+			EEM_Registration::instance('')->delete_registrations_with_no_transaction();
517
+			EEM_Line_Item::instance('')->delete_line_items_with_no_transaction();
518
+		}
519
+	}
520
+
521
+
522
+	/**
523
+	 * Deletes old gateway logs. After about a week we usually don't need them for debugging. But folks can filter that.
524
+	 *
525
+	 * @throws EE_Error
526
+	 * @throws InvalidDataTypeException
527
+	 * @throws InvalidInterfaceException
528
+	 * @throws InvalidArgumentException
529
+	 */
530
+	public static function clean_out_old_gateway_logs()
531
+	{
532
+		if (EE_Maintenance_Mode::instance()->models_can_query()) {
533
+			$reg_config = LoaderFactory::getLoader()->load('EE_Registration_Config');
534
+			$time_diff_for_comparison = apply_filters(
535
+				'FHEE__EE_Cron_Tasks__clean_out_old_gateway_logs__time_diff_for_comparison',
536
+				'-' . $reg_config->gateway_log_lifespan
537
+			);
538
+			EEM_Change_Log::instance()->delete_gateway_logs_older_than(new DateTime($time_diff_for_comparison));
539
+		}
540
+	}
541
+
542
+
543
+	/*****************  FINALIZE ABANDONED TRANSACTIONS *****************/
544
+
545
+
546
+	/**
547
+	 * @var array
548
+	 */
549
+	protected static $_abandoned_transactions = array();
550
+
551
+
552
+	/**
553
+	 * @deprecated
554
+	 * @param int $timestamp
555
+	 * @param int $TXN_ID
556
+	 */
557
+	public static function schedule_finalize_abandoned_transactions_check($timestamp, $TXN_ID)
558
+	{
559
+		EE_Cron_Tasks::schedule_expired_transaction_check($timestamp, $TXN_ID);
560
+	}
561
+
562
+
563
+	/**
564
+	 * @deprecated
565
+	 * @param int $TXN_ID
566
+	 */
567
+	public static function check_for_abandoned_transactions($TXN_ID = 0)
568
+	{
569
+		EE_Cron_Tasks::expired_transaction_check($TXN_ID);
570
+	}
571
+
572
+
573
+	/**
574
+	 * @deprecated
575
+	 * @throws EE_Error
576
+	 * @throws DomainException
577
+	 * @throws InvalidDataTypeException
578
+	 * @throws InvalidInterfaceException
579
+	 * @throws InvalidArgumentException
580
+	 * @throws ReflectionException
581
+	 * @throws RuntimeException
582
+	 */
583
+	public static function finalize_abandoned_transactions()
584
+	{
585
+		do_action('AHEE_log', __CLASS__, __FUNCTION__);
586
+		if (// are there any TXNs that need cleaning up ?
587
+			empty(self::$_abandoned_transactions)
588
+			// reschedule the cron if we can't hit the db right now
589
+			|| EE_Cron_Tasks::reschedule_cron_for_transactions_if_maintenance_mode(
590
+				'schedule_expired_transaction_check',
591
+				self::$_abandoned_transactions
592
+			)
593
+		) {
594
+			return;
595
+		}
596
+		// combine our arrays of transaction IDs
597
+		self::$_expired_transactions = self::$_abandoned_transactions + self::$_expired_transactions;
598
+		// and deal with abandoned transactions here now...
599
+		EE_Cron_Tasks::process_expired_transactions();
600
+	}
601
+
602
+
603
+	/*************  END OF FINALIZE ABANDONED TRANSACTIONS  *************/
604 604
 }
Please login to merge, or discard this patch.
Spacing   +14 added lines, -14 removed lines patch added patch discarded remove patch
@@ -38,7 +38,7 @@  discard block
 block discarded – undo
38 38
      */
39 39
     public static function instance()
40 40
     {
41
-        if (! self::$_instance instanceof EE_Cron_Tasks) {
41
+        if ( ! self::$_instance instanceof EE_Cron_Tasks) {
42 42
             self::$_instance = new self();
43 43
         }
44 44
         return self::$_instance;
@@ -71,7 +71,7 @@  discard block
 block discarded – undo
71 71
              */
72 72
             add_action(
73 73
                 'AHEE__EE_System__load_core_configuration__complete',
74
-                function () {
74
+                function() {
75 75
                     EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request = true;
76 76
                     EE_Registry::instance()->NET_CFG->update_config(true, false);
77 77
                     add_option('ee_disabled_wp_cron_check', 1, '', false);
@@ -123,16 +123,16 @@  discard block
 block discarded – undo
123 123
             'AHEE__EE_Cron_Tasks__clean_up_junk_transactions',
124 124
         );
125 125
         $crons = (array) get_option('cron');
126
-        if (! is_array($crons)) {
126
+        if ( ! is_array($crons)) {
127 127
             return;
128 128
         }
129 129
         foreach ($crons as $timestamp => $cron) {
130 130
             /** @var array[] $cron */
131 131
             foreach ($ee_crons as $ee_cron) {
132
-                if (isset($cron[ $ee_cron ]) && is_array($cron[ $ee_cron ])) {
132
+                if (isset($cron[$ee_cron]) && is_array($cron[$ee_cron])) {
133 133
                     do_action('AHEE_log', __CLASS__, __FUNCTION__, $ee_cron, 'scheduled EE cron');
134
-                    foreach ($cron[ $ee_cron ] as $ee_cron_details) {
135
-                        if (! empty($ee_cron_details['args'])) {
134
+                    foreach ($cron[$ee_cron] as $ee_cron_details) {
135
+                        if ( ! empty($ee_cron_details['args'])) {
136 136
                             do_action(
137 137
                                 'AHEE_log',
138 138
                                 __CLASS__,
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
      */
160 160
     public static function reschedule_cron_for_transactions_if_maintenance_mode($cron_task, array $TXN_IDs)
161 161
     {
162
-        if (! method_exists('EE_Cron_Tasks', $cron_task)) {
162
+        if ( ! method_exists('EE_Cron_Tasks', $cron_task)) {
163 163
             throw new DomainException(
164 164
                 sprintf(
165 165
                     __('"%1$s" is not valid method on EE_Cron_Tasks.', 'event_espresso'),
@@ -168,7 +168,7 @@  discard block
 block discarded – undo
168 168
             );
169 169
         }
170 170
         // reschedule the cron if we can't hit the db right now
171
-        if (! EE_Maintenance_Mode::instance()->models_can_query()) {
171
+        if ( ! EE_Maintenance_Mode::instance()->models_can_query()) {
172 172
             foreach ($TXN_IDs as $TXN_ID => $additional_vars) {
173 173
                 // ensure $additional_vars is an array
174 174
                 $additional_vars = is_array($additional_vars) ? $additional_vars : array($additional_vars);
@@ -249,7 +249,7 @@  discard block
 block discarded – undo
249 249
     {
250 250
         do_action('AHEE_log', __CLASS__, __FUNCTION__, $TXN_ID, '$TXN_ID');
251 251
         if (absint($TXN_ID)) {
252
-            self::$_update_transactions_with_payment[ $TXN_ID ] = $PAY_ID;
252
+            self::$_update_transactions_with_payment[$TXN_ID] = $PAY_ID;
253 253
             add_action(
254 254
                 'shutdown',
255 255
                 array('EE_Cron_Tasks', 'update_transaction_with_payment'),
@@ -295,7 +295,7 @@  discard block
 block discarded – undo
295 295
         EE_Registry::instance()->load_model('Transaction');
296 296
         foreach (self::$_update_transactions_with_payment as $TXN_ID => $PAY_ID) {
297 297
             // reschedule the cron if we can't hit the db right now
298
-            if (! EE_Maintenance_Mode::instance()->models_can_query()) {
298
+            if ( ! EE_Maintenance_Mode::instance()->models_can_query()) {
299 299
                 // reset cron job for updating the TXN
300 300
                 EE_Cron_Tasks::schedule_update_transaction_with_payment(
301 301
                     time() + EE_Cron_Tasks::reschedule_timeout,
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
                 // now try to update the TXN with any payments
312 312
                 $payment_processor->update_txn_based_on_payment($transaction, $payment, true, true);
313 313
             }
314
-            unset(self::$_update_transactions_with_payment[ $TXN_ID ]);
314
+            unset(self::$_update_transactions_with_payment[$TXN_ID]);
315 315
         }
316 316
     }
317 317
 
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
     public static function expired_transaction_check($TXN_ID = 0)
373 373
     {
374 374
         if (absint($TXN_ID)) {
375
-            self::$_expired_transactions[ $TXN_ID ] = $TXN_ID;
375
+            self::$_expired_transactions[$TXN_ID] = $TXN_ID;
376 376
             add_action(
377 377
                 'shutdown',
378 378
                 array('EE_Cron_Tasks', 'process_expired_transactions'),
@@ -486,7 +486,7 @@  discard block
 block discarded – undo
486 486
                         break;
487 487
                 }
488 488
             }
489
-            unset(self::$_expired_transactions[ $TXN_ID ]);
489
+            unset(self::$_expired_transactions[$TXN_ID]);
490 490
         }
491 491
     }
492 492
 
@@ -533,7 +533,7 @@  discard block
 block discarded – undo
533 533
             $reg_config = LoaderFactory::getLoader()->load('EE_Registration_Config');
534 534
             $time_diff_for_comparison = apply_filters(
535 535
                 'FHEE__EE_Cron_Tasks__clean_out_old_gateway_logs__time_diff_for_comparison',
536
-                '-' . $reg_config->gateway_log_lifespan
536
+                '-'.$reg_config->gateway_log_lifespan
537 537
             );
538 538
             EEM_Change_Log::instance()->delete_gateway_logs_older_than(new DateTime($time_diff_for_comparison));
539 539
         }
Please login to merge, or discard this patch.
core/EE_Dependency_Map.core.php 2 patches
Spacing   +33 added lines, -33 removed lines patch added patch discarded remove patch
@@ -122,7 +122,7 @@  discard block
 block discarded – undo
122 122
     public static function instance(ClassInterfaceCache $class_cache = null)
123 123
     {
124 124
         // check if class object is instantiated, and instantiated properly
125
-        if (! self::$_instance instanceof EE_Dependency_Map
125
+        if ( ! self::$_instance instanceof EE_Dependency_Map
126 126
             && $class_cache instanceof ClassInterfaceCache
127 127
         ) {
128 128
             self::$_instance = new EE_Dependency_Map($class_cache);
@@ -203,18 +203,18 @@  discard block
 block discarded – undo
203 203
     ) {
204 204
         $class = trim($class, '\\');
205 205
         $registered = false;
206
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
207
-            self::$_instance->_dependency_map[ $class ] = array();
206
+        if (empty(self::$_instance->_dependency_map[$class])) {
207
+            self::$_instance->_dependency_map[$class] = array();
208 208
         }
209 209
         // we need to make sure that any aliases used when registering a dependency
210 210
         // get resolved to the correct class name
211 211
         foreach ($dependencies as $dependency => $load_source) {
212 212
             $alias = self::$_instance->getFqnForAlias($dependency);
213 213
             if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
214
+                || ! isset(self::$_instance->_dependency_map[$class][$alias])
215 215
             ) {
216
-                unset($dependencies[ $dependency ]);
217
-                $dependencies[ $alias ] = $load_source;
216
+                unset($dependencies[$dependency]);
217
+                $dependencies[$alias] = $load_source;
218 218
                 $registered = true;
219 219
             }
220 220
         }
@@ -224,13 +224,13 @@  discard block
 block discarded – undo
224 224
         // ie: with A = B + C, entries in B take precedence over duplicate entries in C
225 225
         // Union is way faster than array_merge() but should be used with caution...
226 226
         // especially with numerically indexed arrays
227
-        $dependencies += self::$_instance->_dependency_map[ $class ];
227
+        $dependencies += self::$_instance->_dependency_map[$class];
228 228
         // now we need to ensure that the resulting dependencies
229 229
         // array only has the entries that are required for the class
230 230
         // so first count how many dependencies were originally registered for the class
231
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
231
+        $dependency_count = count(self::$_instance->_dependency_map[$class]);
232 232
         // if that count is non-zero (meaning dependencies were already registered)
233
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
233
+        self::$_instance->_dependency_map[$class] = $dependency_count
234 234
             // then truncate the  final array to match that count
235 235
             ? array_slice($dependencies, 0, $dependency_count)
236 236
             // otherwise just take the incoming array because nothing previously existed
@@ -247,13 +247,13 @@  discard block
 block discarded – undo
247 247
      */
248 248
     public static function register_class_loader($class_name, $loader = 'load_core')
249 249
     {
250
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
250
+        if ( ! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251 251
             throw new DomainException(
252 252
                 esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253 253
             );
254 254
         }
255 255
         // check that loader is callable or method starts with "load_" and exists in EE_Registry
256
-        if (! is_callable($loader)
256
+        if ( ! is_callable($loader)
257 257
             && (
258 258
                 strpos($loader, 'load_') !== 0
259 259
                 || ! method_exists('EE_Registry', $loader)
@@ -270,8 +270,8 @@  discard block
 block discarded – undo
270 270
             );
271 271
         }
272 272
         $class_name = self::$_instance->getFqnForAlias($class_name);
273
-        if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
-            self::$_instance->_class_loaders[ $class_name ] = $loader;
273
+        if ( ! isset(self::$_instance->_class_loaders[$class_name])) {
274
+            self::$_instance->_class_loaders[$class_name] = $loader;
275 275
             return true;
276 276
         }
277 277
         return false;
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
         if (strpos($class_name, 'EEM_') === 0) {
300 300
             $class_name = 'LEGACY_MODELS';
301 301
         }
302
-        return isset($this->_dependency_map[ $class_name ]) ? true : false;
302
+        return isset($this->_dependency_map[$class_name]) ? true : false;
303 303
     }
304 304
 
305 305
 
@@ -317,7 +317,7 @@  discard block
 block discarded – undo
317 317
             $class_name = 'LEGACY_MODELS';
318 318
         }
319 319
         $dependency = $this->getFqnForAlias($dependency, $class_name);
320
-        return isset($this->_dependency_map[ $class_name ][ $dependency ])
320
+        return isset($this->_dependency_map[$class_name][$dependency])
321 321
             ? true
322 322
             : false;
323 323
     }
@@ -338,7 +338,7 @@  discard block
 block discarded – undo
338 338
         }
339 339
         $dependency = $this->getFqnForAlias($dependency);
340 340
         return $this->has_dependency_for_class($class_name, $dependency)
341
-            ? $this->_dependency_map[ $class_name ][ $dependency ]
341
+            ? $this->_dependency_map[$class_name][$dependency]
342 342
             : EE_Dependency_Map::not_registered;
343 343
     }
344 344
 
@@ -354,7 +354,7 @@  discard block
 block discarded – undo
354 354
             return 'load_model';
355 355
         }
356 356
         $class_name = $this->getFqnForAlias($class_name);
357
-        return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
357
+        return isset($this->_class_loaders[$class_name]) ? $this->_class_loaders[$class_name] : '';
358 358
     }
359 359
 
360 360
 
@@ -788,13 +788,13 @@  discard block
 block discarded – undo
788 788
             'EE_Front_Controller'                          => 'load_core',
789 789
             'EE_Module_Request_Router'                     => 'load_core',
790 790
             'EE_Registry'                                  => 'load_core',
791
-            'EE_Request'                                   => function () use (&$legacy_request) {
791
+            'EE_Request'                                   => function() use (&$legacy_request) {
792 792
                 return $legacy_request;
793 793
             },
794
-            'EventEspresso\core\services\request\Request'  => function () use (&$request) {
794
+            'EventEspresso\core\services\request\Request'  => function() use (&$request) {
795 795
                 return $request;
796 796
             },
797
-            'EventEspresso\core\services\request\Response' => function () use (&$response) {
797
+            'EventEspresso\core\services\request\Response' => function() use (&$response) {
798 798
                 return $response;
799 799
             },
800 800
             'EE_Base'                                      => 'load_core',
@@ -818,7 +818,7 @@  discard block
 block discarded – undo
818 818
             'EE_Messages_Data_Handler_Collection'          => 'load_lib',
819 819
             'EE_Message_Template_Group_Collection'         => 'load_lib',
820 820
             'EE_Payment_Method_Manager'                    => 'load_lib',
821
-            'EE_Messages_Generator'                        => function () {
821
+            'EE_Messages_Generator'                        => function() {
822 822
                 return EE_Registry::instance()->load_lib(
823 823
                     'Messages_Generator',
824 824
                     array(),
@@ -826,7 +826,7 @@  discard block
 block discarded – undo
826 826
                     false
827 827
                 );
828 828
             },
829
-            'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
829
+            'EE_Messages_Template_Defaults'                => function($arguments = array()) {
830 830
                 return EE_Registry::instance()->load_lib(
831 831
                     'Messages_Template_Defaults',
832 832
                     $arguments,
@@ -835,37 +835,37 @@  discard block
 block discarded – undo
835 835
                 );
836 836
             },
837 837
             // load_helper
838
-            'EEH_Parse_Shortcodes'                         => function () {
838
+            'EEH_Parse_Shortcodes'                         => function() {
839 839
                 if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
840 840
                     return new EEH_Parse_Shortcodes();
841 841
                 }
842 842
                 return null;
843 843
             },
844
-            'EE_Template_Config'                           => function () {
844
+            'EE_Template_Config'                           => function() {
845 845
                 return EE_Config::instance()->template_settings;
846 846
             },
847
-            'EE_Currency_Config'                           => function () {
847
+            'EE_Currency_Config'                           => function() {
848 848
                 return EE_Config::instance()->currency;
849 849
             },
850
-            'EE_Registration_Config'                       => function () {
850
+            'EE_Registration_Config'                       => function() {
851 851
                 return EE_Config::instance()->registration;
852 852
             },
853
-            'EE_Core_Config'                               => function () {
853
+            'EE_Core_Config'                               => function() {
854 854
                 return EE_Config::instance()->core;
855 855
             },
856
-            'EventEspresso\core\services\loaders\Loader'   => function () {
856
+            'EventEspresso\core\services\loaders\Loader'   => function() {
857 857
                 return LoaderFactory::getLoader();
858 858
             },
859
-            'EE_Network_Config'                            => function () {
859
+            'EE_Network_Config'                            => function() {
860 860
                 return EE_Network_Config::instance();
861 861
             },
862
-            'EE_Config'                                    => function () {
862
+            'EE_Config'                                    => function() {
863 863
                 return EE_Config::instance();
864 864
             },
865
-            'EventEspresso\core\domain\Domain'             => function () {
865
+            'EventEspresso\core\domain\Domain'             => function() {
866 866
                 return DomainFactory::getEventEspressoCoreDomain();
867 867
             },
868
-            'EE_Admin_Config'                              => function () {
868
+            'EE_Admin_Config'                              => function() {
869 869
                 return EE_Config::instance()->admin;
870 870
             }
871 871
         );
@@ -927,7 +927,7 @@  discard block
 block discarded – undo
927 927
             }
928 928
             $this->class_cache->addAlias($fqn, $alias);
929 929
         }
930
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
930
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
931 931
             $this->class_cache->addAlias(
932 932
                 'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
933 933
                 'EventEspresso\core\services\notices\NoticeConverterInterface'
Please login to merge, or discard this patch.
Indentation   +979 added lines, -979 removed lines patch added patch discarded remove patch
@@ -20,983 +20,983 @@
 block discarded – undo
20 20
 class EE_Dependency_Map
21 21
 {
22 22
 
23
-    /**
24
-     * This means that the requested class dependency is not present in the dependency map
25
-     */
26
-    const not_registered = 0;
27
-
28
-    /**
29
-     * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
-     */
31
-    const load_new_object = 1;
32
-
33
-    /**
34
-     * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
-     * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
-     */
37
-    const load_from_cache = 2;
38
-
39
-    /**
40
-     * When registering a dependency,
41
-     * this indicates to keep any existing dependencies that already exist,
42
-     * and simply discard any new dependencies declared in the incoming data
43
-     */
44
-    const KEEP_EXISTING_DEPENDENCIES = 0;
45
-
46
-    /**
47
-     * When registering a dependency,
48
-     * this indicates to overwrite any existing dependencies that already exist using the incoming data
49
-     */
50
-    const OVERWRITE_DEPENDENCIES = 1;
51
-
52
-
53
-    /**
54
-     * @type EE_Dependency_Map $_instance
55
-     */
56
-    protected static $_instance;
57
-
58
-    /**
59
-     * @var ClassInterfaceCache $class_cache
60
-     */
61
-    private $class_cache;
62
-
63
-    /**
64
-     * @type RequestInterface $request
65
-     */
66
-    protected $request;
67
-
68
-    /**
69
-     * @type LegacyRequestInterface $legacy_request
70
-     */
71
-    protected $legacy_request;
72
-
73
-    /**
74
-     * @type ResponseInterface $response
75
-     */
76
-    protected $response;
77
-
78
-    /**
79
-     * @type LoaderInterface $loader
80
-     */
81
-    protected $loader;
82
-
83
-    /**
84
-     * @type array $_dependency_map
85
-     */
86
-    protected $_dependency_map = array();
87
-
88
-    /**
89
-     * @type array $_class_loaders
90
-     */
91
-    protected $_class_loaders = array();
92
-
93
-
94
-    /**
95
-     * EE_Dependency_Map constructor.
96
-     *
97
-     * @param ClassInterfaceCache $class_cache
98
-     */
99
-    protected function __construct(ClassInterfaceCache $class_cache)
100
-    {
101
-        $this->class_cache = $class_cache;
102
-        do_action('EE_Dependency_Map____construct', $this);
103
-    }
104
-
105
-
106
-    /**
107
-     * @return void
108
-     */
109
-    public function initialize()
110
-    {
111
-        $this->_register_core_dependencies();
112
-        $this->_register_core_class_loaders();
113
-        $this->_register_core_aliases();
114
-    }
115
-
116
-
117
-    /**
118
-     * @singleton method used to instantiate class object
119
-     * @param ClassInterfaceCache|null $class_cache
120
-     * @return EE_Dependency_Map
121
-     */
122
-    public static function instance(ClassInterfaceCache $class_cache = null)
123
-    {
124
-        // check if class object is instantiated, and instantiated properly
125
-        if (! self::$_instance instanceof EE_Dependency_Map
126
-            && $class_cache instanceof ClassInterfaceCache
127
-        ) {
128
-            self::$_instance = new EE_Dependency_Map($class_cache);
129
-        }
130
-        return self::$_instance;
131
-    }
132
-
133
-
134
-    /**
135
-     * @param RequestInterface $request
136
-     */
137
-    public function setRequest(RequestInterface $request)
138
-    {
139
-        $this->request = $request;
140
-    }
141
-
142
-
143
-    /**
144
-     * @param LegacyRequestInterface $legacy_request
145
-     */
146
-    public function setLegacyRequest(LegacyRequestInterface $legacy_request)
147
-    {
148
-        $this->legacy_request = $legacy_request;
149
-    }
150
-
151
-
152
-    /**
153
-     * @param ResponseInterface $response
154
-     */
155
-    public function setResponse(ResponseInterface $response)
156
-    {
157
-        $this->response = $response;
158
-    }
159
-
160
-
161
-    /**
162
-     * @param LoaderInterface $loader
163
-     */
164
-    public function setLoader(LoaderInterface $loader)
165
-    {
166
-        $this->loader = $loader;
167
-    }
168
-
169
-
170
-    /**
171
-     * @param string $class
172
-     * @param array  $dependencies
173
-     * @param int    $overwrite
174
-     * @return bool
175
-     */
176
-    public static function register_dependencies(
177
-        $class,
178
-        array $dependencies,
179
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
180
-    ) {
181
-        return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
182
-    }
183
-
184
-
185
-    /**
186
-     * Assigns an array of class names and corresponding load sources (new or cached)
187
-     * to the class specified by the first parameter.
188
-     * IMPORTANT !!!
189
-     * The order of elements in the incoming $dependencies array MUST match
190
-     * the order of the constructor parameters for the class in question.
191
-     * This is especially important when overriding any existing dependencies that are registered.
192
-     * the third parameter controls whether any duplicate dependencies are overwritten or not.
193
-     *
194
-     * @param string $class
195
-     * @param array  $dependencies
196
-     * @param int    $overwrite
197
-     * @return bool
198
-     */
199
-    public function registerDependencies(
200
-        $class,
201
-        array $dependencies,
202
-        $overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
203
-    ) {
204
-        $class = trim($class, '\\');
205
-        $registered = false;
206
-        if (empty(self::$_instance->_dependency_map[ $class ])) {
207
-            self::$_instance->_dependency_map[ $class ] = array();
208
-        }
209
-        // we need to make sure that any aliases used when registering a dependency
210
-        // get resolved to the correct class name
211
-        foreach ($dependencies as $dependency => $load_source) {
212
-            $alias = self::$_instance->getFqnForAlias($dependency);
213
-            if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
-                || ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
215
-            ) {
216
-                unset($dependencies[ $dependency ]);
217
-                $dependencies[ $alias ] = $load_source;
218
-                $registered = true;
219
-            }
220
-        }
221
-        // now add our two lists of dependencies together.
222
-        // using Union (+=) favours the arrays in precedence from left to right,
223
-        // so $dependencies is NOT overwritten because it is listed first
224
-        // ie: with A = B + C, entries in B take precedence over duplicate entries in C
225
-        // Union is way faster than array_merge() but should be used with caution...
226
-        // especially with numerically indexed arrays
227
-        $dependencies += self::$_instance->_dependency_map[ $class ];
228
-        // now we need to ensure that the resulting dependencies
229
-        // array only has the entries that are required for the class
230
-        // so first count how many dependencies were originally registered for the class
231
-        $dependency_count = count(self::$_instance->_dependency_map[ $class ]);
232
-        // if that count is non-zero (meaning dependencies were already registered)
233
-        self::$_instance->_dependency_map[ $class ] = $dependency_count
234
-            // then truncate the  final array to match that count
235
-            ? array_slice($dependencies, 0, $dependency_count)
236
-            // otherwise just take the incoming array because nothing previously existed
237
-            : $dependencies;
238
-        return $registered;
239
-    }
240
-
241
-
242
-    /**
243
-     * @param string $class_name
244
-     * @param string $loader
245
-     * @return bool
246
-     * @throws DomainException
247
-     */
248
-    public static function register_class_loader($class_name, $loader = 'load_core')
249
-    {
250
-        if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251
-            throw new DomainException(
252
-                esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253
-            );
254
-        }
255
-        // check that loader is callable or method starts with "load_" and exists in EE_Registry
256
-        if (! is_callable($loader)
257
-            && (
258
-                strpos($loader, 'load_') !== 0
259
-                || ! method_exists('EE_Registry', $loader)
260
-            )
261
-        ) {
262
-            throw new DomainException(
263
-                sprintf(
264
-                    esc_html__(
265
-                        '"%1$s" is not a valid loader method on EE_Registry.',
266
-                        'event_espresso'
267
-                    ),
268
-                    $loader
269
-                )
270
-            );
271
-        }
272
-        $class_name = self::$_instance->getFqnForAlias($class_name);
273
-        if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
-            self::$_instance->_class_loaders[ $class_name ] = $loader;
275
-            return true;
276
-        }
277
-        return false;
278
-    }
279
-
280
-
281
-    /**
282
-     * @return array
283
-     */
284
-    public function dependency_map()
285
-    {
286
-        return $this->_dependency_map;
287
-    }
288
-
289
-
290
-    /**
291
-     * returns TRUE if dependency map contains a listing for the provided class name
292
-     *
293
-     * @param string $class_name
294
-     * @return boolean
295
-     */
296
-    public function has($class_name = '')
297
-    {
298
-        // all legacy models have the same dependencies
299
-        if (strpos($class_name, 'EEM_') === 0) {
300
-            $class_name = 'LEGACY_MODELS';
301
-        }
302
-        return isset($this->_dependency_map[ $class_name ]) ? true : false;
303
-    }
304
-
305
-
306
-    /**
307
-     * returns TRUE if dependency map contains a listing for the provided class name AND dependency
308
-     *
309
-     * @param string $class_name
310
-     * @param string $dependency
311
-     * @return bool
312
-     */
313
-    public function has_dependency_for_class($class_name = '', $dependency = '')
314
-    {
315
-        // all legacy models have the same dependencies
316
-        if (strpos($class_name, 'EEM_') === 0) {
317
-            $class_name = 'LEGACY_MODELS';
318
-        }
319
-        $dependency = $this->getFqnForAlias($dependency, $class_name);
320
-        return isset($this->_dependency_map[ $class_name ][ $dependency ])
321
-            ? true
322
-            : false;
323
-    }
324
-
325
-
326
-    /**
327
-     * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
328
-     *
329
-     * @param string $class_name
330
-     * @param string $dependency
331
-     * @return int
332
-     */
333
-    public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
334
-    {
335
-        // all legacy models have the same dependencies
336
-        if (strpos($class_name, 'EEM_') === 0) {
337
-            $class_name = 'LEGACY_MODELS';
338
-        }
339
-        $dependency = $this->getFqnForAlias($dependency);
340
-        return $this->has_dependency_for_class($class_name, $dependency)
341
-            ? $this->_dependency_map[ $class_name ][ $dependency ]
342
-            : EE_Dependency_Map::not_registered;
343
-    }
344
-
345
-
346
-    /**
347
-     * @param string $class_name
348
-     * @return string | Closure
349
-     */
350
-    public function class_loader($class_name)
351
-    {
352
-        // all legacy models use load_model()
353
-        if (strpos($class_name, 'EEM_') === 0) {
354
-            return 'load_model';
355
-        }
356
-        $class_name = $this->getFqnForAlias($class_name);
357
-        return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
358
-    }
359
-
360
-
361
-    /**
362
-     * @return array
363
-     */
364
-    public function class_loaders()
365
-    {
366
-        return $this->_class_loaders;
367
-    }
368
-
369
-
370
-    /**
371
-     * adds an alias for a classname
372
-     *
373
-     * @param string $fqcn      the class name that should be used (concrete class to replace interface)
374
-     * @param string $alias     the class name that would be type hinted for (abstract parent or interface)
375
-     * @param string $for_class the class that has the dependency (is type hinting for the interface)
376
-     */
377
-    public function add_alias($fqcn, $alias, $for_class = '')
378
-    {
379
-        $this->class_cache->addAlias($fqcn, $alias, $for_class);
380
-    }
381
-
382
-
383
-    /**
384
-     * Returns TRUE if the provided fully qualified name IS an alias
385
-     * WHY?
386
-     * Because if a class is type hinting for a concretion,
387
-     * then why would we need to find another class to supply it?
388
-     * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
389
-     * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
390
-     * Don't go looking for some substitute.
391
-     * Whereas if a class is type hinting for an interface...
392
-     * then we need to find an actual class to use.
393
-     * So the interface IS the alias for some other FQN,
394
-     * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
395
-     * represents some other class.
396
-     *
397
-     * @param string $fqn
398
-     * @param string $for_class
399
-     * @return bool
400
-     */
401
-    public function isAlias($fqn = '', $for_class = '')
402
-    {
403
-        return $this->class_cache->isAlias($fqn, $for_class);
404
-    }
405
-
406
-
407
-    /**
408
-     * Returns a FQN for provided alias if one exists, otherwise returns the original $alias
409
-     * functions recursively, so that multiple aliases can be used to drill down to a FQN
410
-     *  for example:
411
-     *      if the following two entries were added to the _aliases array:
412
-     *          array(
413
-     *              'interface_alias'           => 'some\namespace\interface'
414
-     *              'some\namespace\interface'  => 'some\namespace\classname'
415
-     *          )
416
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
417
-     *      to load an instance of 'some\namespace\classname'
418
-     *
419
-     * @param string $alias
420
-     * @param string $for_class
421
-     * @return string
422
-     */
423
-    public function getFqnForAlias($alias = '', $for_class = '')
424
-    {
425
-        return (string) $this->class_cache->getFqnForAlias($alias, $for_class);
426
-    }
427
-
428
-
429
-    /**
430
-     * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
431
-     * if one exists, or whether a new object should be generated every time the requested class is loaded.
432
-     * This is done by using the following class constants:
433
-     *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
434
-     *        EE_Dependency_Map::load_new_object - generates a new object every time
435
-     */
436
-    protected function _register_core_dependencies()
437
-    {
438
-        $this->_dependency_map = array(
439
-            'EE_Request_Handler'                                                                                          => array(
440
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
441
-            ),
442
-            'EE_System'                                                                                                   => array(
443
-                'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
444
-                'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
445
-                'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
446
-                'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
447
-            ),
448
-            'EE_Session'                                                                                                  => array(
449
-                'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
450
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
451
-                'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
452
-                'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
453
-            ),
454
-            'EE_Cart'                                                                                                     => array(
455
-                'EE_Session' => EE_Dependency_Map::load_from_cache,
456
-            ),
457
-            'EE_Front_Controller'                                                                                         => array(
458
-                'EE_Registry'              => EE_Dependency_Map::load_from_cache,
459
-                'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
460
-                'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
461
-            ),
462
-            'EE_Messenger_Collection_Loader'                                                                              => array(
463
-                'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
464
-            ),
465
-            'EE_Message_Type_Collection_Loader'                                                                           => array(
466
-                'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
467
-            ),
468
-            'EE_Message_Resource_Manager'                                                                                 => array(
469
-                'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
470
-                'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
471
-                'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
472
-            ),
473
-            'EE_Message_Factory'                                                                                          => array(
474
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
475
-            ),
476
-            'EE_messages'                                                                                                 => array(
477
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
478
-            ),
479
-            'EE_Messages_Generator'                                                                                       => array(
480
-                'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
481
-                'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
482
-                'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
483
-                'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
484
-            ),
485
-            'EE_Messages_Processor'                                                                                       => array(
486
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
487
-            ),
488
-            'EE_Messages_Queue'                                                                                           => array(
489
-                'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
490
-            ),
491
-            'EE_Messages_Template_Defaults'                                                                               => array(
492
-                'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
493
-                'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
494
-            ),
495
-            'EE_Message_To_Generate_From_Request'                                                                         => array(
496
-                'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
497
-                'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
498
-            ),
499
-            'EventEspresso\core\services\commands\CommandBus'                                                             => array(
500
-                'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
501
-            ),
502
-            'EventEspresso\services\commands\CommandHandler'                                                              => array(
503
-                'EE_Registry'         => EE_Dependency_Map::load_from_cache,
504
-                'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
505
-            ),
506
-            'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
507
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
508
-            ),
509
-            'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
510
-                'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
511
-                'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
512
-            ),
513
-            'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
514
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
515
-            ),
516
-            'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
517
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
518
-            ),
519
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
520
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
521
-            ),
522
-            'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
523
-                'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
524
-            ),
525
-            'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
526
-                'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
527
-            ),
528
-            'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
529
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
530
-            ),
531
-            'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
532
-                'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
533
-            ),
534
-            'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
535
-                'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
536
-            ),
537
-            'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
538
-                'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
539
-            ),
540
-            'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
541
-                'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
542
-            ),
543
-            'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
544
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
545
-            ),
546
-            'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
547
-                'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
548
-            ),
549
-            'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
550
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
551
-            ),
552
-            'EventEspresso\core\services\database\TableManager'                                                           => array(
553
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
554
-            ),
555
-            'EE_Data_Migration_Class_Base'                                                                                => array(
556
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
557
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
558
-            ),
559
-            'EE_DMS_Core_4_1_0'                                                                                           => array(
560
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
561
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
562
-            ),
563
-            'EE_DMS_Core_4_2_0'                                                                                           => array(
564
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
565
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
566
-            ),
567
-            'EE_DMS_Core_4_3_0'                                                                                           => array(
568
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
569
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
570
-            ),
571
-            'EE_DMS_Core_4_4_0'                                                                                           => array(
572
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
573
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
574
-            ),
575
-            'EE_DMS_Core_4_5_0'                                                                                           => array(
576
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
577
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
578
-            ),
579
-            'EE_DMS_Core_4_6_0'                                                                                           => array(
580
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
581
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
582
-            ),
583
-            'EE_DMS_Core_4_7_0'                                                                                           => array(
584
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
585
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
586
-            ),
587
-            'EE_DMS_Core_4_8_0'                                                                                           => array(
588
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
589
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
590
-            ),
591
-            'EE_DMS_Core_4_9_0'                                                                                           => array(
592
-                'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
593
-                'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
594
-            ),
595
-            'EventEspresso\core\services\assets\I18nRegistry'                                                             => array(
596
-                array(),
597
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
598
-            ),
599
-            'EventEspresso\core\services\assets\Registry'                                                                 => array(
600
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
601
-                'EventEspresso\core\services\assets\I18nRegistry'    => EE_Dependency_Map::load_from_cache,
602
-            ),
603
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
604
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
605
-            ),
606
-            'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
607
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
608
-            ),
609
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
610
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
611
-            ),
612
-            'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
613
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
614
-            ),
615
-            'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
616
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
617
-            ),
618
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
619
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
620
-            ),
621
-            'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
622
-                'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
623
-            ),
624
-            'EventEspresso\core\services\cache\BasicCacheManager'                                                         => array(
625
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
626
-            ),
627
-            'EventEspresso\core\services\cache\PostRelatedCacheManager'                                                   => array(
628
-                'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
629
-            ),
630
-            'EventEspresso\core\domain\services\validation\email\EmailValidationService'                                  => array(
631
-                'EE_Registration_Config'                     => EE_Dependency_Map::load_from_cache,
632
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
633
-            ),
634
-            'EventEspresso\core\domain\values\EmailAddress'                                                               => array(
635
-                null,
636
-                'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
637
-            ),
638
-            'EventEspresso\core\services\orm\ModelFieldFactory'                                                           => array(
639
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
640
-            ),
641
-            'LEGACY_MODELS'                                                                                               => array(
642
-                null,
643
-                'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
644
-            ),
645
-            'EE_Module_Request_Router'                                                                                    => array(
646
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
647
-            ),
648
-            'EE_Registration_Processor'                                                                                   => array(
649
-                'EE_Request' => EE_Dependency_Map::load_from_cache,
650
-            ),
651
-            'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'                                      => array(
652
-                null,
653
-                'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
654
-                'EE_Request'                                                          => EE_Dependency_Map::load_from_cache,
655
-            ),
656
-            'EventEspresso\core\services\licensing\LicenseService'                                                        => array(
657
-                'EventEspresso\core\domain\services\pue\Stats'  => EE_Dependency_Map::load_from_cache,
658
-                'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
659
-            ),
660
-            'EE_Admin_Transactions_List_Table'                                                                            => array(
661
-                null,
662
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
663
-            ),
664
-            'EventEspresso\core\domain\services\pue\Stats'                                                                => array(
665
-                'EventEspresso\core\domain\services\pue\Config'        => EE_Dependency_Map::load_from_cache,
666
-                'EE_Maintenance_Mode'                                  => EE_Dependency_Map::load_from_cache,
667
-                'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache,
668
-            ),
669
-            'EventEspresso\core\domain\services\pue\Config'                                                               => array(
670
-                'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
671
-                'EE_Config'         => EE_Dependency_Map::load_from_cache,
672
-            ),
673
-            'EventEspresso\core\domain\services\pue\StatsGatherer'                                                        => array(
674
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
675
-                'EEM_Event'          => EE_Dependency_Map::load_from_cache,
676
-                'EEM_Datetime'       => EE_Dependency_Map::load_from_cache,
677
-                'EEM_Ticket'         => EE_Dependency_Map::load_from_cache,
678
-                'EEM_Registration'   => EE_Dependency_Map::load_from_cache,
679
-                'EEM_Transaction'    => EE_Dependency_Map::load_from_cache,
680
-                'EE_Config'          => EE_Dependency_Map::load_from_cache,
681
-            ),
682
-            'EventEspresso\core\domain\services\admin\ExitModal'                                                          => array(
683
-                'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache,
684
-            ),
685
-            'EventEspresso\core\domain\services\admin\PluginUpsells'                                                      => array(
686
-                'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
687
-            ),
688
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha'                                    => array(
689
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
690
-                'EE_Session'             => EE_Dependency_Map::load_from_cache,
691
-            ),
692
-            'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings'                                => array(
693
-                'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
694
-            ),
695
-            'EventEspresso\modules\ticket_selector\ProcessTicketSelector'                                                 => array(
696
-                'EE_Core_Config'                                                          => EE_Dependency_Map::load_from_cache,
697
-                'EventEspresso\core\services\request\Request'                             => EE_Dependency_Map::load_from_cache,
698
-                'EE_Session'                                                              => EE_Dependency_Map::load_from_cache,
699
-                'EEM_Ticket'                                                              => EE_Dependency_Map::load_from_cache,
700
-                'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
701
-            ),
702
-            'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker'                                     => array(
703
-                'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
704
-            ),
705
-            'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'                              => array(
706
-                'EE_Core_Config'                             => EE_Dependency_Map::load_from_cache,
707
-                'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
708
-            ),
709
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'                                => array(
710
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
711
-            ),
712
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'                               => array(
713
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
714
-            ),
715
-            'EE_CPT_Strategy'                                                                                             => array(
716
-                'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
717
-                'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
718
-            ),
719
-            'EventEspresso\core\services\loaders\ObjectIdentifier'                                                        => array(
720
-                'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
721
-            ),
722
-            'EventEspresso\core\domain\services\assets\CoreAssetManager'                                                  => array(
723
-                'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
724
-                'EE_Currency_Config'                                 => EE_Dependency_Map::load_from_cache,
725
-                'EE_Template_Config'                                 => EE_Dependency_Map::load_from_cache,
726
-                'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
727
-                'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
728
-            ),
729
-            'EventEspresso\core\domain\services\admin\privacy\policy\PrivacyPolicy' => array(
730
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
731
-                'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache
732
-            ),
733
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendee' => array(
734
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
735
-            ),
736
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendeeBillingData' => array(
737
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
738
-                'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache
739
-            ),
740
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportCheckins' => array(
741
-                'EEM_Checkin' => EE_Dependency_Map::load_from_cache,
742
-            ),
743
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportRegistration' => array(
744
-                'EEM_Registration' => EE_Dependency_Map::load_from_cache,
745
-            ),
746
-            'EventEspresso\core\domain\services\admin\privacy\export\ExportTransaction' => array(
747
-                'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
748
-            ),
749
-            'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAttendeeData' => array(
750
-                'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
751
-            ),
752
-            'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAnswers' => array(
753
-                'EEM_Answer' => EE_Dependency_Map::load_from_cache,
754
-                'EEM_Question' => EE_Dependency_Map::load_from_cache,
755
-            ),
756
-            'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler' => array(
757
-                'EE_Registry' => EE_Dependency_Map::load_from_cache,
758
-                'EE_Config' => EE_Dependency_Map::load_from_cache
759
-            )
760
-        );
761
-    }
762
-
763
-
764
-    /**
765
-     * Registers how core classes are loaded.
766
-     * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
767
-     *        'EE_Request_Handler' => 'load_core'
768
-     *        'EE_Messages_Queue'  => 'load_lib'
769
-     *        'EEH_Debug_Tools'    => 'load_helper'
770
-     * or, if greater control is required, by providing a custom closure. For example:
771
-     *        'Some_Class' => function () {
772
-     *            return new Some_Class();
773
-     *        },
774
-     * This is required for instantiating dependencies
775
-     * where an interface has been type hinted in a class constructor. For example:
776
-     *        'Required_Interface' => function () {
777
-     *            return new A_Class_That_Implements_Required_Interface();
778
-     *        },
779
-     */
780
-    protected function _register_core_class_loaders()
781
-    {
782
-        // for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
783
-        // be used in a closure.
784
-        $request = &$this->request;
785
-        $response = &$this->response;
786
-        $legacy_request = &$this->legacy_request;
787
-        // $loader = &$this->loader;
788
-        $this->_class_loaders = array(
789
-            // load_core
790
-            'EE_Capabilities'                              => 'load_core',
791
-            'EE_Encryption'                                => 'load_core',
792
-            'EE_Front_Controller'                          => 'load_core',
793
-            'EE_Module_Request_Router'                     => 'load_core',
794
-            'EE_Registry'                                  => 'load_core',
795
-            'EE_Request'                                   => function () use (&$legacy_request) {
796
-                return $legacy_request;
797
-            },
798
-            'EventEspresso\core\services\request\Request'  => function () use (&$request) {
799
-                return $request;
800
-            },
801
-            'EventEspresso\core\services\request\Response' => function () use (&$response) {
802
-                return $response;
803
-            },
804
-            'EE_Base'                                      => 'load_core',
805
-            'EE_Request_Handler'                           => 'load_core',
806
-            'EE_Session'                                   => 'load_core',
807
-            'EE_Cron_Tasks'                                => 'load_core',
808
-            'EE_System'                                    => 'load_core',
809
-            'EE_Maintenance_Mode'                          => 'load_core',
810
-            'EE_Register_CPTs'                             => 'load_core',
811
-            'EE_Admin'                                     => 'load_core',
812
-            'EE_CPT_Strategy'                              => 'load_core',
813
-            // load_lib
814
-            'EE_Message_Resource_Manager'                  => 'load_lib',
815
-            'EE_Message_Type_Collection'                   => 'load_lib',
816
-            'EE_Message_Type_Collection_Loader'            => 'load_lib',
817
-            'EE_Messenger_Collection'                      => 'load_lib',
818
-            'EE_Messenger_Collection_Loader'               => 'load_lib',
819
-            'EE_Messages_Processor'                        => 'load_lib',
820
-            'EE_Message_Repository'                        => 'load_lib',
821
-            'EE_Messages_Queue'                            => 'load_lib',
822
-            'EE_Messages_Data_Handler_Collection'          => 'load_lib',
823
-            'EE_Message_Template_Group_Collection'         => 'load_lib',
824
-            'EE_Payment_Method_Manager'                    => 'load_lib',
825
-            'EE_Messages_Generator'                        => function () {
826
-                return EE_Registry::instance()->load_lib(
827
-                    'Messages_Generator',
828
-                    array(),
829
-                    false,
830
-                    false
831
-                );
832
-            },
833
-            'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
834
-                return EE_Registry::instance()->load_lib(
835
-                    'Messages_Template_Defaults',
836
-                    $arguments,
837
-                    false,
838
-                    false
839
-                );
840
-            },
841
-            // load_helper
842
-            'EEH_Parse_Shortcodes'                         => function () {
843
-                if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
844
-                    return new EEH_Parse_Shortcodes();
845
-                }
846
-                return null;
847
-            },
848
-            'EE_Template_Config'                           => function () {
849
-                return EE_Config::instance()->template_settings;
850
-            },
851
-            'EE_Currency_Config'                           => function () {
852
-                return EE_Config::instance()->currency;
853
-            },
854
-            'EE_Registration_Config'                       => function () {
855
-                return EE_Config::instance()->registration;
856
-            },
857
-            'EE_Core_Config'                               => function () {
858
-                return EE_Config::instance()->core;
859
-            },
860
-            'EventEspresso\core\services\loaders\Loader'   => function () {
861
-                return LoaderFactory::getLoader();
862
-            },
863
-            'EE_Network_Config'                            => function () {
864
-                return EE_Network_Config::instance();
865
-            },
866
-            'EE_Config'                                    => function () {
867
-                return EE_Config::instance();
868
-            },
869
-            'EventEspresso\core\domain\Domain'             => function () {
870
-                return DomainFactory::getEventEspressoCoreDomain();
871
-            },
872
-            'EE_Admin_Config'                              => function () {
873
-                return EE_Config::instance()->admin;
874
-            }
875
-        );
876
-    }
877
-
878
-
879
-    /**
880
-     * can be used for supplying alternate names for classes,
881
-     * or for connecting interface names to instantiable classes
882
-     */
883
-    protected function _register_core_aliases()
884
-    {
885
-        $aliases = array(
886
-            'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
887
-            'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
888
-            'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
889
-            'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
890
-            'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
891
-            'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
892
-            'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
893
-            'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
894
-            'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
895
-            'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
896
-            'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
897
-            'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
898
-            'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
899
-            'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
900
-            'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
901
-            'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
902
-            'CreateTransactionCommandHandler'                                              => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
903
-            'CreateAttendeeCommandHandler'                                                 => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
904
-            'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
905
-            'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
906
-            'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
907
-            'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
908
-            'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
909
-            'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
910
-            'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
911
-            'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
912
-            'CommandFactoryInterface'                                                      => 'EventEspresso\core\services\commands\CommandFactoryInterface',
913
-            'EventEspresso\core\services\commands\CommandFactoryInterface'                 => 'EventEspresso\core\services\commands\CommandFactory',
914
-            'EventEspresso\core\domain\services\session\SessionIdentifierInterface'        => 'EE_Session',
915
-            'EmailValidatorInterface'                                                      => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
916
-            'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface'  => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
917
-            'NoticeConverterInterface'                                                     => 'EventEspresso\core\services\notices\NoticeConverterInterface',
918
-            'EventEspresso\core\services\notices\NoticeConverterInterface'                 => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
919
-            'NoticesContainerInterface'                                                    => 'EventEspresso\core\services\notices\NoticesContainerInterface',
920
-            'EventEspresso\core\services\notices\NoticesContainerInterface'                => 'EventEspresso\core\services\notices\NoticesContainer',
921
-            'EventEspresso\core\services\request\RequestInterface'                         => 'EventEspresso\core\services\request\Request',
922
-            'EventEspresso\core\services\request\ResponseInterface'                        => 'EventEspresso\core\services\request\Response',
923
-            'EventEspresso\core\domain\DomainInterface'                                    => 'EventEspresso\core\domain\Domain',
924
-        );
925
-        foreach ($aliases as $alias => $fqn) {
926
-            if (is_array($fqn)) {
927
-                foreach ($fqn as $class => $for_class) {
928
-                    $this->class_cache->addAlias($class, $alias, $for_class);
929
-                }
930
-                continue;
931
-            }
932
-            $this->class_cache->addAlias($fqn, $alias);
933
-        }
934
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
935
-            $this->class_cache->addAlias(
936
-                'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
937
-                'EventEspresso\core\services\notices\NoticeConverterInterface'
938
-            );
939
-        }
940
-    }
941
-
942
-
943
-    /**
944
-     * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
945
-     * request Primarily used by unit tests.
946
-     */
947
-    public function reset()
948
-    {
949
-        $this->_register_core_class_loaders();
950
-        $this->_register_core_dependencies();
951
-    }
952
-
953
-
954
-    /**
955
-     * PLZ NOTE: a better name for this method would be is_alias()
956
-     * because it returns TRUE if the provided fully qualified name IS an alias
957
-     * WHY?
958
-     * Because if a class is type hinting for a concretion,
959
-     * then why would we need to find another class to supply it?
960
-     * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
961
-     * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
962
-     * Don't go looking for some substitute.
963
-     * Whereas if a class is type hinting for an interface...
964
-     * then we need to find an actual class to use.
965
-     * So the interface IS the alias for some other FQN,
966
-     * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
967
-     * represents some other class.
968
-     *
969
-     * @deprecated 4.9.62.p
970
-     * @param string $fqn
971
-     * @param string $for_class
972
-     * @return bool
973
-     */
974
-    public function has_alias($fqn = '', $for_class = '')
975
-    {
976
-        return $this->isAlias($fqn, $for_class);
977
-    }
978
-
979
-
980
-    /**
981
-     * PLZ NOTE: a better name for this method would be get_fqn_for_alias()
982
-     * because it returns a FQN for provided alias if one exists, otherwise returns the original $alias
983
-     * functions recursively, so that multiple aliases can be used to drill down to a FQN
984
-     *  for example:
985
-     *      if the following two entries were added to the _aliases array:
986
-     *          array(
987
-     *              'interface_alias'           => 'some\namespace\interface'
988
-     *              'some\namespace\interface'  => 'some\namespace\classname'
989
-     *          )
990
-     *      then one could use EE_Registry::instance()->create( 'interface_alias' )
991
-     *      to load an instance of 'some\namespace\classname'
992
-     *
993
-     * @deprecated 4.9.62.p
994
-     * @param string $alias
995
-     * @param string $for_class
996
-     * @return string
997
-     */
998
-    public function get_alias($alias = '', $for_class = '')
999
-    {
1000
-        return $this->getFqnForAlias($alias, $for_class);
1001
-    }
23
+	/**
24
+	 * This means that the requested class dependency is not present in the dependency map
25
+	 */
26
+	const not_registered = 0;
27
+
28
+	/**
29
+	 * This instructs class loaders to ALWAYS return a newly instantiated object for the requested class.
30
+	 */
31
+	const load_new_object = 1;
32
+
33
+	/**
34
+	 * This instructs class loaders to return a previously instantiated and cached object for the requested class.
35
+	 * IF a previously instantiated object does not exist, a new one will be created and added to the cache.
36
+	 */
37
+	const load_from_cache = 2;
38
+
39
+	/**
40
+	 * When registering a dependency,
41
+	 * this indicates to keep any existing dependencies that already exist,
42
+	 * and simply discard any new dependencies declared in the incoming data
43
+	 */
44
+	const KEEP_EXISTING_DEPENDENCIES = 0;
45
+
46
+	/**
47
+	 * When registering a dependency,
48
+	 * this indicates to overwrite any existing dependencies that already exist using the incoming data
49
+	 */
50
+	const OVERWRITE_DEPENDENCIES = 1;
51
+
52
+
53
+	/**
54
+	 * @type EE_Dependency_Map $_instance
55
+	 */
56
+	protected static $_instance;
57
+
58
+	/**
59
+	 * @var ClassInterfaceCache $class_cache
60
+	 */
61
+	private $class_cache;
62
+
63
+	/**
64
+	 * @type RequestInterface $request
65
+	 */
66
+	protected $request;
67
+
68
+	/**
69
+	 * @type LegacyRequestInterface $legacy_request
70
+	 */
71
+	protected $legacy_request;
72
+
73
+	/**
74
+	 * @type ResponseInterface $response
75
+	 */
76
+	protected $response;
77
+
78
+	/**
79
+	 * @type LoaderInterface $loader
80
+	 */
81
+	protected $loader;
82
+
83
+	/**
84
+	 * @type array $_dependency_map
85
+	 */
86
+	protected $_dependency_map = array();
87
+
88
+	/**
89
+	 * @type array $_class_loaders
90
+	 */
91
+	protected $_class_loaders = array();
92
+
93
+
94
+	/**
95
+	 * EE_Dependency_Map constructor.
96
+	 *
97
+	 * @param ClassInterfaceCache $class_cache
98
+	 */
99
+	protected function __construct(ClassInterfaceCache $class_cache)
100
+	{
101
+		$this->class_cache = $class_cache;
102
+		do_action('EE_Dependency_Map____construct', $this);
103
+	}
104
+
105
+
106
+	/**
107
+	 * @return void
108
+	 */
109
+	public function initialize()
110
+	{
111
+		$this->_register_core_dependencies();
112
+		$this->_register_core_class_loaders();
113
+		$this->_register_core_aliases();
114
+	}
115
+
116
+
117
+	/**
118
+	 * @singleton method used to instantiate class object
119
+	 * @param ClassInterfaceCache|null $class_cache
120
+	 * @return EE_Dependency_Map
121
+	 */
122
+	public static function instance(ClassInterfaceCache $class_cache = null)
123
+	{
124
+		// check if class object is instantiated, and instantiated properly
125
+		if (! self::$_instance instanceof EE_Dependency_Map
126
+			&& $class_cache instanceof ClassInterfaceCache
127
+		) {
128
+			self::$_instance = new EE_Dependency_Map($class_cache);
129
+		}
130
+		return self::$_instance;
131
+	}
132
+
133
+
134
+	/**
135
+	 * @param RequestInterface $request
136
+	 */
137
+	public function setRequest(RequestInterface $request)
138
+	{
139
+		$this->request = $request;
140
+	}
141
+
142
+
143
+	/**
144
+	 * @param LegacyRequestInterface $legacy_request
145
+	 */
146
+	public function setLegacyRequest(LegacyRequestInterface $legacy_request)
147
+	{
148
+		$this->legacy_request = $legacy_request;
149
+	}
150
+
151
+
152
+	/**
153
+	 * @param ResponseInterface $response
154
+	 */
155
+	public function setResponse(ResponseInterface $response)
156
+	{
157
+		$this->response = $response;
158
+	}
159
+
160
+
161
+	/**
162
+	 * @param LoaderInterface $loader
163
+	 */
164
+	public function setLoader(LoaderInterface $loader)
165
+	{
166
+		$this->loader = $loader;
167
+	}
168
+
169
+
170
+	/**
171
+	 * @param string $class
172
+	 * @param array  $dependencies
173
+	 * @param int    $overwrite
174
+	 * @return bool
175
+	 */
176
+	public static function register_dependencies(
177
+		$class,
178
+		array $dependencies,
179
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
180
+	) {
181
+		return self::$_instance->registerDependencies($class, $dependencies, $overwrite);
182
+	}
183
+
184
+
185
+	/**
186
+	 * Assigns an array of class names and corresponding load sources (new or cached)
187
+	 * to the class specified by the first parameter.
188
+	 * IMPORTANT !!!
189
+	 * The order of elements in the incoming $dependencies array MUST match
190
+	 * the order of the constructor parameters for the class in question.
191
+	 * This is especially important when overriding any existing dependencies that are registered.
192
+	 * the third parameter controls whether any duplicate dependencies are overwritten or not.
193
+	 *
194
+	 * @param string $class
195
+	 * @param array  $dependencies
196
+	 * @param int    $overwrite
197
+	 * @return bool
198
+	 */
199
+	public function registerDependencies(
200
+		$class,
201
+		array $dependencies,
202
+		$overwrite = EE_Dependency_Map::KEEP_EXISTING_DEPENDENCIES
203
+	) {
204
+		$class = trim($class, '\\');
205
+		$registered = false;
206
+		if (empty(self::$_instance->_dependency_map[ $class ])) {
207
+			self::$_instance->_dependency_map[ $class ] = array();
208
+		}
209
+		// we need to make sure that any aliases used when registering a dependency
210
+		// get resolved to the correct class name
211
+		foreach ($dependencies as $dependency => $load_source) {
212
+			$alias = self::$_instance->getFqnForAlias($dependency);
213
+			if ($overwrite === EE_Dependency_Map::OVERWRITE_DEPENDENCIES
214
+				|| ! isset(self::$_instance->_dependency_map[ $class ][ $alias ])
215
+			) {
216
+				unset($dependencies[ $dependency ]);
217
+				$dependencies[ $alias ] = $load_source;
218
+				$registered = true;
219
+			}
220
+		}
221
+		// now add our two lists of dependencies together.
222
+		// using Union (+=) favours the arrays in precedence from left to right,
223
+		// so $dependencies is NOT overwritten because it is listed first
224
+		// ie: with A = B + C, entries in B take precedence over duplicate entries in C
225
+		// Union is way faster than array_merge() but should be used with caution...
226
+		// especially with numerically indexed arrays
227
+		$dependencies += self::$_instance->_dependency_map[ $class ];
228
+		// now we need to ensure that the resulting dependencies
229
+		// array only has the entries that are required for the class
230
+		// so first count how many dependencies were originally registered for the class
231
+		$dependency_count = count(self::$_instance->_dependency_map[ $class ]);
232
+		// if that count is non-zero (meaning dependencies were already registered)
233
+		self::$_instance->_dependency_map[ $class ] = $dependency_count
234
+			// then truncate the  final array to match that count
235
+			? array_slice($dependencies, 0, $dependency_count)
236
+			// otherwise just take the incoming array because nothing previously existed
237
+			: $dependencies;
238
+		return $registered;
239
+	}
240
+
241
+
242
+	/**
243
+	 * @param string $class_name
244
+	 * @param string $loader
245
+	 * @return bool
246
+	 * @throws DomainException
247
+	 */
248
+	public static function register_class_loader($class_name, $loader = 'load_core')
249
+	{
250
+		if (! $loader instanceof Closure && strpos($class_name, '\\') !== false) {
251
+			throw new DomainException(
252
+				esc_html__('Don\'t use class loaders for FQCNs.', 'event_espresso')
253
+			);
254
+		}
255
+		// check that loader is callable or method starts with "load_" and exists in EE_Registry
256
+		if (! is_callable($loader)
257
+			&& (
258
+				strpos($loader, 'load_') !== 0
259
+				|| ! method_exists('EE_Registry', $loader)
260
+			)
261
+		) {
262
+			throw new DomainException(
263
+				sprintf(
264
+					esc_html__(
265
+						'"%1$s" is not a valid loader method on EE_Registry.',
266
+						'event_espresso'
267
+					),
268
+					$loader
269
+				)
270
+			);
271
+		}
272
+		$class_name = self::$_instance->getFqnForAlias($class_name);
273
+		if (! isset(self::$_instance->_class_loaders[ $class_name ])) {
274
+			self::$_instance->_class_loaders[ $class_name ] = $loader;
275
+			return true;
276
+		}
277
+		return false;
278
+	}
279
+
280
+
281
+	/**
282
+	 * @return array
283
+	 */
284
+	public function dependency_map()
285
+	{
286
+		return $this->_dependency_map;
287
+	}
288
+
289
+
290
+	/**
291
+	 * returns TRUE if dependency map contains a listing for the provided class name
292
+	 *
293
+	 * @param string $class_name
294
+	 * @return boolean
295
+	 */
296
+	public function has($class_name = '')
297
+	{
298
+		// all legacy models have the same dependencies
299
+		if (strpos($class_name, 'EEM_') === 0) {
300
+			$class_name = 'LEGACY_MODELS';
301
+		}
302
+		return isset($this->_dependency_map[ $class_name ]) ? true : false;
303
+	}
304
+
305
+
306
+	/**
307
+	 * returns TRUE if dependency map contains a listing for the provided class name AND dependency
308
+	 *
309
+	 * @param string $class_name
310
+	 * @param string $dependency
311
+	 * @return bool
312
+	 */
313
+	public function has_dependency_for_class($class_name = '', $dependency = '')
314
+	{
315
+		// all legacy models have the same dependencies
316
+		if (strpos($class_name, 'EEM_') === 0) {
317
+			$class_name = 'LEGACY_MODELS';
318
+		}
319
+		$dependency = $this->getFqnForAlias($dependency, $class_name);
320
+		return isset($this->_dependency_map[ $class_name ][ $dependency ])
321
+			? true
322
+			: false;
323
+	}
324
+
325
+
326
+	/**
327
+	 * returns loading strategy for whether a previously cached dependency should be loaded or a new instance returned
328
+	 *
329
+	 * @param string $class_name
330
+	 * @param string $dependency
331
+	 * @return int
332
+	 */
333
+	public function loading_strategy_for_class_dependency($class_name = '', $dependency = '')
334
+	{
335
+		// all legacy models have the same dependencies
336
+		if (strpos($class_name, 'EEM_') === 0) {
337
+			$class_name = 'LEGACY_MODELS';
338
+		}
339
+		$dependency = $this->getFqnForAlias($dependency);
340
+		return $this->has_dependency_for_class($class_name, $dependency)
341
+			? $this->_dependency_map[ $class_name ][ $dependency ]
342
+			: EE_Dependency_Map::not_registered;
343
+	}
344
+
345
+
346
+	/**
347
+	 * @param string $class_name
348
+	 * @return string | Closure
349
+	 */
350
+	public function class_loader($class_name)
351
+	{
352
+		// all legacy models use load_model()
353
+		if (strpos($class_name, 'EEM_') === 0) {
354
+			return 'load_model';
355
+		}
356
+		$class_name = $this->getFqnForAlias($class_name);
357
+		return isset($this->_class_loaders[ $class_name ]) ? $this->_class_loaders[ $class_name ] : '';
358
+	}
359
+
360
+
361
+	/**
362
+	 * @return array
363
+	 */
364
+	public function class_loaders()
365
+	{
366
+		return $this->_class_loaders;
367
+	}
368
+
369
+
370
+	/**
371
+	 * adds an alias for a classname
372
+	 *
373
+	 * @param string $fqcn      the class name that should be used (concrete class to replace interface)
374
+	 * @param string $alias     the class name that would be type hinted for (abstract parent or interface)
375
+	 * @param string $for_class the class that has the dependency (is type hinting for the interface)
376
+	 */
377
+	public function add_alias($fqcn, $alias, $for_class = '')
378
+	{
379
+		$this->class_cache->addAlias($fqcn, $alias, $for_class);
380
+	}
381
+
382
+
383
+	/**
384
+	 * Returns TRUE if the provided fully qualified name IS an alias
385
+	 * WHY?
386
+	 * Because if a class is type hinting for a concretion,
387
+	 * then why would we need to find another class to supply it?
388
+	 * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
389
+	 * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
390
+	 * Don't go looking for some substitute.
391
+	 * Whereas if a class is type hinting for an interface...
392
+	 * then we need to find an actual class to use.
393
+	 * So the interface IS the alias for some other FQN,
394
+	 * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
395
+	 * represents some other class.
396
+	 *
397
+	 * @param string $fqn
398
+	 * @param string $for_class
399
+	 * @return bool
400
+	 */
401
+	public function isAlias($fqn = '', $for_class = '')
402
+	{
403
+		return $this->class_cache->isAlias($fqn, $for_class);
404
+	}
405
+
406
+
407
+	/**
408
+	 * Returns a FQN for provided alias if one exists, otherwise returns the original $alias
409
+	 * functions recursively, so that multiple aliases can be used to drill down to a FQN
410
+	 *  for example:
411
+	 *      if the following two entries were added to the _aliases array:
412
+	 *          array(
413
+	 *              'interface_alias'           => 'some\namespace\interface'
414
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
415
+	 *          )
416
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
417
+	 *      to load an instance of 'some\namespace\classname'
418
+	 *
419
+	 * @param string $alias
420
+	 * @param string $for_class
421
+	 * @return string
422
+	 */
423
+	public function getFqnForAlias($alias = '', $for_class = '')
424
+	{
425
+		return (string) $this->class_cache->getFqnForAlias($alias, $for_class);
426
+	}
427
+
428
+
429
+	/**
430
+	 * Registers the core dependencies and whether a previously instantiated object should be loaded from the cache,
431
+	 * if one exists, or whether a new object should be generated every time the requested class is loaded.
432
+	 * This is done by using the following class constants:
433
+	 *        EE_Dependency_Map::load_from_cache - loads previously instantiated object
434
+	 *        EE_Dependency_Map::load_new_object - generates a new object every time
435
+	 */
436
+	protected function _register_core_dependencies()
437
+	{
438
+		$this->_dependency_map = array(
439
+			'EE_Request_Handler'                                                                                          => array(
440
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
441
+			),
442
+			'EE_System'                                                                                                   => array(
443
+				'EE_Registry'                                 => EE_Dependency_Map::load_from_cache,
444
+				'EventEspresso\core\services\loaders\Loader'  => EE_Dependency_Map::load_from_cache,
445
+				'EventEspresso\core\services\request\Request' => EE_Dependency_Map::load_from_cache,
446
+				'EE_Maintenance_Mode'                         => EE_Dependency_Map::load_from_cache,
447
+			),
448
+			'EE_Session'                                                                                                  => array(
449
+				'EventEspresso\core\services\cache\TransientCacheStorage'  => EE_Dependency_Map::load_from_cache,
450
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
451
+				'EventEspresso\core\services\request\Request'              => EE_Dependency_Map::load_from_cache,
452
+				'EE_Encryption'                                            => EE_Dependency_Map::load_from_cache,
453
+			),
454
+			'EE_Cart'                                                                                                     => array(
455
+				'EE_Session' => EE_Dependency_Map::load_from_cache,
456
+			),
457
+			'EE_Front_Controller'                                                                                         => array(
458
+				'EE_Registry'              => EE_Dependency_Map::load_from_cache,
459
+				'EE_Request_Handler'       => EE_Dependency_Map::load_from_cache,
460
+				'EE_Module_Request_Router' => EE_Dependency_Map::load_from_cache,
461
+			),
462
+			'EE_Messenger_Collection_Loader'                                                                              => array(
463
+				'EE_Messenger_Collection' => EE_Dependency_Map::load_new_object,
464
+			),
465
+			'EE_Message_Type_Collection_Loader'                                                                           => array(
466
+				'EE_Message_Type_Collection' => EE_Dependency_Map::load_new_object,
467
+			),
468
+			'EE_Message_Resource_Manager'                                                                                 => array(
469
+				'EE_Messenger_Collection_Loader'    => EE_Dependency_Map::load_new_object,
470
+				'EE_Message_Type_Collection_Loader' => EE_Dependency_Map::load_new_object,
471
+				'EEM_Message_Template_Group'        => EE_Dependency_Map::load_from_cache,
472
+			),
473
+			'EE_Message_Factory'                                                                                          => array(
474
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
475
+			),
476
+			'EE_messages'                                                                                                 => array(
477
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
478
+			),
479
+			'EE_Messages_Generator'                                                                                       => array(
480
+				'EE_Messages_Queue'                    => EE_Dependency_Map::load_new_object,
481
+				'EE_Messages_Data_Handler_Collection'  => EE_Dependency_Map::load_new_object,
482
+				'EE_Message_Template_Group_Collection' => EE_Dependency_Map::load_new_object,
483
+				'EEH_Parse_Shortcodes'                 => EE_Dependency_Map::load_from_cache,
484
+			),
485
+			'EE_Messages_Processor'                                                                                       => array(
486
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
487
+			),
488
+			'EE_Messages_Queue'                                                                                           => array(
489
+				'EE_Message_Repository' => EE_Dependency_Map::load_new_object,
490
+			),
491
+			'EE_Messages_Template_Defaults'                                                                               => array(
492
+				'EEM_Message_Template_Group' => EE_Dependency_Map::load_from_cache,
493
+				'EEM_Message_Template'       => EE_Dependency_Map::load_from_cache,
494
+			),
495
+			'EE_Message_To_Generate_From_Request'                                                                         => array(
496
+				'EE_Message_Resource_Manager' => EE_Dependency_Map::load_from_cache,
497
+				'EE_Request_Handler'          => EE_Dependency_Map::load_from_cache,
498
+			),
499
+			'EventEspresso\core\services\commands\CommandBus'                                                             => array(
500
+				'EventEspresso\core\services\commands\CommandHandlerManager' => EE_Dependency_Map::load_from_cache,
501
+			),
502
+			'EventEspresso\services\commands\CommandHandler'                                                              => array(
503
+				'EE_Registry'         => EE_Dependency_Map::load_from_cache,
504
+				'CommandBusInterface' => EE_Dependency_Map::load_from_cache,
505
+			),
506
+			'EventEspresso\core\services\commands\CommandHandlerManager'                                                  => array(
507
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
508
+			),
509
+			'EventEspresso\core\services\commands\CompositeCommandHandler'                                                => array(
510
+				'EventEspresso\core\services\commands\CommandBus'     => EE_Dependency_Map::load_from_cache,
511
+				'EventEspresso\core\services\commands\CommandFactory' => EE_Dependency_Map::load_from_cache,
512
+			),
513
+			'EventEspresso\core\services\commands\CommandFactory'                                                         => array(
514
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
515
+			),
516
+			'EventEspresso\core\services\commands\middleware\CapChecker'                                                  => array(
517
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
518
+			),
519
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker'                                         => array(
520
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
521
+			),
522
+			'EventEspresso\core\domain\services\capabilities\RegistrationsCapChecker'                                     => array(
523
+				'EE_Capabilities' => EE_Dependency_Map::load_from_cache,
524
+			),
525
+			'EventEspresso\core\services\commands\registration\CreateRegistrationCommandHandler'                          => array(
526
+				'EventEspresso\core\domain\services\registration\CreateRegistrationService' => EE_Dependency_Map::load_from_cache,
527
+			),
528
+			'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommandHandler'                     => array(
529
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
530
+			),
531
+			'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommandHandler'                    => array(
532
+				'EventEspresso\core\domain\services\registration\CopyRegistrationService' => EE_Dependency_Map::load_from_cache,
533
+			),
534
+			'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler'         => array(
535
+				'EventEspresso\core\domain\services\registration\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
536
+			),
537
+			'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler' => array(
538
+				'EventEspresso\core\domain\services\registration\UpdateRegistrationService' => EE_Dependency_Map::load_from_cache,
539
+			),
540
+			'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommandHandler'                              => array(
541
+				'EventEspresso\core\domain\services\ticket\CreateTicketLineItemService' => EE_Dependency_Map::load_from_cache,
542
+			),
543
+			'EventEspresso\core\services\commands\ticket\CancelTicketLineItemCommandHandler'                              => array(
544
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
545
+			),
546
+			'EventEspresso\core\domain\services\registration\CancelRegistrationService'                                   => array(
547
+				'EventEspresso\core\domain\services\ticket\CancelTicketLineItemService' => EE_Dependency_Map::load_from_cache,
548
+			),
549
+			'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler'                                  => array(
550
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
551
+			),
552
+			'EventEspresso\core\services\database\TableManager'                                                           => array(
553
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
554
+			),
555
+			'EE_Data_Migration_Class_Base'                                                                                => array(
556
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
557
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
558
+			),
559
+			'EE_DMS_Core_4_1_0'                                                                                           => array(
560
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
561
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
562
+			),
563
+			'EE_DMS_Core_4_2_0'                                                                                           => array(
564
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
565
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
566
+			),
567
+			'EE_DMS_Core_4_3_0'                                                                                           => array(
568
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
569
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
570
+			),
571
+			'EE_DMS_Core_4_4_0'                                                                                           => array(
572
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
573
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
574
+			),
575
+			'EE_DMS_Core_4_5_0'                                                                                           => array(
576
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
577
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
578
+			),
579
+			'EE_DMS_Core_4_6_0'                                                                                           => array(
580
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
581
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
582
+			),
583
+			'EE_DMS_Core_4_7_0'                                                                                           => array(
584
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
585
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
586
+			),
587
+			'EE_DMS_Core_4_8_0'                                                                                           => array(
588
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
589
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
590
+			),
591
+			'EE_DMS_Core_4_9_0'                                                                                           => array(
592
+				'EventEspresso\core\services\database\TableAnalysis' => EE_Dependency_Map::load_from_cache,
593
+				'EventEspresso\core\services\database\TableManager'  => EE_Dependency_Map::load_from_cache,
594
+			),
595
+			'EventEspresso\core\services\assets\I18nRegistry'                                                             => array(
596
+				array(),
597
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
598
+			),
599
+			'EventEspresso\core\services\assets\Registry'                                                                 => array(
600
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
601
+				'EventEspresso\core\services\assets\I18nRegistry'    => EE_Dependency_Map::load_from_cache,
602
+			),
603
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCancelled'                                             => array(
604
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
605
+			),
606
+			'EventEspresso\core\domain\entities\shortcodes\EspressoCheckout'                                              => array(
607
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
608
+			),
609
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEventAttendees'                                        => array(
610
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
611
+			),
612
+			'EventEspresso\core\domain\entities\shortcodes\EspressoEvents'                                                => array(
613
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
614
+			),
615
+			'EventEspresso\core\domain\entities\shortcodes\EspressoThankYou'                                              => array(
616
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
617
+			),
618
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTicketSelector'                                        => array(
619
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
620
+			),
621
+			'EventEspresso\core\domain\entities\shortcodes\EspressoTxnPage'                                               => array(
622
+				'EventEspresso\core\services\cache\PostRelatedCacheManager' => EE_Dependency_Map::load_from_cache,
623
+			),
624
+			'EventEspresso\core\services\cache\BasicCacheManager'                                                         => array(
625
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
626
+			),
627
+			'EventEspresso\core\services\cache\PostRelatedCacheManager'                                                   => array(
628
+				'EventEspresso\core\services\cache\TransientCacheStorage' => EE_Dependency_Map::load_from_cache,
629
+			),
630
+			'EventEspresso\core\domain\services\validation\email\EmailValidationService'                                  => array(
631
+				'EE_Registration_Config'                     => EE_Dependency_Map::load_from_cache,
632
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
633
+			),
634
+			'EventEspresso\core\domain\values\EmailAddress'                                                               => array(
635
+				null,
636
+				'EventEspresso\core\domain\services\validation\email\EmailValidationService' => EE_Dependency_Map::load_from_cache,
637
+			),
638
+			'EventEspresso\core\services\orm\ModelFieldFactory'                                                           => array(
639
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
640
+			),
641
+			'LEGACY_MODELS'                                                                                               => array(
642
+				null,
643
+				'EventEspresso\core\services\database\ModelFieldFactory' => EE_Dependency_Map::load_from_cache,
644
+			),
645
+			'EE_Module_Request_Router'                                                                                    => array(
646
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
647
+			),
648
+			'EE_Registration_Processor'                                                                                   => array(
649
+				'EE_Request' => EE_Dependency_Map::load_from_cache,
650
+			),
651
+			'EventEspresso\core\services\notifications\PersistentAdminNoticeManager'                                      => array(
652
+				null,
653
+				'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker' => EE_Dependency_Map::load_from_cache,
654
+				'EE_Request'                                                          => EE_Dependency_Map::load_from_cache,
655
+			),
656
+			'EventEspresso\core\services\licensing\LicenseService'                                                        => array(
657
+				'EventEspresso\core\domain\services\pue\Stats'  => EE_Dependency_Map::load_from_cache,
658
+				'EventEspresso\core\domain\services\pue\Config' => EE_Dependency_Map::load_from_cache,
659
+			),
660
+			'EE_Admin_Transactions_List_Table'                                                                            => array(
661
+				null,
662
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache,
663
+			),
664
+			'EventEspresso\core\domain\services\pue\Stats'                                                                => array(
665
+				'EventEspresso\core\domain\services\pue\Config'        => EE_Dependency_Map::load_from_cache,
666
+				'EE_Maintenance_Mode'                                  => EE_Dependency_Map::load_from_cache,
667
+				'EventEspresso\core\domain\services\pue\StatsGatherer' => EE_Dependency_Map::load_from_cache,
668
+			),
669
+			'EventEspresso\core\domain\services\pue\Config'                                                               => array(
670
+				'EE_Network_Config' => EE_Dependency_Map::load_from_cache,
671
+				'EE_Config'         => EE_Dependency_Map::load_from_cache,
672
+			),
673
+			'EventEspresso\core\domain\services\pue\StatsGatherer'                                                        => array(
674
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
675
+				'EEM_Event'          => EE_Dependency_Map::load_from_cache,
676
+				'EEM_Datetime'       => EE_Dependency_Map::load_from_cache,
677
+				'EEM_Ticket'         => EE_Dependency_Map::load_from_cache,
678
+				'EEM_Registration'   => EE_Dependency_Map::load_from_cache,
679
+				'EEM_Transaction'    => EE_Dependency_Map::load_from_cache,
680
+				'EE_Config'          => EE_Dependency_Map::load_from_cache,
681
+			),
682
+			'EventEspresso\core\domain\services\admin\ExitModal'                                                          => array(
683
+				'EventEspresso\core\services\assets\Registry' => EE_Dependency_Map::load_from_cache,
684
+			),
685
+			'EventEspresso\core\domain\services\admin\PluginUpsells'                                                      => array(
686
+				'EventEspresso\core\domain\Domain' => EE_Dependency_Map::load_from_cache,
687
+			),
688
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\InvisibleRecaptcha'                                    => array(
689
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
690
+				'EE_Session'             => EE_Dependency_Map::load_from_cache,
691
+			),
692
+			'EventEspresso\caffeinated\modules\recaptcha_invisible\RecaptchaAdminSettings'                                => array(
693
+				'EE_Registration_Config' => EE_Dependency_Map::load_from_cache,
694
+			),
695
+			'EventEspresso\modules\ticket_selector\ProcessTicketSelector'                                                 => array(
696
+				'EE_Core_Config'                                                          => EE_Dependency_Map::load_from_cache,
697
+				'EventEspresso\core\services\request\Request'                             => EE_Dependency_Map::load_from_cache,
698
+				'EE_Session'                                                              => EE_Dependency_Map::load_from_cache,
699
+				'EEM_Ticket'                                                              => EE_Dependency_Map::load_from_cache,
700
+				'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker' => EE_Dependency_Map::load_from_cache,
701
+			),
702
+			'EventEspresso\modules\ticket_selector\TicketDatetimeAvailabilityTracker'                                     => array(
703
+				'EEM_Datetime' => EE_Dependency_Map::load_from_cache,
704
+			),
705
+			'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions'                              => array(
706
+				'EE_Core_Config'                             => EE_Dependency_Map::load_from_cache,
707
+				'EventEspresso\core\services\loaders\Loader' => EE_Dependency_Map::load_from_cache,
708
+			),
709
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'                                => array(
710
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
711
+			),
712
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'                               => array(
713
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
714
+			),
715
+			'EE_CPT_Strategy'                                                                                             => array(
716
+				'EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions' => EE_Dependency_Map::load_from_cache,
717
+				'EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions' => EE_Dependency_Map::load_from_cache,
718
+			),
719
+			'EventEspresso\core\services\loaders\ObjectIdentifier'                                                        => array(
720
+				'EventEspresso\core\services\loaders\ClassInterfaceCache' => EE_Dependency_Map::load_from_cache,
721
+			),
722
+			'EventEspresso\core\domain\services\assets\CoreAssetManager'                                                  => array(
723
+				'EventEspresso\core\services\assets\AssetCollection' => EE_Dependency_Map::load_from_cache,
724
+				'EE_Currency_Config'                                 => EE_Dependency_Map::load_from_cache,
725
+				'EE_Template_Config'                                 => EE_Dependency_Map::load_from_cache,
726
+				'EventEspresso\core\domain\Domain'                   => EE_Dependency_Map::load_from_cache,
727
+				'EventEspresso\core\services\assets\Registry'        => EE_Dependency_Map::load_from_cache,
728
+			),
729
+			'EventEspresso\core\domain\services\admin\privacy\policy\PrivacyPolicy' => array(
730
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache,
731
+				'EventEspresso\core\domain\values\session\SessionLifespan' => EE_Dependency_Map::load_from_cache
732
+			),
733
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendee' => array(
734
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
735
+			),
736
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportAttendeeBillingData' => array(
737
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
738
+				'EEM_Payment_Method' => EE_Dependency_Map::load_from_cache
739
+			),
740
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportCheckins' => array(
741
+				'EEM_Checkin' => EE_Dependency_Map::load_from_cache,
742
+			),
743
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportRegistration' => array(
744
+				'EEM_Registration' => EE_Dependency_Map::load_from_cache,
745
+			),
746
+			'EventEspresso\core\domain\services\admin\privacy\export\ExportTransaction' => array(
747
+				'EEM_Transaction' => EE_Dependency_Map::load_from_cache,
748
+			),
749
+			'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAttendeeData' => array(
750
+				'EEM_Attendee' => EE_Dependency_Map::load_from_cache,
751
+			),
752
+			'EventEspresso\core\domain\services\admin\privacy\erasure\EraseAnswers' => array(
753
+				'EEM_Answer' => EE_Dependency_Map::load_from_cache,
754
+				'EEM_Question' => EE_Dependency_Map::load_from_cache,
755
+			),
756
+			'EventEspresso\core\domain\services\admin\privacy\forms\PrivacySettingsFormHandler' => array(
757
+				'EE_Registry' => EE_Dependency_Map::load_from_cache,
758
+				'EE_Config' => EE_Dependency_Map::load_from_cache
759
+			)
760
+		);
761
+	}
762
+
763
+
764
+	/**
765
+	 * Registers how core classes are loaded.
766
+	 * This can either be done by simply providing the name of one of the EE_Registry loader methods such as:
767
+	 *        'EE_Request_Handler' => 'load_core'
768
+	 *        'EE_Messages_Queue'  => 'load_lib'
769
+	 *        'EEH_Debug_Tools'    => 'load_helper'
770
+	 * or, if greater control is required, by providing a custom closure. For example:
771
+	 *        'Some_Class' => function () {
772
+	 *            return new Some_Class();
773
+	 *        },
774
+	 * This is required for instantiating dependencies
775
+	 * where an interface has been type hinted in a class constructor. For example:
776
+	 *        'Required_Interface' => function () {
777
+	 *            return new A_Class_That_Implements_Required_Interface();
778
+	 *        },
779
+	 */
780
+	protected function _register_core_class_loaders()
781
+	{
782
+		// for PHP5.3 compat, we need to register any properties called here in a variable because `$this` cannot
783
+		// be used in a closure.
784
+		$request = &$this->request;
785
+		$response = &$this->response;
786
+		$legacy_request = &$this->legacy_request;
787
+		// $loader = &$this->loader;
788
+		$this->_class_loaders = array(
789
+			// load_core
790
+			'EE_Capabilities'                              => 'load_core',
791
+			'EE_Encryption'                                => 'load_core',
792
+			'EE_Front_Controller'                          => 'load_core',
793
+			'EE_Module_Request_Router'                     => 'load_core',
794
+			'EE_Registry'                                  => 'load_core',
795
+			'EE_Request'                                   => function () use (&$legacy_request) {
796
+				return $legacy_request;
797
+			},
798
+			'EventEspresso\core\services\request\Request'  => function () use (&$request) {
799
+				return $request;
800
+			},
801
+			'EventEspresso\core\services\request\Response' => function () use (&$response) {
802
+				return $response;
803
+			},
804
+			'EE_Base'                                      => 'load_core',
805
+			'EE_Request_Handler'                           => 'load_core',
806
+			'EE_Session'                                   => 'load_core',
807
+			'EE_Cron_Tasks'                                => 'load_core',
808
+			'EE_System'                                    => 'load_core',
809
+			'EE_Maintenance_Mode'                          => 'load_core',
810
+			'EE_Register_CPTs'                             => 'load_core',
811
+			'EE_Admin'                                     => 'load_core',
812
+			'EE_CPT_Strategy'                              => 'load_core',
813
+			// load_lib
814
+			'EE_Message_Resource_Manager'                  => 'load_lib',
815
+			'EE_Message_Type_Collection'                   => 'load_lib',
816
+			'EE_Message_Type_Collection_Loader'            => 'load_lib',
817
+			'EE_Messenger_Collection'                      => 'load_lib',
818
+			'EE_Messenger_Collection_Loader'               => 'load_lib',
819
+			'EE_Messages_Processor'                        => 'load_lib',
820
+			'EE_Message_Repository'                        => 'load_lib',
821
+			'EE_Messages_Queue'                            => 'load_lib',
822
+			'EE_Messages_Data_Handler_Collection'          => 'load_lib',
823
+			'EE_Message_Template_Group_Collection'         => 'load_lib',
824
+			'EE_Payment_Method_Manager'                    => 'load_lib',
825
+			'EE_Messages_Generator'                        => function () {
826
+				return EE_Registry::instance()->load_lib(
827
+					'Messages_Generator',
828
+					array(),
829
+					false,
830
+					false
831
+				);
832
+			},
833
+			'EE_Messages_Template_Defaults'                => function ($arguments = array()) {
834
+				return EE_Registry::instance()->load_lib(
835
+					'Messages_Template_Defaults',
836
+					$arguments,
837
+					false,
838
+					false
839
+				);
840
+			},
841
+			// load_helper
842
+			'EEH_Parse_Shortcodes'                         => function () {
843
+				if (EE_Registry::instance()->load_helper('Parse_Shortcodes')) {
844
+					return new EEH_Parse_Shortcodes();
845
+				}
846
+				return null;
847
+			},
848
+			'EE_Template_Config'                           => function () {
849
+				return EE_Config::instance()->template_settings;
850
+			},
851
+			'EE_Currency_Config'                           => function () {
852
+				return EE_Config::instance()->currency;
853
+			},
854
+			'EE_Registration_Config'                       => function () {
855
+				return EE_Config::instance()->registration;
856
+			},
857
+			'EE_Core_Config'                               => function () {
858
+				return EE_Config::instance()->core;
859
+			},
860
+			'EventEspresso\core\services\loaders\Loader'   => function () {
861
+				return LoaderFactory::getLoader();
862
+			},
863
+			'EE_Network_Config'                            => function () {
864
+				return EE_Network_Config::instance();
865
+			},
866
+			'EE_Config'                                    => function () {
867
+				return EE_Config::instance();
868
+			},
869
+			'EventEspresso\core\domain\Domain'             => function () {
870
+				return DomainFactory::getEventEspressoCoreDomain();
871
+			},
872
+			'EE_Admin_Config'                              => function () {
873
+				return EE_Config::instance()->admin;
874
+			}
875
+		);
876
+	}
877
+
878
+
879
+	/**
880
+	 * can be used for supplying alternate names for classes,
881
+	 * or for connecting interface names to instantiable classes
882
+	 */
883
+	protected function _register_core_aliases()
884
+	{
885
+		$aliases = array(
886
+			'CommandBusInterface'                                                          => 'EventEspresso\core\services\commands\CommandBusInterface',
887
+			'EventEspresso\core\services\commands\CommandBusInterface'                     => 'EventEspresso\core\services\commands\CommandBus',
888
+			'CommandHandlerManagerInterface'                                               => 'EventEspresso\core\services\commands\CommandHandlerManagerInterface',
889
+			'EventEspresso\core\services\commands\CommandHandlerManagerInterface'          => 'EventEspresso\core\services\commands\CommandHandlerManager',
890
+			'CapChecker'                                                                   => 'EventEspresso\core\services\commands\middleware\CapChecker',
891
+			'AddActionHook'                                                                => 'EventEspresso\core\services\commands\middleware\AddActionHook',
892
+			'CapabilitiesChecker'                                                          => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
893
+			'CapabilitiesCheckerInterface'                                                 => 'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface',
894
+			'EventEspresso\core\domain\services\capabilities\CapabilitiesCheckerInterface' => 'EventEspresso\core\domain\services\capabilities\CapabilitiesChecker',
895
+			'CreateRegistrationService'                                                    => 'EventEspresso\core\domain\services\registration\CreateRegistrationService',
896
+			'CreateRegistrationCommandHandler'                                             => 'EventEspresso\core\services\commands\registration\CreateRegistrationCommand',
897
+			'CopyRegistrationDetailsCommandHandler'                                        => 'EventEspresso\core\services\commands\registration\CopyRegistrationDetailsCommand',
898
+			'CopyRegistrationPaymentsCommandHandler'                                       => 'EventEspresso\core\services\commands\registration\CopyRegistrationPaymentsCommand',
899
+			'CancelRegistrationAndTicketLineItemCommandHandler'                            => 'EventEspresso\core\services\commands\registration\CancelRegistrationAndTicketLineItemCommandHandler',
900
+			'UpdateRegistrationAndTransactionAfterChangeCommandHandler'                    => 'EventEspresso\core\services\commands\registration\UpdateRegistrationAndTransactionAfterChangeCommandHandler',
901
+			'CreateTicketLineItemCommandHandler'                                           => 'EventEspresso\core\services\commands\ticket\CreateTicketLineItemCommand',
902
+			'CreateTransactionCommandHandler'                                              => 'EventEspresso\core\services\commands\transaction\CreateTransactionCommandHandler',
903
+			'CreateAttendeeCommandHandler'                                                 => 'EventEspresso\core\services\commands\attendee\CreateAttendeeCommandHandler',
904
+			'TableManager'                                                                 => 'EventEspresso\core\services\database\TableManager',
905
+			'TableAnalysis'                                                                => 'EventEspresso\core\services\database\TableAnalysis',
906
+			'EspressoShortcode'                                                            => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
907
+			'ShortcodeInterface'                                                           => 'EventEspresso\core\services\shortcodes\ShortcodeInterface',
908
+			'EventEspresso\core\services\shortcodes\ShortcodeInterface'                    => 'EventEspresso\core\services\shortcodes\EspressoShortcode',
909
+			'EventEspresso\core\services\cache\CacheStorageInterface'                      => 'EventEspresso\core\services\cache\TransientCacheStorage',
910
+			'LoaderInterface'                                                              => 'EventEspresso\core\services\loaders\LoaderInterface',
911
+			'EventEspresso\core\services\loaders\LoaderInterface'                          => 'EventEspresso\core\services\loaders\Loader',
912
+			'CommandFactoryInterface'                                                      => 'EventEspresso\core\services\commands\CommandFactoryInterface',
913
+			'EventEspresso\core\services\commands\CommandFactoryInterface'                 => 'EventEspresso\core\services\commands\CommandFactory',
914
+			'EventEspresso\core\domain\services\session\SessionIdentifierInterface'        => 'EE_Session',
915
+			'EmailValidatorInterface'                                                      => 'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface',
916
+			'EventEspresso\core\domain\services\validation\email\EmailValidatorInterface'  => 'EventEspresso\core\domain\services\validation\email\EmailValidationService',
917
+			'NoticeConverterInterface'                                                     => 'EventEspresso\core\services\notices\NoticeConverterInterface',
918
+			'EventEspresso\core\services\notices\NoticeConverterInterface'                 => 'EventEspresso\core\services\notices\ConvertNoticesToEeErrors',
919
+			'NoticesContainerInterface'                                                    => 'EventEspresso\core\services\notices\NoticesContainerInterface',
920
+			'EventEspresso\core\services\notices\NoticesContainerInterface'                => 'EventEspresso\core\services\notices\NoticesContainer',
921
+			'EventEspresso\core\services\request\RequestInterface'                         => 'EventEspresso\core\services\request\Request',
922
+			'EventEspresso\core\services\request\ResponseInterface'                        => 'EventEspresso\core\services\request\Response',
923
+			'EventEspresso\core\domain\DomainInterface'                                    => 'EventEspresso\core\domain\Domain',
924
+		);
925
+		foreach ($aliases as $alias => $fqn) {
926
+			if (is_array($fqn)) {
927
+				foreach ($fqn as $class => $for_class) {
928
+					$this->class_cache->addAlias($class, $alias, $for_class);
929
+				}
930
+				continue;
931
+			}
932
+			$this->class_cache->addAlias($fqn, $alias);
933
+		}
934
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && is_admin()) {
935
+			$this->class_cache->addAlias(
936
+				'EventEspresso\core\services\notices\ConvertNoticesToAdminNotices',
937
+				'EventEspresso\core\services\notices\NoticeConverterInterface'
938
+			);
939
+		}
940
+	}
941
+
942
+
943
+	/**
944
+	 * This is used to reset the internal map and class_loaders to their original default state at the beginning of the
945
+	 * request Primarily used by unit tests.
946
+	 */
947
+	public function reset()
948
+	{
949
+		$this->_register_core_class_loaders();
950
+		$this->_register_core_dependencies();
951
+	}
952
+
953
+
954
+	/**
955
+	 * PLZ NOTE: a better name for this method would be is_alias()
956
+	 * because it returns TRUE if the provided fully qualified name IS an alias
957
+	 * WHY?
958
+	 * Because if a class is type hinting for a concretion,
959
+	 * then why would we need to find another class to supply it?
960
+	 * ie: if a class asks for `Fully/Qualified/Namespace/SpecificClassName`,
961
+	 * then give it an instance of `Fully/Qualified/Namespace/SpecificClassName`.
962
+	 * Don't go looking for some substitute.
963
+	 * Whereas if a class is type hinting for an interface...
964
+	 * then we need to find an actual class to use.
965
+	 * So the interface IS the alias for some other FQN,
966
+	 * and we need to find out if `Fully/Qualified/Namespace/SomeInterface`
967
+	 * represents some other class.
968
+	 *
969
+	 * @deprecated 4.9.62.p
970
+	 * @param string $fqn
971
+	 * @param string $for_class
972
+	 * @return bool
973
+	 */
974
+	public function has_alias($fqn = '', $for_class = '')
975
+	{
976
+		return $this->isAlias($fqn, $for_class);
977
+	}
978
+
979
+
980
+	/**
981
+	 * PLZ NOTE: a better name for this method would be get_fqn_for_alias()
982
+	 * because it returns a FQN for provided alias if one exists, otherwise returns the original $alias
983
+	 * functions recursively, so that multiple aliases can be used to drill down to a FQN
984
+	 *  for example:
985
+	 *      if the following two entries were added to the _aliases array:
986
+	 *          array(
987
+	 *              'interface_alias'           => 'some\namespace\interface'
988
+	 *              'some\namespace\interface'  => 'some\namespace\classname'
989
+	 *          )
990
+	 *      then one could use EE_Registry::instance()->create( 'interface_alias' )
991
+	 *      to load an instance of 'some\namespace\classname'
992
+	 *
993
+	 * @deprecated 4.9.62.p
994
+	 * @param string $alias
995
+	 * @param string $for_class
996
+	 * @return string
997
+	 */
998
+	public function get_alias($alias = '', $for_class = '')
999
+	{
1000
+		return $this->getFqnForAlias($alias, $for_class);
1001
+	}
1002 1002
 }
Please login to merge, or discard this patch.
core/libraries/plugin_api/EE_Register_CPT.lib.php 1 patch
Indentation   +230 added lines, -230 removed lines patch added patch discarded remove patch
@@ -13,257 +13,257 @@
 block discarded – undo
13 13
 class EE_Register_CPT implements EEI_Plugin_API
14 14
 {
15 15
 
16
-    /**
17
-     * Holds values for registered variations
18
-     *
19
-     * @since 4.5.0
20
-     *
21
-     * @var array[][][]
22
-     */
23
-    protected static $_registry = array();
16
+	/**
17
+	 * Holds values for registered variations
18
+	 *
19
+	 * @since 4.5.0
20
+	 *
21
+	 * @var array[][][]
22
+	 */
23
+	protected static $_registry = array();
24 24
 
25 25
 
26
-    /**
27
-     * Used to register new CPTs and Taxonomies.
28
-     *
29
-     * @param string $cpt_ref                 reference used for the addon registering cpts and cts
30
-     * @param array  $setup_args              {
31
-     *                                        An array of required values for registering the cpts and taxonomies
32
-     * @type array   $cpts                    {
33
-     *                                        An array of cpts and their arguments.(short example below)
34
-     * @see CustomPostTypeDefinitions::setDefinitions for a more complete example.
35
-     *                                        'people' => array(
36
-     *                                        'singular_name' => __('People', 'event_espresso'),
37
-     *                                        'plural_name' => __('People', 'event_espresso'),
38
-     *                                        'singular_slug' => __('people', 'event_espresso'),
39
-     *                                        'plural_slug' => __('peoples', 'event_espresso'),
40
-     *                                        'class_name' => 'EE_People'
41
-     *                                        )
42
-     *                                        },
43
-     * @type array   $cts                     {
44
-     *                                        An array of custom taxonomies and their arguments (short example below).
45
-     * @see CustomTaxonomyDefinitions::setTaxonomies() for a more complete example.
46
-     *                                        'espresso_people_type' => array(
47
-     *                                        'singular_name' => __('People Type', 'event_espresso'),
48
-     *                                        'plural_name' => __('People Types', 'event_espresso'),
49
-     *                                        'args' => array()
50
-     *                                        )
51
-     *                                        },
52
-     * @type array   $default_terms           {
53
-     *                                        An array of terms to set as the default for a given taxonomy and the
54
-     *                                        custom post types applied to.
55
-     *                                        'taxonomy_name' => array(
56
-     *                                        'term' => array( 'cpt_a_name', 'cpt_b_name' )
57
-     *                                        )
58
-     *                                        }
59
-     *                                        }
60
-     * @throws  EE_Error
61
-     * @return void
62
-     */
63
-    public static function register($cpt_ref = null, $setup_args = array())
64
-    {
26
+	/**
27
+	 * Used to register new CPTs and Taxonomies.
28
+	 *
29
+	 * @param string $cpt_ref                 reference used for the addon registering cpts and cts
30
+	 * @param array  $setup_args              {
31
+	 *                                        An array of required values for registering the cpts and taxonomies
32
+	 * @type array   $cpts                    {
33
+	 *                                        An array of cpts and their arguments.(short example below)
34
+	 * @see CustomPostTypeDefinitions::setDefinitions for a more complete example.
35
+	 *                                        'people' => array(
36
+	 *                                        'singular_name' => __('People', 'event_espresso'),
37
+	 *                                        'plural_name' => __('People', 'event_espresso'),
38
+	 *                                        'singular_slug' => __('people', 'event_espresso'),
39
+	 *                                        'plural_slug' => __('peoples', 'event_espresso'),
40
+	 *                                        'class_name' => 'EE_People'
41
+	 *                                        )
42
+	 *                                        },
43
+	 * @type array   $cts                     {
44
+	 *                                        An array of custom taxonomies and their arguments (short example below).
45
+	 * @see CustomTaxonomyDefinitions::setTaxonomies() for a more complete example.
46
+	 *                                        'espresso_people_type' => array(
47
+	 *                                        'singular_name' => __('People Type', 'event_espresso'),
48
+	 *                                        'plural_name' => __('People Types', 'event_espresso'),
49
+	 *                                        'args' => array()
50
+	 *                                        )
51
+	 *                                        },
52
+	 * @type array   $default_terms           {
53
+	 *                                        An array of terms to set as the default for a given taxonomy and the
54
+	 *                                        custom post types applied to.
55
+	 *                                        'taxonomy_name' => array(
56
+	 *                                        'term' => array( 'cpt_a_name', 'cpt_b_name' )
57
+	 *                                        )
58
+	 *                                        }
59
+	 *                                        }
60
+	 * @throws  EE_Error
61
+	 * @return void
62
+	 */
63
+	public static function register($cpt_ref = null, $setup_args = array())
64
+	{
65 65
 
66
-        // check for required params
67
-        if (empty($cpt_ref)) {
68
-            throw new EE_Error(
69
-                __(
70
-                    'In order to register custom post types and custom taxonomies, you must include a value to reference what had been registered',
71
-                    'event_espresso'
72
-                )
73
-            );
74
-        }
66
+		// check for required params
67
+		if (empty($cpt_ref)) {
68
+			throw new EE_Error(
69
+				__(
70
+					'In order to register custom post types and custom taxonomies, you must include a value to reference what had been registered',
71
+					'event_espresso'
72
+				)
73
+			);
74
+		}
75 75
 
76
-        if (! is_array($setup_args) || (empty($setup_args['cpts']) && empty($setup_args['cts']))) {
77
-            throw new EE_Error(
78
-                __(
79
-                    'In order to register custom post types or custom taxonomies, you must include an array containing either an array of custom post types to register (key "cpts"), an array of custom taxonomies ("cts") or both.',
80
-                    'event_espresso'
81
-                )
82
-            );
83
-        }
76
+		if (! is_array($setup_args) || (empty($setup_args['cpts']) && empty($setup_args['cts']))) {
77
+			throw new EE_Error(
78
+				__(
79
+					'In order to register custom post types or custom taxonomies, you must include an array containing either an array of custom post types to register (key "cpts"), an array of custom taxonomies ("cts") or both.',
80
+					'event_espresso'
81
+				)
82
+			);
83
+		}
84 84
 
85
-        // make sure we don't register twice
86
-        if (isset(self::$_registry[ $cpt_ref ])) {
87
-            return;
88
-        }
85
+		// make sure we don't register twice
86
+		if (isset(self::$_registry[ $cpt_ref ])) {
87
+			return;
88
+		}
89 89
 
90
-        // make sure cpt ref is unique.
91
-        if (isset(self::$_registry[ $cpt_ref ])) {
92
-            $cpt_ref = uniqid() . '_' . $cpt_ref;
93
-        }
90
+		// make sure cpt ref is unique.
91
+		if (isset(self::$_registry[ $cpt_ref ])) {
92
+			$cpt_ref = uniqid() . '_' . $cpt_ref;
93
+		}
94 94
 
95
-        // make sure this was called in the right place!
96
-        if (did_action('AHEE__EE_System__load_CPTs_and_session__complete')) {
97
-            EE_Error::doing_it_wrong(
98
-                __METHOD__,
99
-                sprintf(
100
-                    __(
101
-                        'EE_Register_CPT has been called and given a reference of "%s".  It may or may not work because it should be called on or before "AHEE__EE_System__load_CPTs_and_session__complete" action hook.',
102
-                        'event_espresso'
103
-                    ),
104
-                    $cpt_ref
105
-                ),
106
-                '4.5.0'
107
-            );
108
-        }
109
-        // validate incoming args
110
-        $validated = array(
111
-            'cpts'          => isset($setup_args['cpts'])
112
-                ? (array) $setup_args['cpts']
113
-                : array(),
114
-            'cts'           => isset($setup_args['cts'])
115
-                ? (array) $setup_args['cts']
116
-                : array(),
117
-            'default_terms' => isset($setup_args['default_terms'])
118
-                ? (array) $setup_args['default_terms']
119
-                : array(),
120
-        );
95
+		// make sure this was called in the right place!
96
+		if (did_action('AHEE__EE_System__load_CPTs_and_session__complete')) {
97
+			EE_Error::doing_it_wrong(
98
+				__METHOD__,
99
+				sprintf(
100
+					__(
101
+						'EE_Register_CPT has been called and given a reference of "%s".  It may or may not work because it should be called on or before "AHEE__EE_System__load_CPTs_and_session__complete" action hook.',
102
+						'event_espresso'
103
+					),
104
+					$cpt_ref
105
+				),
106
+				'4.5.0'
107
+			);
108
+		}
109
+		// validate incoming args
110
+		$validated = array(
111
+			'cpts'          => isset($setup_args['cpts'])
112
+				? (array) $setup_args['cpts']
113
+				: array(),
114
+			'cts'           => isset($setup_args['cts'])
115
+				? (array) $setup_args['cts']
116
+				: array(),
117
+			'default_terms' => isset($setup_args['default_terms'])
118
+				? (array) $setup_args['default_terms']
119
+				: array(),
120
+		);
121 121
 
122
-        self::$_registry[ $cpt_ref ] = $validated;
122
+		self::$_registry[ $cpt_ref ] = $validated;
123 123
 
124
-        // hook into to cpt system
125
-        add_filter(
126
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
127
-            array(__CLASS__, 'filterCustomPostTypeDefinitions'),
128
-            5
129
-        );
130
-        add_filter(
131
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
132
-            array(__CLASS__, 'filterCustomTaxonomyDefinitions'),
133
-            5
134
-        );
135
-        add_action(
136
-            'AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end',
137
-            array(__CLASS__, 'registerCustomTaxonomyTerm'),
138
-            5
139
-        );
140
-    }
124
+		// hook into to cpt system
125
+		add_filter(
126
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes',
127
+			array(__CLASS__, 'filterCustomPostTypeDefinitions'),
128
+			5
129
+		);
130
+		add_filter(
131
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
132
+			array(__CLASS__, 'filterCustomTaxonomyDefinitions'),
133
+			5
134
+		);
135
+		add_action(
136
+			'AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end',
137
+			array(__CLASS__, 'registerCustomTaxonomyTerm'),
138
+			5
139
+		);
140
+	}
141 141
 
142 142
 
143
-    /**
144
-     * Callback for
145
-     * FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes
146
-     * that adds additional custom post types to be registered.
147
-     *
148
-     * @param array $custom_post_type_definitions array of cpts that are already set
149
-     * @return array new array of cpts and their registration information
150
-     */
151
-    public static function filterCustomPostTypeDefinitions($custom_post_type_definitions)
152
-    {
153
-        foreach (self::$_registry as $registries) {
154
-            foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
155
-                $custom_post_type_definitions[ $cpt_name ] = $cpt_settings;
156
-            }
157
-        }
158
-        return $custom_post_type_definitions;
159
-    }
143
+	/**
144
+	 * Callback for
145
+	 * FHEE__EventEspresso_core_domain_entities_custom_post_types_CustomPostTypeDefinitions__getCustomPostTypes
146
+	 * that adds additional custom post types to be registered.
147
+	 *
148
+	 * @param array $custom_post_type_definitions array of cpts that are already set
149
+	 * @return array new array of cpts and their registration information
150
+	 */
151
+	public static function filterCustomPostTypeDefinitions($custom_post_type_definitions)
152
+	{
153
+		foreach (self::$_registry as $registries) {
154
+			foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
155
+				$custom_post_type_definitions[ $cpt_name ] = $cpt_settings;
156
+			}
157
+		}
158
+		return $custom_post_type_definitions;
159
+	}
160 160
 
161 161
 
162
-    /**
163
-     * Callback for
164
-     * FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies
165
-     * that adds additional custom taxonomies to be registered.
166
-     *
167
-     * @param array $custom_taxonomy_definitions array of cts that are already set.
168
-     * @return array new array of cts and their registration information.
169
-     */
170
-    public static function filterCustomTaxonomyDefinitions($custom_taxonomy_definitions)
171
-    {
172
-        foreach (self::$_registry as $registries) {
173
-            foreach ($registries['cts'] as $ct_name => $ct_settings) {
174
-                $custom_taxonomy_definitions[ $ct_name ] = $ct_settings;
175
-            }
176
-        }
177
-        return $custom_taxonomy_definitions;
178
-    }
162
+	/**
163
+	 * Callback for
164
+	 * FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies
165
+	 * that adds additional custom taxonomies to be registered.
166
+	 *
167
+	 * @param array $custom_taxonomy_definitions array of cts that are already set.
168
+	 * @return array new array of cts and their registration information.
169
+	 */
170
+	public static function filterCustomTaxonomyDefinitions($custom_taxonomy_definitions)
171
+	{
172
+		foreach (self::$_registry as $registries) {
173
+			foreach ($registries['cts'] as $ct_name => $ct_settings) {
174
+				$custom_taxonomy_definitions[ $ct_name ] = $ct_settings;
175
+			}
176
+		}
177
+		return $custom_taxonomy_definitions;
178
+	}
179 179
 
180 180
 
181
-    /**
182
-     * Callback for
183
-     * AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end
184
-     * which is used to set the default terms
185
-     *
186
-     * @param RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms
187
-     * @return void
188
-     */
189
-    public static function registerCustomTaxonomyTerm(RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms)
190
-    {
191
-        foreach (self::$_registry as $registries) {
192
-            foreach ($registries['default_terms'] as $taxonomy => $terms) {
193
-                foreach ($terms as $term => $cpts) {
194
-                    $register_custom_taxonomy_terms->registerCustomTaxonomyTerm(
195
-                        $taxonomy,
196
-                        $term,
197
-                        $cpts
198
-                    );
199
-                }
200
-            }
201
-        }
202
-    }
181
+	/**
182
+	 * Callback for
183
+	 * AHEE__EventEspresso_core_domain_services_custom_post_types_RegisterCustomTaxonomyTerms__construct_end
184
+	 * which is used to set the default terms
185
+	 *
186
+	 * @param RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms
187
+	 * @return void
188
+	 */
189
+	public static function registerCustomTaxonomyTerm(RegisterCustomTaxonomyTerms $register_custom_taxonomy_terms)
190
+	{
191
+		foreach (self::$_registry as $registries) {
192
+			foreach ($registries['default_terms'] as $taxonomy => $terms) {
193
+				foreach ($terms as $term => $cpts) {
194
+					$register_custom_taxonomy_terms->registerCustomTaxonomyTerm(
195
+						$taxonomy,
196
+						$term,
197
+						$cpts
198
+					);
199
+				}
200
+			}
201
+		}
202
+	}
203 203
 
204 204
 
205
-    /**
206
-     * @deprecated 4.9.62.p
207
-     * @param array $cpts array of cpts that are already set
208
-     * @return array new array of cpts and their registration information
209
-     */
210
-    public static function filter_cpts($cpts)
211
-    {
212
-        foreach (self::$_registry as $registries) {
213
-            foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
214
-                $cpts[ $cpt_name ] = $cpt_settings;
215
-            }
216
-        }
217
-        return $cpts;
218
-    }
205
+	/**
206
+	 * @deprecated 4.9.62.p
207
+	 * @param array $cpts array of cpts that are already set
208
+	 * @return array new array of cpts and their registration information
209
+	 */
210
+	public static function filter_cpts($cpts)
211
+	{
212
+		foreach (self::$_registry as $registries) {
213
+			foreach ($registries['cpts'] as $cpt_name => $cpt_settings) {
214
+				$cpts[ $cpt_name ] = $cpt_settings;
215
+			}
216
+		}
217
+		return $cpts;
218
+	}
219 219
 
220 220
 
221
-    /**
222
-     * @deprecated 4.9.62.p
223
-     * @param array $cts array of cts that are already set.
224
-     * @return array new array of cts and their registration information.
225
-     */
226
-    public static function filter_cts($cts)
227
-    {
228
-        foreach (self::$_registry as $registries) {
229
-            foreach ($registries['cts'] as $ct_name => $ct_settings) {
230
-                $cts[ $ct_name ] = $ct_settings;
231
-            }
232
-        }
233
-        return $cts;
234
-    }
221
+	/**
222
+	 * @deprecated 4.9.62.p
223
+	 * @param array $cts array of cts that are already set.
224
+	 * @return array new array of cts and their registration information.
225
+	 */
226
+	public static function filter_cts($cts)
227
+	{
228
+		foreach (self::$_registry as $registries) {
229
+			foreach ($registries['cts'] as $ct_name => $ct_settings) {
230
+				$cts[ $ct_name ] = $ct_settings;
231
+			}
232
+		}
233
+		return $cts;
234
+	}
235 235
 
236 236
 
237
-    /**
238
-     * @deprecated 4.9.62.p
239
-     * @param EE_Register_CPTs $cpt_class
240
-     * @return void
241
-     */
242
-    public static function default_terms(EE_Register_CPTs $cpt_class)
243
-    {
244
-        foreach (self::$_registry as $registries) {
245
-            foreach ($registries['default_terms'] as $taxonomy => $terms) {
246
-                foreach ($terms as $term => $cpts) {
247
-                    $cpt_class->set_default_term($taxonomy, $term, $cpts);
248
-                }
249
-            }
250
-        }
251
-    }
237
+	/**
238
+	 * @deprecated 4.9.62.p
239
+	 * @param EE_Register_CPTs $cpt_class
240
+	 * @return void
241
+	 */
242
+	public static function default_terms(EE_Register_CPTs $cpt_class)
243
+	{
244
+		foreach (self::$_registry as $registries) {
245
+			foreach ($registries['default_terms'] as $taxonomy => $terms) {
246
+				foreach ($terms as $term => $cpts) {
247
+					$cpt_class->set_default_term($taxonomy, $term, $cpts);
248
+				}
249
+			}
250
+		}
251
+	}
252 252
 
253 253
 
254
-    /**
255
-     * This deregisters whats been registered on this class (for the given slug).
256
-     *
257
-     * @since 4.5.0
258
-     *
259
-     * @param string $cpt_ref The reference for the item registered to be removed.
260
-     *
261
-     * @return void
262
-     */
263
-    public static function deregister($cpt_ref = null)
264
-    {
265
-        if (! empty(self::$_registry[ $cpt_ref ])) {
266
-            unset(self::$_registry[ $cpt_ref ]);
267
-        }
268
-    }
254
+	/**
255
+	 * This deregisters whats been registered on this class (for the given slug).
256
+	 *
257
+	 * @since 4.5.0
258
+	 *
259
+	 * @param string $cpt_ref The reference for the item registered to be removed.
260
+	 *
261
+	 * @return void
262
+	 */
263
+	public static function deregister($cpt_ref = null)
264
+	{
265
+		if (! empty(self::$_registry[ $cpt_ref ])) {
266
+			unset(self::$_registry[ $cpt_ref ]);
267
+		}
268
+	}
269 269
 }
Please login to merge, or discard this patch.
core/EE_Registry.core.php 1 patch
Indentation   +1660 added lines, -1660 removed lines patch added patch discarded remove patch
@@ -23,1664 +23,1664 @@
 block discarded – undo
23 23
 class EE_Registry implements ResettableInterface
24 24
 {
25 25
 
26
-    /**
27
-     * @var EE_Registry $_instance
28
-     */
29
-    private static $_instance;
30
-
31
-    /**
32
-     * @var EE_Dependency_Map $_dependency_map
33
-     */
34
-    protected $_dependency_map;
35
-
36
-    /**
37
-     * @var Mirror
38
-     */
39
-    private $mirror;
40
-
41
-    /**
42
-     * @var ClassInterfaceCache $class_cache
43
-     */
44
-    private $class_cache;
45
-
46
-    /**
47
-     * @var array $_class_abbreviations
48
-     */
49
-    protected $_class_abbreviations = array();
50
-
51
-    /**
52
-     * @var CommandBusInterface $BUS
53
-     */
54
-    public $BUS;
55
-
56
-    /**
57
-     * @var EE_Cart $CART
58
-     */
59
-    public $CART;
60
-
61
-    /**
62
-     * @var EE_Config $CFG
63
-     */
64
-    public $CFG;
65
-
66
-    /**
67
-     * @var EE_Network_Config $NET_CFG
68
-     */
69
-    public $NET_CFG;
70
-
71
-    /**
72
-     * StdClass object for storing library classes in
73
-     *
74
-     * @var RegistryContainer $LIB
75
-     */
76
-    public $LIB;
77
-
78
-    /**
79
-     * @var EE_Request_Handler $REQ
80
-     */
81
-    public $REQ;
82
-
83
-    /**
84
-     * @var EE_Session $SSN
85
-     */
86
-    public $SSN;
87
-
88
-    /**
89
-     * @since 4.5.0
90
-     * @var EE_Capabilities $CAP
91
-     */
92
-    public $CAP;
93
-
94
-    /**
95
-     * @since 4.9.0
96
-     * @var EE_Message_Resource_Manager $MRM
97
-     */
98
-    public $MRM;
99
-
100
-    /**
101
-     * @var Registry $AssetsRegistry
102
-     */
103
-    public $AssetsRegistry;
104
-
105
-    /**
106
-     * StdClass object for holding addons which have registered themselves to work with EE core
107
-     *
108
-     * @var EE_Addon[] $addons
109
-     */
110
-    public $addons;
111
-
112
-    /**
113
-     * keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
114
-     *
115
-     * @var EEM_Base[] $models
116
-     */
117
-    public $models = array();
118
-
119
-    /**
120
-     * @var EED_Module[] $modules
121
-     */
122
-    public $modules;
123
-
124
-    /**
125
-     * @var EES_Shortcode[] $shortcodes
126
-     */
127
-    public $shortcodes;
128
-
129
-    /**
130
-     * @var WP_Widget[] $widgets
131
-     */
132
-    public $widgets;
133
-
134
-    /**
135
-     * this is an array of all implemented model names (i.e. not the parent abstract models, or models
136
-     * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
137
-     * Keys are model "short names" (eg "Event") as used in model relations, and values are
138
-     * classnames (eg "EEM_Event")
139
-     *
140
-     * @var array $non_abstract_db_models
141
-     */
142
-    public $non_abstract_db_models = array();
143
-
144
-    /**
145
-     * internationalization for JS strings
146
-     *    usage:   EE_Registry::i18n_js_strings['string_key'] = esc_html__( 'string to translate.', 'event_espresso' );
147
-     *    in js file:  var translatedString = eei18n.string_key;
148
-     *
149
-     * @var array $i18n_js_strings
150
-     */
151
-    public static $i18n_js_strings = array();
152
-
153
-    /**
154
-     * $main_file - path to espresso.php
155
-     *
156
-     * @var array $main_file
157
-     */
158
-    public $main_file;
159
-
160
-    /**
161
-     * array of ReflectionClass objects where the key is the class name
162
-     *
163
-     * @deprecated 4.9.62.p
164
-     * @var ReflectionClass[] $_reflectors
165
-     */
166
-    public $_reflectors;
167
-
168
-    /**
169
-     * boolean flag to indicate whether or not to load/save dependencies from/to the cache
170
-     *
171
-     * @var boolean $_cache_on
172
-     */
173
-    protected $_cache_on = true;
174
-
175
-    /**
176
-     * @var ObjectIdentifier
177
-     */
178
-    private $object_identifier;
179
-
180
-
181
-    /**
182
-     * @singleton method used to instantiate class object
183
-     * @param EE_Dependency_Map|null   $dependency_map
184
-     * @param Mirror|null              $mirror
185
-     * @param ClassInterfaceCache|null $class_cache
186
-     * @param ObjectIdentifier|null    $object_identifier
187
-     * @return EE_Registry instance
188
-     */
189
-    public static function instance(
190
-        EE_Dependency_Map $dependency_map = null,
191
-        Mirror $mirror = null,
192
-        ClassInterfaceCache $class_cache = null,
193
-        ObjectIdentifier $object_identifier = null
194
-    ) {
195
-        // check if class object is instantiated
196
-        if (! self::$_instance instanceof EE_Registry
197
-            && $dependency_map instanceof EE_Dependency_Map
198
-            && $mirror instanceof Mirror
199
-            && $class_cache instanceof ClassInterfaceCache
200
-            && $object_identifier instanceof ObjectIdentifier
201
-        ) {
202
-            self::$_instance = new self(
203
-                $dependency_map,
204
-                $mirror,
205
-                $class_cache,
206
-                $object_identifier
207
-            );
208
-        }
209
-        return self::$_instance;
210
-    }
211
-
212
-
213
-    /**
214
-     * protected constructor to prevent direct creation
215
-     *
216
-     * @Constructor
217
-     * @param  EE_Dependency_Map  $dependency_map
218
-     * @param Mirror              $mirror
219
-     * @param ClassInterfaceCache $class_cache
220
-     * @param ObjectIdentifier    $object_identifier
221
-     */
222
-    protected function __construct(
223
-        EE_Dependency_Map $dependency_map,
224
-        Mirror $mirror,
225
-        ClassInterfaceCache $class_cache,
226
-        ObjectIdentifier $object_identifier
227
-    ) {
228
-        $this->_dependency_map = $dependency_map;
229
-        $this->mirror = $mirror;
230
-        $this->class_cache = $class_cache;
231
-        $this->object_identifier = $object_identifier;
232
-        // $registry_container = new RegistryContainer();
233
-        $this->LIB = new RegistryContainer();
234
-        $this->addons = new RegistryContainer();
235
-        $this->modules = new RegistryContainer();
236
-        $this->shortcodes = new RegistryContainer();
237
-        $this->widgets = new RegistryContainer();
238
-        add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
239
-    }
240
-
241
-
242
-    /**
243
-     * initialize
244
-     *
245
-     * @throws OutOfBoundsException
246
-     * @throws InvalidArgumentException
247
-     * @throws InvalidInterfaceException
248
-     * @throws InvalidDataTypeException
249
-     * @throws EE_Error
250
-     * @throws ReflectionException
251
-     */
252
-    public function initialize()
253
-    {
254
-        $this->_class_abbreviations = apply_filters(
255
-            'FHEE__EE_Registry____construct___class_abbreviations',
256
-            array(
257
-                'EE_Config'                                       => 'CFG',
258
-                'EE_Session'                                      => 'SSN',
259
-                'EE_Capabilities'                                 => 'CAP',
260
-                'EE_Cart'                                         => 'CART',
261
-                'EE_Network_Config'                               => 'NET_CFG',
262
-                'EE_Request_Handler'                              => 'REQ',
263
-                'EE_Message_Resource_Manager'                     => 'MRM',
264
-                'EventEspresso\core\services\commands\CommandBus' => 'BUS',
265
-                'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
266
-            )
267
-        );
268
-        $this->load_core('Base', array(), true);
269
-        // add our request and response objects to the cache
270
-        $request_loader = $this->_dependency_map->class_loader(
271
-            'EventEspresso\core\services\request\Request'
272
-        );
273
-        $this->_set_cached_class(
274
-            $request_loader(),
275
-            'EventEspresso\core\services\request\Request'
276
-        );
277
-        $response_loader = $this->_dependency_map->class_loader(
278
-            'EventEspresso\core\services\request\Response'
279
-        );
280
-        $this->_set_cached_class(
281
-            $response_loader(),
282
-            'EventEspresso\core\services\request\Response'
283
-        );
284
-        add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
285
-    }
286
-
287
-
288
-    /**
289
-     * @return void
290
-     */
291
-    public function init()
292
-    {
293
-        // Get current page protocol
294
-        $protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
295
-        // Output admin-ajax.php URL with same protocol as current page
296
-        self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
297
-        self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
298
-    }
299
-
300
-
301
-    /**
302
-     * localize_i18n_js_strings
303
-     *
304
-     * @return string
305
-     */
306
-    public static function localize_i18n_js_strings()
307
-    {
308
-        $i18n_js_strings = (array) self::$i18n_js_strings;
309
-        foreach ($i18n_js_strings as $key => $value) {
310
-            if (is_scalar($value)) {
311
-                $i18n_js_strings[ $key ] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
-            }
313
-        }
314
-        return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
315
-    }
316
-
317
-
318
-    /**
319
-     * @param mixed string | EED_Module $module
320
-     * @throws OutOfBoundsException
321
-     * @throws InvalidArgumentException
322
-     * @throws InvalidInterfaceException
323
-     * @throws InvalidDataTypeException
324
-     * @throws EE_Error
325
-     * @throws ReflectionException
326
-     */
327
-    public function add_module($module)
328
-    {
329
-        if ($module instanceof EED_Module) {
330
-            $module_class = get_class($module);
331
-            $this->modules->{$module_class} = $module;
332
-        } else {
333
-            if (! class_exists('EE_Module_Request_Router', false)) {
334
-                $this->load_core('Module_Request_Router');
335
-            }
336
-            EE_Module_Request_Router::module_factory($module);
337
-        }
338
-    }
339
-
340
-
341
-    /**
342
-     * @param string $module_name
343
-     * @return mixed EED_Module | NULL
344
-     */
345
-    public function get_module($module_name = '')
346
-    {
347
-        return isset($this->modules->{$module_name})
348
-            ? $this->modules->{$module_name}
349
-            : null;
350
-    }
351
-
352
-
353
-    /**
354
-     * loads core classes - must be singletons
355
-     *
356
-     * @param string $class_name - simple class name ie: session
357
-     * @param mixed  $arguments
358
-     * @param bool   $load_only
359
-     * @return mixed
360
-     * @throws InvalidInterfaceException
361
-     * @throws InvalidDataTypeException
362
-     * @throws EE_Error
363
-     * @throws ReflectionException
364
-     * @throws InvalidArgumentException
365
-     */
366
-    public function load_core($class_name, $arguments = array(), $load_only = false)
367
-    {
368
-        $core_paths = apply_filters(
369
-            'FHEE__EE_Registry__load_core__core_paths',
370
-            array(
371
-                EE_CORE,
372
-                EE_ADMIN,
373
-                EE_CPTS,
374
-                EE_CORE . 'data_migration_scripts' . DS,
375
-                EE_CORE . 'capabilities' . DS,
376
-                EE_CORE . 'request_stack' . DS,
377
-                EE_CORE . 'middleware' . DS,
378
-            )
379
-        );
380
-        // retrieve instantiated class
381
-        return $this->_load(
382
-            $core_paths,
383
-            'EE_',
384
-            $class_name,
385
-            'core',
386
-            $arguments,
387
-            false,
388
-            true,
389
-            $load_only
390
-        );
391
-    }
392
-
393
-
394
-    /**
395
-     * loads service classes
396
-     *
397
-     * @param string $class_name - simple class name ie: session
398
-     * @param mixed  $arguments
399
-     * @param bool   $load_only
400
-     * @return mixed
401
-     * @throws InvalidInterfaceException
402
-     * @throws InvalidDataTypeException
403
-     * @throws EE_Error
404
-     * @throws ReflectionException
405
-     * @throws InvalidArgumentException
406
-     */
407
-    public function load_service($class_name, $arguments = array(), $load_only = false)
408
-    {
409
-        $service_paths = apply_filters(
410
-            'FHEE__EE_Registry__load_service__service_paths',
411
-            array(
412
-                EE_CORE . 'services' . DS,
413
-            )
414
-        );
415
-        // retrieve instantiated class
416
-        return $this->_load(
417
-            $service_paths,
418
-            'EE_',
419
-            $class_name,
420
-            'class',
421
-            $arguments,
422
-            false,
423
-            true,
424
-            $load_only
425
-        );
426
-    }
427
-
428
-
429
-    /**
430
-     * loads data_migration_scripts
431
-     *
432
-     * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
433
-     * @param mixed  $arguments
434
-     * @return EE_Data_Migration_Script_Base|mixed
435
-     * @throws InvalidInterfaceException
436
-     * @throws InvalidDataTypeException
437
-     * @throws EE_Error
438
-     * @throws ReflectionException
439
-     * @throws InvalidArgumentException
440
-     */
441
-    public function load_dms($class_name, $arguments = array())
442
-    {
443
-        // retrieve instantiated class
444
-        return $this->_load(
445
-            EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(),
446
-            'EE_DMS_',
447
-            $class_name,
448
-            'dms',
449
-            $arguments,
450
-            false,
451
-            false
452
-        );
453
-    }
454
-
455
-
456
-    /**
457
-     * loads object creating classes - must be singletons
458
-     *
459
-     * @param string $class_name - simple class name ie: attendee
460
-     * @param mixed  $arguments  - an array of arguments to pass to the class
461
-     * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to
462
-     *                           instantiate
463
-     * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then
464
-     *                           set this to FALSE (ie. when instantiating model objects from client in a loop)
465
-     * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate
466
-     *                           (default)
467
-     * @return EE_Base_Class | bool
468
-     * @throws InvalidInterfaceException
469
-     * @throws InvalidDataTypeException
470
-     * @throws EE_Error
471
-     * @throws ReflectionException
472
-     * @throws InvalidArgumentException
473
-     */
474
-    public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
475
-    {
476
-        $paths = apply_filters(
477
-            'FHEE__EE_Registry__load_class__paths',
478
-            array(
479
-                EE_CORE,
480
-                EE_CLASSES,
481
-                EE_BUSINESS,
482
-            )
483
-        );
484
-        // retrieve instantiated class
485
-        return $this->_load(
486
-            $paths,
487
-            'EE_',
488
-            $class_name,
489
-            'class',
490
-            $arguments,
491
-            $from_db,
492
-            $cache,
493
-            $load_only
494
-        );
495
-    }
496
-
497
-
498
-    /**
499
-     * loads helper classes - must be singletons
500
-     *
501
-     * @param string $class_name - simple class name ie: price
502
-     * @param mixed  $arguments
503
-     * @param bool   $load_only
504
-     * @return EEH_Base | bool
505
-     * @throws InvalidInterfaceException
506
-     * @throws InvalidDataTypeException
507
-     * @throws EE_Error
508
-     * @throws ReflectionException
509
-     * @throws InvalidArgumentException
510
-     */
511
-    public function load_helper($class_name, $arguments = array(), $load_only = true)
512
-    {
513
-        // todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
514
-        $helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
515
-        // retrieve instantiated class
516
-        return $this->_load(
517
-            $helper_paths,
518
-            'EEH_',
519
-            $class_name,
520
-            'helper',
521
-            $arguments,
522
-            false,
523
-            true,
524
-            $load_only
525
-        );
526
-    }
527
-
528
-
529
-    /**
530
-     * loads core classes - must be singletons
531
-     *
532
-     * @param string $class_name - simple class name ie: session
533
-     * @param mixed  $arguments
534
-     * @param bool   $load_only
535
-     * @param bool   $cache      whether to cache the object or not.
536
-     * @return mixed
537
-     * @throws InvalidInterfaceException
538
-     * @throws InvalidDataTypeException
539
-     * @throws EE_Error
540
-     * @throws ReflectionException
541
-     * @throws InvalidArgumentException
542
-     */
543
-    public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
544
-    {
545
-        $paths = array(
546
-            EE_LIBRARIES,
547
-            EE_LIBRARIES . 'messages' . DS,
548
-            EE_LIBRARIES . 'shortcodes' . DS,
549
-            EE_LIBRARIES . 'qtips' . DS,
550
-            EE_LIBRARIES . 'payment_methods' . DS,
551
-        );
552
-        // retrieve instantiated class
553
-        return $this->_load(
554
-            $paths,
555
-            'EE_',
556
-            $class_name,
557
-            'lib',
558
-            $arguments,
559
-            false,
560
-            $cache,
561
-            $load_only
562
-        );
563
-    }
564
-
565
-
566
-    /**
567
-     * loads model classes - must be singletons
568
-     *
569
-     * @param string $class_name - simple class name ie: price
570
-     * @param mixed  $arguments
571
-     * @param bool   $load_only
572
-     * @return EEM_Base | bool
573
-     * @throws InvalidInterfaceException
574
-     * @throws InvalidDataTypeException
575
-     * @throws EE_Error
576
-     * @throws ReflectionException
577
-     * @throws InvalidArgumentException
578
-     */
579
-    public function load_model($class_name, $arguments = array(), $load_only = false)
580
-    {
581
-        $paths = apply_filters(
582
-            'FHEE__EE_Registry__load_model__paths',
583
-            array(
584
-                EE_MODELS,
585
-                EE_CORE,
586
-            )
587
-        );
588
-        // retrieve instantiated class
589
-        return $this->_load(
590
-            $paths,
591
-            'EEM_',
592
-            $class_name,
593
-            'model',
594
-            $arguments,
595
-            false,
596
-            true,
597
-            $load_only
598
-        );
599
-    }
600
-
601
-
602
-    /**
603
-     * loads model classes - must be singletons
604
-     *
605
-     * @param string $class_name - simple class name ie: price
606
-     * @param mixed  $arguments
607
-     * @param bool   $load_only
608
-     * @return mixed | bool
609
-     * @throws InvalidInterfaceException
610
-     * @throws InvalidDataTypeException
611
-     * @throws EE_Error
612
-     * @throws ReflectionException
613
-     * @throws InvalidArgumentException
614
-     */
615
-    public function load_model_class($class_name, $arguments = array(), $load_only = true)
616
-    {
617
-        $paths = array(
618
-            EE_MODELS . 'fields' . DS,
619
-            EE_MODELS . 'helpers' . DS,
620
-            EE_MODELS . 'relations' . DS,
621
-            EE_MODELS . 'strategies' . DS,
622
-        );
623
-        // retrieve instantiated class
624
-        return $this->_load(
625
-            $paths,
626
-            'EE_',
627
-            $class_name,
628
-            '',
629
-            $arguments,
630
-            false,
631
-            true,
632
-            $load_only
633
-        );
634
-    }
635
-
636
-
637
-    /**
638
-     * Determines if $model_name is the name of an actual EE model.
639
-     *
640
-     * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
641
-     * @return boolean
642
-     */
643
-    public function is_model_name($model_name)
644
-    {
645
-        return isset($this->models[ $model_name ]);
646
-    }
647
-
648
-
649
-    /**
650
-     * generic class loader
651
-     *
652
-     * @param string $path_to_file - directory path to file location, not including filename
653
-     * @param string $file_name    - file name  ie:  my_file.php, including extension
654
-     * @param string $type         - file type - core? class? helper? model?
655
-     * @param mixed  $arguments
656
-     * @param bool   $load_only
657
-     * @return mixed
658
-     * @throws InvalidInterfaceException
659
-     * @throws InvalidDataTypeException
660
-     * @throws EE_Error
661
-     * @throws ReflectionException
662
-     * @throws InvalidArgumentException
663
-     */
664
-    public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
665
-    {
666
-        // retrieve instantiated class
667
-        return $this->_load(
668
-            $path_to_file,
669
-            '',
670
-            $file_name,
671
-            $type,
672
-            $arguments,
673
-            false,
674
-            true,
675
-            $load_only
676
-        );
677
-    }
678
-
679
-
680
-    /**
681
-     * @param string $path_to_file - directory path to file location, not including filename
682
-     * @param string $class_name   - full class name  ie:  My_Class
683
-     * @param string $type         - file type - core? class? helper? model?
684
-     * @param mixed  $arguments
685
-     * @param bool   $load_only
686
-     * @return bool|EE_Addon|object
687
-     * @throws InvalidInterfaceException
688
-     * @throws InvalidDataTypeException
689
-     * @throws EE_Error
690
-     * @throws ReflectionException
691
-     * @throws InvalidArgumentException
692
-     */
693
-    public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
694
-    {
695
-        // retrieve instantiated class
696
-        return $this->_load(
697
-            $path_to_file,
698
-            'addon',
699
-            $class_name,
700
-            $type,
701
-            $arguments,
702
-            false,
703
-            true,
704
-            $load_only
705
-        );
706
-    }
707
-
708
-
709
-    /**
710
-     * instantiates, caches, and automatically resolves dependencies
711
-     * for classes that use a Fully Qualified Class Name.
712
-     * if the class is not capable of being loaded using PSR-4 autoloading,
713
-     * then you need to use one of the existing load_*() methods
714
-     * which can resolve the classname and filepath from the passed arguments
715
-     *
716
-     * @param bool|string $class_name   Fully Qualified Class Name
717
-     * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
718
-     * @param bool        $cache        whether to cache the instantiated object for reuse
719
-     * @param bool        $from_db      some classes are instantiated from the db
720
-     *                                  and thus call a different method to instantiate
721
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
722
-     * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
723
-     * @return bool|null|mixed          null = failure to load or instantiate class object.
724
-     *                                  object = class loaded and instantiated successfully.
725
-     *                                  bool = fail or success when $load_only is true
726
-     * @throws InvalidInterfaceException
727
-     * @throws InvalidDataTypeException
728
-     * @throws EE_Error
729
-     * @throws ReflectionException
730
-     * @throws InvalidArgumentException
731
-     */
732
-    public function create(
733
-        $class_name = false,
734
-        $arguments = array(),
735
-        $cache = false,
736
-        $from_db = false,
737
-        $load_only = false,
738
-        $addon = false
739
-    ) {
740
-        $class_name = ltrim($class_name, '\\');
741
-        $class_name = $this->class_cache->getFqnForAlias($class_name);
742
-        $class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
743
-        // if a non-FQCN was passed, then
744
-        // verifyClassExists() might return an object
745
-        // or it could return null if the class just could not be found anywhere
746
-        if ($class_exists instanceof $class_name || $class_exists === null) {
747
-            // either way, return the results
748
-            return $class_exists;
749
-        }
750
-        $class_name = $class_exists;
751
-        // if we're only loading the class and it already exists, then let's just return true immediately
752
-        if ($load_only) {
753
-            return true;
754
-        }
755
-        $addon = $addon ? 'addon' : '';
756
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
757
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
758
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
759
-        if ($this->_cache_on && $cache && ! $load_only) {
760
-            // return object if it's already cached
761
-            $cached_class = $this->_get_cached_class($class_name, $addon, $arguments);
762
-            if ($cached_class !== null) {
763
-                return $cached_class;
764
-            }
765
-        }// obtain the loader method from the dependency map
766
-        $loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
767
-        if ($loader instanceof Closure) {
768
-            $class_obj = $loader($arguments);
769
-        } else {
770
-            if ($loader && method_exists($this, $loader)) {
771
-                $class_obj = $this->{$loader}($class_name, $arguments);
772
-            } else {
773
-                $class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
774
-            }
775
-        }
776
-        if (($this->_cache_on && $cache) || $this->get_class_abbreviation($class_name, '')) {
777
-            // save it for later... kinda like gum  { : $
778
-            $this->_set_cached_class(
779
-                $class_obj,
780
-                $class_name,
781
-                $addon,
782
-                $from_db,
783
-                $arguments
784
-            );
785
-        }
786
-        $this->_cache_on = true;
787
-        return $class_obj;
788
-    }
789
-
790
-
791
-    /**
792
-     * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
793
-     *
794
-     * @param string|object $class_name
795
-     * @param array         $arguments
796
-     * @param int           $attempt
797
-     * @return mixed
798
-     */
799
-    private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1)
800
-    {
801
-        if (is_object($class_name) || class_exists($class_name)) {
802
-            return $class_name;
803
-        }
804
-        switch ($attempt) {
805
-            case 1:
806
-                // if it's a FQCN then maybe the class is registered with a preceding \
807
-                $class_name = strpos($class_name, '\\') !== false
808
-                    ? '\\' . ltrim($class_name, '\\')
809
-                    : $class_name;
810
-                break;
811
-            case 2:
812
-                //
813
-                $loader = $this->_dependency_map->class_loader($class_name);
814
-                if ($loader && method_exists($this, $loader)) {
815
-                    return $this->{$loader}($class_name, $arguments);
816
-                }
817
-                break;
818
-            case 3:
819
-            default:
820
-                return null;
821
-        }
822
-        $attempt++;
823
-        return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
824
-    }
825
-
826
-
827
-    /**
828
-     * instantiates, caches, and injects dependencies for classes
829
-     *
830
-     * @param array       $file_paths   an array of paths to folders to look in
831
-     * @param string      $class_prefix EE  or EEM or... ???
832
-     * @param bool|string $class_name   $class name
833
-     * @param string      $type         file type - core? class? helper? model?
834
-     * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
835
-     * @param bool        $from_db      some classes are instantiated from the db
836
-     *                                  and thus call a different method to instantiate
837
-     * @param bool        $cache        whether to cache the instantiated object for reuse
838
-     * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
839
-     * @return bool|null|object null = failure to load or instantiate class object.
840
-     *                                  object = class loaded and instantiated successfully.
841
-     *                                  bool = fail or success when $load_only is true
842
-     * @throws EE_Error
843
-     * @throws ReflectionException
844
-     * @throws InvalidInterfaceException
845
-     * @throws InvalidDataTypeException
846
-     * @throws InvalidArgumentException
847
-     */
848
-    protected function _load(
849
-        $file_paths = array(),
850
-        $class_prefix = 'EE_',
851
-        $class_name = false,
852
-        $type = 'class',
853
-        $arguments = array(),
854
-        $from_db = false,
855
-        $cache = true,
856
-        $load_only = false
857
-    ) {
858
-        $class_name = ltrim($class_name, '\\');
859
-        // strip php file extension
860
-        $class_name = str_replace('.php', '', trim($class_name));
861
-        // does the class have a prefix ?
862
-        if (! empty($class_prefix) && $class_prefix !== 'addon') {
863
-            // make sure $class_prefix is uppercase
864
-            $class_prefix = strtoupper(trim($class_prefix));
865
-            // add class prefix ONCE!!!
866
-            $class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
867
-        }
868
-        $class_name = $this->class_cache->getFqnForAlias($class_name);
869
-        $class_exists = class_exists($class_name, false);
870
-        // if we're only loading the class and it already exists, then let's just return true immediately
871
-        if ($load_only && $class_exists) {
872
-            return true;
873
-        }
874
-        $arguments = is_array($arguments) ? $arguments : array($arguments);
875
-        // $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
876
-        // $cache is controlled by individual calls to separate Registry loader methods like load_class()
877
-        // $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
878
-        if ($this->_cache_on && $cache && ! $load_only) {
879
-            // return object if it's already cached
880
-            $cached_class = $this->_get_cached_class($class_name, $class_prefix, $arguments);
881
-            if ($cached_class !== null) {
882
-                return $cached_class;
883
-            }
884
-        }
885
-        // if the class doesn't already exist.. then we need to try and find the file and load it
886
-        if (! $class_exists) {
887
-            // get full path to file
888
-            $path = $this->_resolve_path($class_name, $type, $file_paths);
889
-            // load the file
890
-            $loaded = $this->_require_file($path, $class_name, $type, $file_paths);
891
-            // if we are only loading a file but NOT instantiating an object
892
-            // then return boolean for whether class was loaded or not
893
-            if ($load_only) {
894
-                return $loaded;
895
-            }
896
-            // if an object was expected but loading failed, then return nothing
897
-            if (! $loaded) {
898
-                return null;
899
-            }
900
-        }
901
-        // instantiate the requested object
902
-        $class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
903
-        if ($this->_cache_on && $cache) {
904
-            // save it for later... kinda like gum  { : $
905
-            $this->_set_cached_class(
906
-                $class_obj,
907
-                $class_name,
908
-                $class_prefix,
909
-                $from_db,
910
-                $arguments
911
-            );
912
-        }
913
-        $this->_cache_on = true;
914
-        return $class_obj;
915
-    }
916
-
917
-
918
-    /**
919
-     * @param string $class_name
920
-     * @param string $default have to specify something, but not anything that will conflict
921
-     * @return mixed|string
922
-     */
923
-    protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
924
-    {
925
-        return isset($this->_class_abbreviations[ $class_name ])
926
-            ? $this->_class_abbreviations[ $class_name ]
927
-            : $default;
928
-    }
929
-
930
-
931
-    /**
932
-     * attempts to find a cached version of the requested class
933
-     * by looking in the following places:
934
-     *        $this->{$class_abbreviation}            ie:    $this->CART
935
-     *        $this->{$class_name}                        ie:    $this->Some_Class
936
-     *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
937
-     *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
938
-     *
939
-     * @param string $class_name
940
-     * @param string $class_prefix
941
-     * @param array  $arguments
942
-     * @return mixed
943
-     */
944
-    protected function _get_cached_class(
945
-        $class_name,
946
-        $class_prefix = '',
947
-        $arguments = array()
948
-    ) {
949
-        if ($class_name === 'EE_Registry') {
950
-            return $this;
951
-        }
952
-        $class_abbreviation = $this->get_class_abbreviation($class_name);
953
-        // check if class has already been loaded, and return it if it has been
954
-        if (isset($this->{$class_abbreviation})) {
955
-            return $this->{$class_abbreviation};
956
-        }
957
-        $class_name = str_replace('\\', '_', $class_name);
958
-        if (isset($this->{$class_name})) {
959
-            return $this->{$class_name};
960
-        }
961
-        if ($class_prefix === 'addon' && isset($this->addons->{$class_name})) {
962
-            return $this->addons->{$class_name};
963
-        }
964
-        $object_identifier = $this->object_identifier->getIdentifier($class_name, $arguments);
965
-        if (isset($this->LIB->{$object_identifier})) {
966
-            return $this->LIB->{$object_identifier};
967
-        }
968
-        foreach ($this->LIB as $key => $object) {
969
-            if (// request does not contain new arguments and therefore no args identifier
970
-                ! $this->object_identifier->hasArguments($object_identifier)
971
-                // but previously cached class with args was found
972
-                && $this->object_identifier->fqcnMatchesObjectIdentifier($class_name, $key)
973
-            ) {
974
-                return $object;
975
-            }
976
-        }
977
-        return null;
978
-    }
979
-
980
-
981
-    /**
982
-     * removes a cached version of the requested class
983
-     *
984
-     * @param string  $class_name
985
-     * @param boolean $addon
986
-     * @param array   $arguments
987
-     * @return boolean
988
-     */
989
-    public function clear_cached_class(
990
-        $class_name,
991
-        $addon = false,
992
-        $arguments = array()
993
-    ) {
994
-        $class_abbreviation = $this->get_class_abbreviation($class_name);
995
-        // check if class has already been loaded, and return it if it has been
996
-        if (isset($this->{$class_abbreviation})) {
997
-            $this->{$class_abbreviation} = null;
998
-            return true;
999
-        }
1000
-        $class_name = str_replace('\\', '_', $class_name);
1001
-        if (isset($this->{$class_name})) {
1002
-            $this->{$class_name} = null;
1003
-            return true;
1004
-        }
1005
-        if ($addon && isset($this->addons->{$class_name})) {
1006
-            unset($this->addons->{$class_name});
1007
-            return true;
1008
-        }
1009
-        $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1010
-        if (isset($this->LIB->{$class_name})) {
1011
-            unset($this->LIB->{$class_name});
1012
-            return true;
1013
-        }
1014
-        return false;
1015
-    }
1016
-
1017
-
1018
-    /**
1019
-     * _set_cached_class
1020
-     * attempts to cache the instantiated class locally
1021
-     * in one of the following places, in the following order:
1022
-     *        $this->{class_abbreviation}   ie:    $this->CART
1023
-     *        $this->{$class_name}          ie:    $this->Some_Class
1024
-     *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1025
-     *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1026
-     *
1027
-     * @param object $class_obj
1028
-     * @param string $class_name
1029
-     * @param string $class_prefix
1030
-     * @param bool   $from_db
1031
-     * @param array  $arguments
1032
-     * @return void
1033
-     */
1034
-    protected function _set_cached_class(
1035
-        $class_obj,
1036
-        $class_name,
1037
-        $class_prefix = '',
1038
-        $from_db = false,
1039
-        $arguments = array()
1040
-    ) {
1041
-        if ($class_name === 'EE_Registry' || empty($class_obj)) {
1042
-            return;
1043
-        }
1044
-        // return newly instantiated class
1045
-        $class_abbreviation = $this->get_class_abbreviation($class_name, '');
1046
-        if ($class_abbreviation) {
1047
-            $this->{$class_abbreviation} = $class_obj;
1048
-            return;
1049
-        }
1050
-        $class_name = str_replace('\\', '_', $class_name);
1051
-        if (property_exists($this, $class_name)) {
1052
-            $this->{$class_name} = $class_obj;
1053
-            return;
1054
-        }
1055
-        if ($class_prefix === 'addon') {
1056
-            $this->addons->{$class_name} = $class_obj;
1057
-            return;
1058
-        }
1059
-        if (! $from_db) {
1060
-            $class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1061
-            $this->LIB->{$class_name} = $class_obj;
1062
-        }
1063
-    }
1064
-
1065
-
1066
-    /**
1067
-     * attempts to find a full valid filepath for the requested class.
1068
-     * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
1069
-     * then returns that path if the target file has been found and is readable
1070
-     *
1071
-     * @param string $class_name
1072
-     * @param string $type
1073
-     * @param array  $file_paths
1074
-     * @return string | bool
1075
-     */
1076
-    protected function _resolve_path($class_name, $type = '', $file_paths = array())
1077
-    {
1078
-        // make sure $file_paths is an array
1079
-        $file_paths = is_array($file_paths)
1080
-            ? $file_paths
1081
-            : array($file_paths);
1082
-        // cycle thru paths
1083
-        foreach ($file_paths as $key => $file_path) {
1084
-            // convert all separators to proper DS, if no filepath, then use EE_CLASSES
1085
-            $file_path = $file_path
1086
-                ? str_replace(array('/', '\\'), DS, $file_path)
1087
-                : EE_CLASSES;
1088
-            // prep file type
1089
-            $type = ! empty($type)
1090
-                ? trim($type, '.') . '.'
1091
-                : '';
1092
-            // build full file path
1093
-            $file_paths[ $key ] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
1094
-            // does the file exist and can be read ?
1095
-            if (is_readable($file_paths[ $key ])) {
1096
-                return $file_paths[ $key ];
1097
-            }
1098
-        }
1099
-        return false;
1100
-    }
1101
-
1102
-
1103
-    /**
1104
-     * basically just performs a require_once()
1105
-     * but with some error handling
1106
-     *
1107
-     * @param  string $path
1108
-     * @param  string $class_name
1109
-     * @param  string $type
1110
-     * @param  array  $file_paths
1111
-     * @return bool
1112
-     * @throws EE_Error
1113
-     * @throws ReflectionException
1114
-     */
1115
-    protected function _require_file($path, $class_name, $type = '', $file_paths = array())
1116
-    {
1117
-        $this->resolve_legacy_class_parent($class_name);
1118
-        // don't give up! you gotta...
1119
-        try {
1120
-            // does the file exist and can it be read ?
1121
-            if (! $path) {
1122
-                // just in case the file has already been autoloaded,
1123
-                // but discrepancies in the naming schema are preventing it from
1124
-                // being loaded via one of the EE_Registry::load_*() methods,
1125
-                // then let's try one last hail mary before throwing an exception
1126
-                // and call class_exists() again, but with autoloading turned ON
1127
-                if (class_exists($class_name)) {
1128
-                    return true;
1129
-                }
1130
-                // so sorry, can't find the file
1131
-                throw new EE_Error(
1132
-                    sprintf(
1133
-                        esc_html__(
1134
-                            'The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s',
1135
-                            'event_espresso'
1136
-                        ),
1137
-                        trim($type, '.'),
1138
-                        $class_name,
1139
-                        '<br />' . implode(',<br />', $file_paths)
1140
-                    )
1141
-                );
1142
-            }
1143
-            // get the file
1144
-            require_once($path);
1145
-            // if the class isn't already declared somewhere
1146
-            if (class_exists($class_name, false) === false) {
1147
-                // so sorry, not a class
1148
-                throw new EE_Error(
1149
-                    sprintf(
1150
-                        esc_html__(
1151
-                            'The %s file %s does not appear to contain the %s Class.',
1152
-                            'event_espresso'
1153
-                        ),
1154
-                        $type,
1155
-                        $path,
1156
-                        $class_name
1157
-                    )
1158
-                );
1159
-            }
1160
-        } catch (EE_Error $e) {
1161
-            $e->get_error();
1162
-            return false;
1163
-        }
1164
-        return true;
1165
-    }
1166
-
1167
-
1168
-    /**
1169
-     * Some of our legacy classes that extended a parent class would simply use a require() statement
1170
-     * before their class declaration in order to ensure that the parent class was loaded.
1171
-     * This is not ideal, but it's nearly impossible to determine the parent class of a non-namespaced class,
1172
-     * without triggering a fatal error because the parent class has yet to be loaded and therefore doesn't exist.
1173
-     *
1174
-     * @param string $class_name
1175
-     */
1176
-    protected function resolve_legacy_class_parent($class_name = '')
1177
-    {
1178
-        try {
1179
-            $legacy_parent_class_map = array(
1180
-                'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1181
-            );
1182
-            if (isset($legacy_parent_class_map[ $class_name ])) {
1183
-                require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1184
-            }
1185
-        } catch (Exception $exception) {
1186
-        }
1187
-    }
1188
-
1189
-
1190
-    /**
1191
-     * _create_object
1192
-     * Attempts to instantiate the requested class via any of the
1193
-     * commonly used instantiation methods employed throughout EE.
1194
-     * The priority for instantiation is as follows:
1195
-     *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
1196
-     *        - model objects via their 'new_instance_from_db' method
1197
-     *        - model objects via their 'new_instance' method
1198
-     *        - "singleton" classes" via their 'instance' method
1199
-     *    - standard instantiable classes via their __constructor
1200
-     * Prior to instantiation, if the classname exists in the dependency_map,
1201
-     * then the constructor for the requested class will be examined to determine
1202
-     * if any dependencies exist, and if they can be injected.
1203
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1204
-     *
1205
-     * @param string $class_name
1206
-     * @param array  $arguments
1207
-     * @param string $type
1208
-     * @param bool   $from_db
1209
-     * @return null|object|bool
1210
-     * @throws InvalidArgumentException
1211
-     * @throws InvalidInterfaceException
1212
-     * @throws EE_Error
1213
-     * @throws ReflectionException
1214
-     * @throws InvalidDataTypeException
1215
-     */
1216
-    protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
1217
-    {
1218
-        // create reflection
1219
-        $reflector = $this->mirror->getReflectionClass($class_name);
1220
-        // make sure arguments are an array
1221
-        $arguments = is_array($arguments)
1222
-            ? $arguments
1223
-            : array($arguments);
1224
-        // and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
1225
-        // else wrap it in an additional array so that it doesn't get split into multiple parameters
1226
-        $arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
1227
-            ? $arguments
1228
-            : array($arguments);
1229
-        // attempt to inject dependencies ?
1230
-        if ($this->_dependency_map->has($class_name)) {
1231
-            $arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
1232
-        }
1233
-        // instantiate the class if possible
1234
-        if ($reflector->isAbstract()) {
1235
-            // nothing to instantiate, loading file was enough
1236
-            // does not throw an exception so $instantiation_mode is unused
1237
-            // $instantiation_mode = "1) no constructor abstract class";
1238
-            return true;
1239
-        }
1240
-        if (empty($arguments)
1241
-            && $this->mirror->getConstructorFromReflection($reflector) === null
1242
-            && $reflector->isInstantiable()
1243
-        ) {
1244
-            // no constructor = static methods only... nothing to instantiate, loading file was enough
1245
-            // $instantiation_mode = "2) no constructor but instantiable";
1246
-            return $reflector->newInstance();
1247
-        }
1248
-        if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
1249
-            // $instantiation_mode = "3) new_instance_from_db()";
1250
-            return call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
1251
-        }
1252
-        if (method_exists($class_name, 'new_instance')) {
1253
-            // $instantiation_mode = "4) new_instance()";
1254
-            return call_user_func_array(array($class_name, 'new_instance'), $arguments);
1255
-        }
1256
-        if (method_exists($class_name, 'instance')) {
1257
-            // $instantiation_mode = "5) instance()";
1258
-            return call_user_func_array(array($class_name, 'instance'), $arguments);
1259
-        }
1260
-        if ($reflector->isInstantiable()) {
1261
-            // $instantiation_mode = "6) constructor";
1262
-            return $reflector->newInstanceArgs($arguments);
1263
-        }
1264
-        // heh ? something's not right !
1265
-        throw new EE_Error(
1266
-            sprintf(
1267
-                __('The %s file %s could not be instantiated.', 'event_espresso'),
1268
-                $type,
1269
-                $class_name
1270
-            )
1271
-        );
1272
-    }
1273
-
1274
-
1275
-    /**
1276
-     * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
1277
-     * @param array $array
1278
-     * @return bool
1279
-     */
1280
-    protected function _array_is_numerically_and_sequentially_indexed(array $array)
1281
-    {
1282
-        return ! empty($array)
1283
-            ? array_keys($array) === range(0, count($array) - 1)
1284
-            : true;
1285
-    }
1286
-
1287
-
1288
-    /**
1289
-     * _resolve_dependencies
1290
-     * examines the constructor for the requested class to determine
1291
-     * if any dependencies exist, and if they can be injected.
1292
-     * If so, then those classes will be added to the array of arguments passed to the constructor
1293
-     * PLZ NOTE: this is achieved by type hinting the constructor params
1294
-     * For example:
1295
-     *        if attempting to load a class "Foo" with the following constructor:
1296
-     *        __construct( Bar $bar_class, Fighter $grohl_class )
1297
-     *        then $bar_class and $grohl_class will be added to the $arguments array,
1298
-     *        but only IF they are NOT already present in the incoming arguments array,
1299
-     *        and the correct classes can be loaded
1300
-     *
1301
-     * @param ReflectionClass $reflector
1302
-     * @param string          $class_name
1303
-     * @param array           $arguments
1304
-     * @return array
1305
-     * @throws InvalidArgumentException
1306
-     * @throws InvalidDataTypeException
1307
-     * @throws InvalidInterfaceException
1308
-     * @throws ReflectionException
1309
-     */
1310
-    protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, array $arguments = array())
1311
-    {
1312
-        // let's examine the constructor
1313
-        $constructor = $this->mirror->getConstructorFromReflection($reflector);
1314
-        // whu? huh? nothing?
1315
-        if (! $constructor) {
1316
-            return $arguments;
1317
-        }
1318
-        // get constructor parameters
1319
-        $params = $this->mirror->getParametersFromReflection($reflector);
1320
-        // and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1321
-        $argument_keys = array_keys($arguments);
1322
-        // now loop thru all of the constructors expected parameters
1323
-        foreach ($params as $index => $param) {
1324
-            // is this a dependency for a specific class ?
1325
-            $param_class = $this->mirror->getParameterClassName($param, $class_name, $index);
1326
-            // BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1327
-            $param_class = $this->class_cache->isAlias($param_class, $class_name)
1328
-                ? $this->class_cache->getFqnForAlias($param_class, $class_name)
1329
-                : $param_class;
1330
-            if (// param is not even a class
1331
-                $param_class === null
1332
-                // and something already exists in the incoming arguments for this param
1333
-                && array_key_exists($index, $argument_keys)
1334
-                && array_key_exists($argument_keys[ $index ], $arguments)
1335
-            ) {
1336
-                // so let's skip this argument and move on to the next
1337
-                continue;
1338
-            }
1339
-            if (// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1340
-                $param_class !== null
1341
-                && isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1342
-                && $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1343
-            ) {
1344
-                // skip this argument and move on to the next
1345
-                continue;
1346
-            }
1347
-            if (// parameter is type hinted as a class, and should be injected
1348
-                $param_class !== null
1349
-                && $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1350
-            ) {
1351
-                $arguments = $this->_resolve_dependency(
1352
-                    $class_name,
1353
-                    $param_class,
1354
-                    $arguments,
1355
-                    $index
1356
-                );
1357
-            } else {
1358
-                $arguments[ $index ] = $this->mirror->getParameterDefaultValue(
1359
-                    $param,
1360
-                    $class_name,
1361
-                    $index
1362
-                );
1363
-            }
1364
-        }
1365
-        return $arguments;
1366
-    }
1367
-
1368
-
1369
-    /**
1370
-     * @param string $class_name
1371
-     * @param string $param_class
1372
-     * @param array  $arguments
1373
-     * @param mixed  $index
1374
-     * @return array
1375
-     * @throws InvalidArgumentException
1376
-     * @throws InvalidInterfaceException
1377
-     * @throws InvalidDataTypeException
1378
-     */
1379
-    protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1380
-    {
1381
-        $dependency = null;
1382
-        // should dependency be loaded from cache ?
1383
-        $cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
1384
-            $class_name,
1385
-            $param_class
1386
-        );
1387
-        $cache_on = $cache_on !== EE_Dependency_Map::load_new_object;
1388
-        // we might have a dependency...
1389
-        // let's MAYBE try and find it in our cache if that's what's been requested
1390
-        $cached_class = $cache_on
1391
-            ? $this->_get_cached_class($param_class)
1392
-            : null;
1393
-        // and grab it if it exists
1394
-        if ($cached_class instanceof $param_class) {
1395
-            $dependency = $cached_class;
1396
-        } elseif ($param_class !== $class_name) {
1397
-            // obtain the loader method from the dependency map
1398
-            $loader = $this->_dependency_map->class_loader($param_class);
1399
-            // is loader a custom closure ?
1400
-            if ($loader instanceof Closure) {
1401
-                $dependency = $loader($arguments);
1402
-            } else {
1403
-                // set the cache on property for the recursive loading call
1404
-                $this->_cache_on = $cache_on;
1405
-                // if not, then let's try and load it via the registry
1406
-                if ($loader && method_exists($this, $loader)) {
1407
-                    $dependency = $this->{$loader}($param_class);
1408
-                } else {
1409
-                    $dependency = LoaderFactory::getLoader()->load(
1410
-                        $param_class,
1411
-                        array(),
1412
-                        $cache_on
1413
-                    );
1414
-                }
1415
-            }
1416
-        }
1417
-        // did we successfully find the correct dependency ?
1418
-        if ($dependency instanceof $param_class) {
1419
-            // then let's inject it into the incoming array of arguments at the correct location
1420
-            $arguments[ $index ] = $dependency;
1421
-        }
1422
-        return $arguments;
1423
-    }
1424
-
1425
-
1426
-    /**
1427
-     * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1428
-     *
1429
-     * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1430
-     *                          in the EE_Dependency_Map::$_class_loaders array,
1431
-     *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1432
-     * @param array  $arguments
1433
-     * @return object
1434
-     */
1435
-    public static function factory($classname, $arguments = array())
1436
-    {
1437
-        $loader = self::instance()->_dependency_map->class_loader($classname);
1438
-        if ($loader instanceof Closure) {
1439
-            return $loader($arguments);
1440
-        }
1441
-        if (method_exists(self::instance(), $loader)) {
1442
-            return self::instance()->{$loader}($classname, $arguments);
1443
-        }
1444
-        return null;
1445
-    }
1446
-
1447
-
1448
-    /**
1449
-     * Gets the addon by its class name
1450
-     *
1451
-     * @param string $class_name
1452
-     * @return EE_Addon
1453
-     */
1454
-    public function getAddon($class_name)
1455
-    {
1456
-        $class_name = str_replace('\\', '_', $class_name);
1457
-        return $this->addons->{$class_name};
1458
-    }
1459
-
1460
-
1461
-    /**
1462
-     * removes the addon from the internal cache
1463
-     *
1464
-     * @param string $class_name
1465
-     * @return void
1466
-     */
1467
-    public function removeAddon($class_name)
1468
-    {
1469
-        $class_name = str_replace('\\', '_', $class_name);
1470
-        unset($this->addons->{$class_name});
1471
-    }
1472
-
1473
-
1474
-    /**
1475
-     * Gets the addon by its name/slug (not classname. For that, just
1476
-     * use the get_addon() method above
1477
-     *
1478
-     * @param string $name
1479
-     * @return EE_Addon
1480
-     */
1481
-    public function get_addon_by_name($name)
1482
-    {
1483
-        foreach ($this->addons as $addon) {
1484
-            if ($addon->name() === $name) {
1485
-                return $addon;
1486
-            }
1487
-        }
1488
-        return null;
1489
-    }
1490
-
1491
-
1492
-    /**
1493
-     * Gets an array of all the registered addons, where the keys are their names.
1494
-     * (ie, what each returns for their name() function)
1495
-     * They're already available on EE_Registry::instance()->addons as properties,
1496
-     * where each property's name is the addon's classname,
1497
-     * So if you just want to get the addon by classname,
1498
-     * OR use the get_addon() method above.
1499
-     * PLEASE  NOTE:
1500
-     * addons with Fully Qualified Class Names
1501
-     * have had the namespace separators converted to underscores,
1502
-     * so a classname like Fully\Qualified\ClassName
1503
-     * would have been converted to Fully_Qualified_ClassName
1504
-     *
1505
-     * @return EE_Addon[] where the KEYS are the addon's name()
1506
-     */
1507
-    public function get_addons_by_name()
1508
-    {
1509
-        $addons = array();
1510
-        foreach ($this->addons as $addon) {
1511
-            $addons[ $addon->name() ] = $addon;
1512
-        }
1513
-        return $addons;
1514
-    }
1515
-
1516
-
1517
-    /**
1518
-     * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1519
-     * a stale copy of it around
1520
-     *
1521
-     * @param string $model_name
1522
-     * @return \EEM_Base
1523
-     * @throws \EE_Error
1524
-     */
1525
-    public function reset_model($model_name)
1526
-    {
1527
-        $model_class_name = strpos($model_name, 'EEM_') !== 0
1528
-            ? "EEM_{$model_name}"
1529
-            : $model_name;
1530
-        if (! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1531
-            return null;
1532
-        }
1533
-        // get that model reset it and make sure we nuke the old reference to it
1534
-        if ($this->LIB->{$model_class_name} instanceof $model_class_name
1535
-            && is_callable(
1536
-                array($model_class_name, 'reset')
1537
-            )) {
1538
-            $this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1539
-        } else {
1540
-            throw new EE_Error(
1541
-                sprintf(
1542
-                    esc_html__('Model %s does not have a method "reset"', 'event_espresso'),
1543
-                    $model_name
1544
-                )
1545
-            );
1546
-        }
1547
-        return $this->LIB->{$model_class_name};
1548
-    }
1549
-
1550
-
1551
-    /**
1552
-     * Resets the registry.
1553
-     * The criteria for what gets reset is based on what can be shared between sites on the same request when
1554
-     * switch_to_blog is used in a multisite install.  Here is a list of things that are NOT reset.
1555
-     * - $_dependency_map
1556
-     * - $_class_abbreviations
1557
-     * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1558
-     * - $REQ:  Still on the same request so no need to change.
1559
-     * - $CAP: There is no site specific state in the EE_Capability class.
1560
-     * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only
1561
-     * one Session can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1562
-     * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1563
-     *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1564
-     *             switch or on the restore.
1565
-     * - $modules
1566
-     * - $shortcodes
1567
-     * - $widgets
1568
-     *
1569
-     * @param boolean $hard             [deprecated]
1570
-     * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1571
-     *                                  or just reset without re-instantiating (handy to set to FALSE if you're not
1572
-     *                                  sure if you CAN currently reinstantiate the singletons at the moment)
1573
-     * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so
1574
-     *                                  client
1575
-     *                                  code instead can just change the model context to a different blog id if
1576
-     *                                  necessary
1577
-     * @return EE_Registry
1578
-     * @throws InvalidInterfaceException
1579
-     * @throws InvalidDataTypeException
1580
-     * @throws EE_Error
1581
-     * @throws ReflectionException
1582
-     * @throws InvalidArgumentException
1583
-     */
1584
-    public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1585
-    {
1586
-        $instance = self::instance();
1587
-        $instance->_cache_on = true;
1588
-        // reset some "special" classes
1589
-        EEH_Activation::reset();
1590
-        $hard = apply_filters('FHEE__EE_Registry__reset__hard', $hard);
1591
-        $instance->CFG = EE_Config::reset($hard, $reinstantiate);
1592
-        $instance->CART = null;
1593
-        $instance->MRM = null;
1594
-        $instance->AssetsRegistry = LoaderFactory::getLoader()->getShared(
1595
-            'EventEspresso\core\services\assets\Registry'
1596
-        );
1597
-        // messages reset
1598
-        EED_Messages::reset();
1599
-        // handle of objects cached on LIB
1600
-        foreach (array('LIB', 'modules') as $cache) {
1601
-            foreach ($instance->{$cache} as $class_name => $class) {
1602
-                if (self::_reset_and_unset_object($class, $reset_models)) {
1603
-                    unset($instance->{$cache}->{$class_name});
1604
-                }
1605
-            }
1606
-        }
1607
-        return $instance;
1608
-    }
1609
-
1610
-
1611
-    /**
1612
-     * if passed object implements ResettableInterface, then call it's reset() method
1613
-     * if passed object implements InterminableInterface, then return false,
1614
-     * to indicate that it should NOT be cleared from the Registry cache
1615
-     *
1616
-     * @param      $object
1617
-     * @param bool $reset_models
1618
-     * @return bool returns true if cached object should be unset
1619
-     */
1620
-    private static function _reset_and_unset_object($object, $reset_models)
1621
-    {
1622
-        if (! is_object($object)) {
1623
-            // don't unset anything that's not an object
1624
-            return false;
1625
-        }
1626
-        if ($object instanceof EED_Module) {
1627
-            $object::reset();
1628
-            // don't unset modules
1629
-            return false;
1630
-        }
1631
-        if ($object instanceof ResettableInterface) {
1632
-            if ($object instanceof EEM_Base) {
1633
-                if ($reset_models) {
1634
-                    $object->reset();
1635
-                    return true;
1636
-                }
1637
-                return false;
1638
-            }
1639
-            $object->reset();
1640
-            return true;
1641
-        }
1642
-        if (! $object instanceof InterminableInterface) {
1643
-            return true;
1644
-        }
1645
-        return false;
1646
-    }
1647
-
1648
-
1649
-    /**
1650
-     * Gets all the custom post type models defined
1651
-     *
1652
-     * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1653
-     */
1654
-    public function cpt_models()
1655
-    {
1656
-        $cpt_models = array();
1657
-        foreach ($this->non_abstract_db_models as $short_name => $classname) {
1658
-            if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1659
-                $cpt_models[ $short_name ] = $classname;
1660
-            }
1661
-        }
1662
-        return $cpt_models;
1663
-    }
1664
-
1665
-
1666
-    /**
1667
-     * @return \EE_Config
1668
-     */
1669
-    public static function CFG()
1670
-    {
1671
-        return self::instance()->CFG;
1672
-    }
1673
-
1674
-
1675
-    /**
1676
-     * @deprecated 4.9.62.p
1677
-     * @param string $class_name
1678
-     * @return ReflectionClass
1679
-     * @throws ReflectionException
1680
-     * @throws InvalidDataTypeException
1681
-     */
1682
-    public function get_ReflectionClass($class_name)
1683
-    {
1684
-        return $this->mirror->getReflectionClass($class_name);
1685
-    }
26
+	/**
27
+	 * @var EE_Registry $_instance
28
+	 */
29
+	private static $_instance;
30
+
31
+	/**
32
+	 * @var EE_Dependency_Map $_dependency_map
33
+	 */
34
+	protected $_dependency_map;
35
+
36
+	/**
37
+	 * @var Mirror
38
+	 */
39
+	private $mirror;
40
+
41
+	/**
42
+	 * @var ClassInterfaceCache $class_cache
43
+	 */
44
+	private $class_cache;
45
+
46
+	/**
47
+	 * @var array $_class_abbreviations
48
+	 */
49
+	protected $_class_abbreviations = array();
50
+
51
+	/**
52
+	 * @var CommandBusInterface $BUS
53
+	 */
54
+	public $BUS;
55
+
56
+	/**
57
+	 * @var EE_Cart $CART
58
+	 */
59
+	public $CART;
60
+
61
+	/**
62
+	 * @var EE_Config $CFG
63
+	 */
64
+	public $CFG;
65
+
66
+	/**
67
+	 * @var EE_Network_Config $NET_CFG
68
+	 */
69
+	public $NET_CFG;
70
+
71
+	/**
72
+	 * StdClass object for storing library classes in
73
+	 *
74
+	 * @var RegistryContainer $LIB
75
+	 */
76
+	public $LIB;
77
+
78
+	/**
79
+	 * @var EE_Request_Handler $REQ
80
+	 */
81
+	public $REQ;
82
+
83
+	/**
84
+	 * @var EE_Session $SSN
85
+	 */
86
+	public $SSN;
87
+
88
+	/**
89
+	 * @since 4.5.0
90
+	 * @var EE_Capabilities $CAP
91
+	 */
92
+	public $CAP;
93
+
94
+	/**
95
+	 * @since 4.9.0
96
+	 * @var EE_Message_Resource_Manager $MRM
97
+	 */
98
+	public $MRM;
99
+
100
+	/**
101
+	 * @var Registry $AssetsRegistry
102
+	 */
103
+	public $AssetsRegistry;
104
+
105
+	/**
106
+	 * StdClass object for holding addons which have registered themselves to work with EE core
107
+	 *
108
+	 * @var EE_Addon[] $addons
109
+	 */
110
+	public $addons;
111
+
112
+	/**
113
+	 * keys are 'short names' (eg Event), values are class names (eg 'EEM_Event')
114
+	 *
115
+	 * @var EEM_Base[] $models
116
+	 */
117
+	public $models = array();
118
+
119
+	/**
120
+	 * @var EED_Module[] $modules
121
+	 */
122
+	public $modules;
123
+
124
+	/**
125
+	 * @var EES_Shortcode[] $shortcodes
126
+	 */
127
+	public $shortcodes;
128
+
129
+	/**
130
+	 * @var WP_Widget[] $widgets
131
+	 */
132
+	public $widgets;
133
+
134
+	/**
135
+	 * this is an array of all implemented model names (i.e. not the parent abstract models, or models
136
+	 * which don't actually fetch items from the DB in the normal way (ie, are not children of EEM_Base)).
137
+	 * Keys are model "short names" (eg "Event") as used in model relations, and values are
138
+	 * classnames (eg "EEM_Event")
139
+	 *
140
+	 * @var array $non_abstract_db_models
141
+	 */
142
+	public $non_abstract_db_models = array();
143
+
144
+	/**
145
+	 * internationalization for JS strings
146
+	 *    usage:   EE_Registry::i18n_js_strings['string_key'] = esc_html__( 'string to translate.', 'event_espresso' );
147
+	 *    in js file:  var translatedString = eei18n.string_key;
148
+	 *
149
+	 * @var array $i18n_js_strings
150
+	 */
151
+	public static $i18n_js_strings = array();
152
+
153
+	/**
154
+	 * $main_file - path to espresso.php
155
+	 *
156
+	 * @var array $main_file
157
+	 */
158
+	public $main_file;
159
+
160
+	/**
161
+	 * array of ReflectionClass objects where the key is the class name
162
+	 *
163
+	 * @deprecated 4.9.62.p
164
+	 * @var ReflectionClass[] $_reflectors
165
+	 */
166
+	public $_reflectors;
167
+
168
+	/**
169
+	 * boolean flag to indicate whether or not to load/save dependencies from/to the cache
170
+	 *
171
+	 * @var boolean $_cache_on
172
+	 */
173
+	protected $_cache_on = true;
174
+
175
+	/**
176
+	 * @var ObjectIdentifier
177
+	 */
178
+	private $object_identifier;
179
+
180
+
181
+	/**
182
+	 * @singleton method used to instantiate class object
183
+	 * @param EE_Dependency_Map|null   $dependency_map
184
+	 * @param Mirror|null              $mirror
185
+	 * @param ClassInterfaceCache|null $class_cache
186
+	 * @param ObjectIdentifier|null    $object_identifier
187
+	 * @return EE_Registry instance
188
+	 */
189
+	public static function instance(
190
+		EE_Dependency_Map $dependency_map = null,
191
+		Mirror $mirror = null,
192
+		ClassInterfaceCache $class_cache = null,
193
+		ObjectIdentifier $object_identifier = null
194
+	) {
195
+		// check if class object is instantiated
196
+		if (! self::$_instance instanceof EE_Registry
197
+			&& $dependency_map instanceof EE_Dependency_Map
198
+			&& $mirror instanceof Mirror
199
+			&& $class_cache instanceof ClassInterfaceCache
200
+			&& $object_identifier instanceof ObjectIdentifier
201
+		) {
202
+			self::$_instance = new self(
203
+				$dependency_map,
204
+				$mirror,
205
+				$class_cache,
206
+				$object_identifier
207
+			);
208
+		}
209
+		return self::$_instance;
210
+	}
211
+
212
+
213
+	/**
214
+	 * protected constructor to prevent direct creation
215
+	 *
216
+	 * @Constructor
217
+	 * @param  EE_Dependency_Map  $dependency_map
218
+	 * @param Mirror              $mirror
219
+	 * @param ClassInterfaceCache $class_cache
220
+	 * @param ObjectIdentifier    $object_identifier
221
+	 */
222
+	protected function __construct(
223
+		EE_Dependency_Map $dependency_map,
224
+		Mirror $mirror,
225
+		ClassInterfaceCache $class_cache,
226
+		ObjectIdentifier $object_identifier
227
+	) {
228
+		$this->_dependency_map = $dependency_map;
229
+		$this->mirror = $mirror;
230
+		$this->class_cache = $class_cache;
231
+		$this->object_identifier = $object_identifier;
232
+		// $registry_container = new RegistryContainer();
233
+		$this->LIB = new RegistryContainer();
234
+		$this->addons = new RegistryContainer();
235
+		$this->modules = new RegistryContainer();
236
+		$this->shortcodes = new RegistryContainer();
237
+		$this->widgets = new RegistryContainer();
238
+		add_action('EE_Load_Espresso_Core__handle_request__initialize_core_loading', array($this, 'initialize'));
239
+	}
240
+
241
+
242
+	/**
243
+	 * initialize
244
+	 *
245
+	 * @throws OutOfBoundsException
246
+	 * @throws InvalidArgumentException
247
+	 * @throws InvalidInterfaceException
248
+	 * @throws InvalidDataTypeException
249
+	 * @throws EE_Error
250
+	 * @throws ReflectionException
251
+	 */
252
+	public function initialize()
253
+	{
254
+		$this->_class_abbreviations = apply_filters(
255
+			'FHEE__EE_Registry____construct___class_abbreviations',
256
+			array(
257
+				'EE_Config'                                       => 'CFG',
258
+				'EE_Session'                                      => 'SSN',
259
+				'EE_Capabilities'                                 => 'CAP',
260
+				'EE_Cart'                                         => 'CART',
261
+				'EE_Network_Config'                               => 'NET_CFG',
262
+				'EE_Request_Handler'                              => 'REQ',
263
+				'EE_Message_Resource_Manager'                     => 'MRM',
264
+				'EventEspresso\core\services\commands\CommandBus' => 'BUS',
265
+				'EventEspresso\core\services\assets\Registry'     => 'AssetsRegistry',
266
+			)
267
+		);
268
+		$this->load_core('Base', array(), true);
269
+		// add our request and response objects to the cache
270
+		$request_loader = $this->_dependency_map->class_loader(
271
+			'EventEspresso\core\services\request\Request'
272
+		);
273
+		$this->_set_cached_class(
274
+			$request_loader(),
275
+			'EventEspresso\core\services\request\Request'
276
+		);
277
+		$response_loader = $this->_dependency_map->class_loader(
278
+			'EventEspresso\core\services\request\Response'
279
+		);
280
+		$this->_set_cached_class(
281
+			$response_loader(),
282
+			'EventEspresso\core\services\request\Response'
283
+		);
284
+		add_action('AHEE__EE_System__set_hooks_for_core', array($this, 'init'));
285
+	}
286
+
287
+
288
+	/**
289
+	 * @return void
290
+	 */
291
+	public function init()
292
+	{
293
+		// Get current page protocol
294
+		$protocol = isset($_SERVER['HTTPS']) ? 'https://' : 'http://';
295
+		// Output admin-ajax.php URL with same protocol as current page
296
+		self::$i18n_js_strings['ajax_url'] = admin_url('admin-ajax.php', $protocol);
297
+		self::$i18n_js_strings['wp_debug'] = defined('WP_DEBUG') ? WP_DEBUG : false;
298
+	}
299
+
300
+
301
+	/**
302
+	 * localize_i18n_js_strings
303
+	 *
304
+	 * @return string
305
+	 */
306
+	public static function localize_i18n_js_strings()
307
+	{
308
+		$i18n_js_strings = (array) self::$i18n_js_strings;
309
+		foreach ($i18n_js_strings as $key => $value) {
310
+			if (is_scalar($value)) {
311
+				$i18n_js_strings[ $key ] = html_entity_decode((string) $value, ENT_QUOTES, 'UTF-8');
312
+			}
313
+		}
314
+		return '/* <![CDATA[ */ var eei18n = ' . wp_json_encode($i18n_js_strings) . '; /* ]]> */';
315
+	}
316
+
317
+
318
+	/**
319
+	 * @param mixed string | EED_Module $module
320
+	 * @throws OutOfBoundsException
321
+	 * @throws InvalidArgumentException
322
+	 * @throws InvalidInterfaceException
323
+	 * @throws InvalidDataTypeException
324
+	 * @throws EE_Error
325
+	 * @throws ReflectionException
326
+	 */
327
+	public function add_module($module)
328
+	{
329
+		if ($module instanceof EED_Module) {
330
+			$module_class = get_class($module);
331
+			$this->modules->{$module_class} = $module;
332
+		} else {
333
+			if (! class_exists('EE_Module_Request_Router', false)) {
334
+				$this->load_core('Module_Request_Router');
335
+			}
336
+			EE_Module_Request_Router::module_factory($module);
337
+		}
338
+	}
339
+
340
+
341
+	/**
342
+	 * @param string $module_name
343
+	 * @return mixed EED_Module | NULL
344
+	 */
345
+	public function get_module($module_name = '')
346
+	{
347
+		return isset($this->modules->{$module_name})
348
+			? $this->modules->{$module_name}
349
+			: null;
350
+	}
351
+
352
+
353
+	/**
354
+	 * loads core classes - must be singletons
355
+	 *
356
+	 * @param string $class_name - simple class name ie: session
357
+	 * @param mixed  $arguments
358
+	 * @param bool   $load_only
359
+	 * @return mixed
360
+	 * @throws InvalidInterfaceException
361
+	 * @throws InvalidDataTypeException
362
+	 * @throws EE_Error
363
+	 * @throws ReflectionException
364
+	 * @throws InvalidArgumentException
365
+	 */
366
+	public function load_core($class_name, $arguments = array(), $load_only = false)
367
+	{
368
+		$core_paths = apply_filters(
369
+			'FHEE__EE_Registry__load_core__core_paths',
370
+			array(
371
+				EE_CORE,
372
+				EE_ADMIN,
373
+				EE_CPTS,
374
+				EE_CORE . 'data_migration_scripts' . DS,
375
+				EE_CORE . 'capabilities' . DS,
376
+				EE_CORE . 'request_stack' . DS,
377
+				EE_CORE . 'middleware' . DS,
378
+			)
379
+		);
380
+		// retrieve instantiated class
381
+		return $this->_load(
382
+			$core_paths,
383
+			'EE_',
384
+			$class_name,
385
+			'core',
386
+			$arguments,
387
+			false,
388
+			true,
389
+			$load_only
390
+		);
391
+	}
392
+
393
+
394
+	/**
395
+	 * loads service classes
396
+	 *
397
+	 * @param string $class_name - simple class name ie: session
398
+	 * @param mixed  $arguments
399
+	 * @param bool   $load_only
400
+	 * @return mixed
401
+	 * @throws InvalidInterfaceException
402
+	 * @throws InvalidDataTypeException
403
+	 * @throws EE_Error
404
+	 * @throws ReflectionException
405
+	 * @throws InvalidArgumentException
406
+	 */
407
+	public function load_service($class_name, $arguments = array(), $load_only = false)
408
+	{
409
+		$service_paths = apply_filters(
410
+			'FHEE__EE_Registry__load_service__service_paths',
411
+			array(
412
+				EE_CORE . 'services' . DS,
413
+			)
414
+		);
415
+		// retrieve instantiated class
416
+		return $this->_load(
417
+			$service_paths,
418
+			'EE_',
419
+			$class_name,
420
+			'class',
421
+			$arguments,
422
+			false,
423
+			true,
424
+			$load_only
425
+		);
426
+	}
427
+
428
+
429
+	/**
430
+	 * loads data_migration_scripts
431
+	 *
432
+	 * @param string $class_name - class name for the DMS ie: EE_DMS_Core_4_2_0
433
+	 * @param mixed  $arguments
434
+	 * @return EE_Data_Migration_Script_Base|mixed
435
+	 * @throws InvalidInterfaceException
436
+	 * @throws InvalidDataTypeException
437
+	 * @throws EE_Error
438
+	 * @throws ReflectionException
439
+	 * @throws InvalidArgumentException
440
+	 */
441
+	public function load_dms($class_name, $arguments = array())
442
+	{
443
+		// retrieve instantiated class
444
+		return $this->_load(
445
+			EE_Data_Migration_Manager::instance()->get_data_migration_script_folders(),
446
+			'EE_DMS_',
447
+			$class_name,
448
+			'dms',
449
+			$arguments,
450
+			false,
451
+			false
452
+		);
453
+	}
454
+
455
+
456
+	/**
457
+	 * loads object creating classes - must be singletons
458
+	 *
459
+	 * @param string $class_name - simple class name ie: attendee
460
+	 * @param mixed  $arguments  - an array of arguments to pass to the class
461
+	 * @param bool   $from_db    - some classes are instantiated from the db and thus call a different method to
462
+	 *                           instantiate
463
+	 * @param bool   $cache      if you don't want the class to be stored in the internal cache (non-persistent) then
464
+	 *                           set this to FALSE (ie. when instantiating model objects from client in a loop)
465
+	 * @param bool   $load_only  whether or not to just load the file and NOT instantiate, or load AND instantiate
466
+	 *                           (default)
467
+	 * @return EE_Base_Class | bool
468
+	 * @throws InvalidInterfaceException
469
+	 * @throws InvalidDataTypeException
470
+	 * @throws EE_Error
471
+	 * @throws ReflectionException
472
+	 * @throws InvalidArgumentException
473
+	 */
474
+	public function load_class($class_name, $arguments = array(), $from_db = false, $cache = true, $load_only = false)
475
+	{
476
+		$paths = apply_filters(
477
+			'FHEE__EE_Registry__load_class__paths',
478
+			array(
479
+				EE_CORE,
480
+				EE_CLASSES,
481
+				EE_BUSINESS,
482
+			)
483
+		);
484
+		// retrieve instantiated class
485
+		return $this->_load(
486
+			$paths,
487
+			'EE_',
488
+			$class_name,
489
+			'class',
490
+			$arguments,
491
+			$from_db,
492
+			$cache,
493
+			$load_only
494
+		);
495
+	}
496
+
497
+
498
+	/**
499
+	 * loads helper classes - must be singletons
500
+	 *
501
+	 * @param string $class_name - simple class name ie: price
502
+	 * @param mixed  $arguments
503
+	 * @param bool   $load_only
504
+	 * @return EEH_Base | bool
505
+	 * @throws InvalidInterfaceException
506
+	 * @throws InvalidDataTypeException
507
+	 * @throws EE_Error
508
+	 * @throws ReflectionException
509
+	 * @throws InvalidArgumentException
510
+	 */
511
+	public function load_helper($class_name, $arguments = array(), $load_only = true)
512
+	{
513
+		// todo: add doing_it_wrong() in a few versions after all addons have had calls to this method removed
514
+		$helper_paths = apply_filters('FHEE__EE_Registry__load_helper__helper_paths', array(EE_HELPERS));
515
+		// retrieve instantiated class
516
+		return $this->_load(
517
+			$helper_paths,
518
+			'EEH_',
519
+			$class_name,
520
+			'helper',
521
+			$arguments,
522
+			false,
523
+			true,
524
+			$load_only
525
+		);
526
+	}
527
+
528
+
529
+	/**
530
+	 * loads core classes - must be singletons
531
+	 *
532
+	 * @param string $class_name - simple class name ie: session
533
+	 * @param mixed  $arguments
534
+	 * @param bool   $load_only
535
+	 * @param bool   $cache      whether to cache the object or not.
536
+	 * @return mixed
537
+	 * @throws InvalidInterfaceException
538
+	 * @throws InvalidDataTypeException
539
+	 * @throws EE_Error
540
+	 * @throws ReflectionException
541
+	 * @throws InvalidArgumentException
542
+	 */
543
+	public function load_lib($class_name, $arguments = array(), $load_only = false, $cache = true)
544
+	{
545
+		$paths = array(
546
+			EE_LIBRARIES,
547
+			EE_LIBRARIES . 'messages' . DS,
548
+			EE_LIBRARIES . 'shortcodes' . DS,
549
+			EE_LIBRARIES . 'qtips' . DS,
550
+			EE_LIBRARIES . 'payment_methods' . DS,
551
+		);
552
+		// retrieve instantiated class
553
+		return $this->_load(
554
+			$paths,
555
+			'EE_',
556
+			$class_name,
557
+			'lib',
558
+			$arguments,
559
+			false,
560
+			$cache,
561
+			$load_only
562
+		);
563
+	}
564
+
565
+
566
+	/**
567
+	 * loads model classes - must be singletons
568
+	 *
569
+	 * @param string $class_name - simple class name ie: price
570
+	 * @param mixed  $arguments
571
+	 * @param bool   $load_only
572
+	 * @return EEM_Base | bool
573
+	 * @throws InvalidInterfaceException
574
+	 * @throws InvalidDataTypeException
575
+	 * @throws EE_Error
576
+	 * @throws ReflectionException
577
+	 * @throws InvalidArgumentException
578
+	 */
579
+	public function load_model($class_name, $arguments = array(), $load_only = false)
580
+	{
581
+		$paths = apply_filters(
582
+			'FHEE__EE_Registry__load_model__paths',
583
+			array(
584
+				EE_MODELS,
585
+				EE_CORE,
586
+			)
587
+		);
588
+		// retrieve instantiated class
589
+		return $this->_load(
590
+			$paths,
591
+			'EEM_',
592
+			$class_name,
593
+			'model',
594
+			$arguments,
595
+			false,
596
+			true,
597
+			$load_only
598
+		);
599
+	}
600
+
601
+
602
+	/**
603
+	 * loads model classes - must be singletons
604
+	 *
605
+	 * @param string $class_name - simple class name ie: price
606
+	 * @param mixed  $arguments
607
+	 * @param bool   $load_only
608
+	 * @return mixed | bool
609
+	 * @throws InvalidInterfaceException
610
+	 * @throws InvalidDataTypeException
611
+	 * @throws EE_Error
612
+	 * @throws ReflectionException
613
+	 * @throws InvalidArgumentException
614
+	 */
615
+	public function load_model_class($class_name, $arguments = array(), $load_only = true)
616
+	{
617
+		$paths = array(
618
+			EE_MODELS . 'fields' . DS,
619
+			EE_MODELS . 'helpers' . DS,
620
+			EE_MODELS . 'relations' . DS,
621
+			EE_MODELS . 'strategies' . DS,
622
+		);
623
+		// retrieve instantiated class
624
+		return $this->_load(
625
+			$paths,
626
+			'EE_',
627
+			$class_name,
628
+			'',
629
+			$arguments,
630
+			false,
631
+			true,
632
+			$load_only
633
+		);
634
+	}
635
+
636
+
637
+	/**
638
+	 * Determines if $model_name is the name of an actual EE model.
639
+	 *
640
+	 * @param string $model_name like Event, Attendee, Question_Group_Question, etc.
641
+	 * @return boolean
642
+	 */
643
+	public function is_model_name($model_name)
644
+	{
645
+		return isset($this->models[ $model_name ]);
646
+	}
647
+
648
+
649
+	/**
650
+	 * generic class loader
651
+	 *
652
+	 * @param string $path_to_file - directory path to file location, not including filename
653
+	 * @param string $file_name    - file name  ie:  my_file.php, including extension
654
+	 * @param string $type         - file type - core? class? helper? model?
655
+	 * @param mixed  $arguments
656
+	 * @param bool   $load_only
657
+	 * @return mixed
658
+	 * @throws InvalidInterfaceException
659
+	 * @throws InvalidDataTypeException
660
+	 * @throws EE_Error
661
+	 * @throws ReflectionException
662
+	 * @throws InvalidArgumentException
663
+	 */
664
+	public function load_file($path_to_file, $file_name, $type = '', $arguments = array(), $load_only = true)
665
+	{
666
+		// retrieve instantiated class
667
+		return $this->_load(
668
+			$path_to_file,
669
+			'',
670
+			$file_name,
671
+			$type,
672
+			$arguments,
673
+			false,
674
+			true,
675
+			$load_only
676
+		);
677
+	}
678
+
679
+
680
+	/**
681
+	 * @param string $path_to_file - directory path to file location, not including filename
682
+	 * @param string $class_name   - full class name  ie:  My_Class
683
+	 * @param string $type         - file type - core? class? helper? model?
684
+	 * @param mixed  $arguments
685
+	 * @param bool   $load_only
686
+	 * @return bool|EE_Addon|object
687
+	 * @throws InvalidInterfaceException
688
+	 * @throws InvalidDataTypeException
689
+	 * @throws EE_Error
690
+	 * @throws ReflectionException
691
+	 * @throws InvalidArgumentException
692
+	 */
693
+	public function load_addon($path_to_file, $class_name, $type = 'class', $arguments = array(), $load_only = false)
694
+	{
695
+		// retrieve instantiated class
696
+		return $this->_load(
697
+			$path_to_file,
698
+			'addon',
699
+			$class_name,
700
+			$type,
701
+			$arguments,
702
+			false,
703
+			true,
704
+			$load_only
705
+		);
706
+	}
707
+
708
+
709
+	/**
710
+	 * instantiates, caches, and automatically resolves dependencies
711
+	 * for classes that use a Fully Qualified Class Name.
712
+	 * if the class is not capable of being loaded using PSR-4 autoloading,
713
+	 * then you need to use one of the existing load_*() methods
714
+	 * which can resolve the classname and filepath from the passed arguments
715
+	 *
716
+	 * @param bool|string $class_name   Fully Qualified Class Name
717
+	 * @param array       $arguments    an argument, or array of arguments to pass to the class upon instantiation
718
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
719
+	 * @param bool        $from_db      some classes are instantiated from the db
720
+	 *                                  and thus call a different method to instantiate
721
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
722
+	 * @param bool|string $addon        if true, will cache the object in the EE_Registry->$addons array
723
+	 * @return bool|null|mixed          null = failure to load or instantiate class object.
724
+	 *                                  object = class loaded and instantiated successfully.
725
+	 *                                  bool = fail or success when $load_only is true
726
+	 * @throws InvalidInterfaceException
727
+	 * @throws InvalidDataTypeException
728
+	 * @throws EE_Error
729
+	 * @throws ReflectionException
730
+	 * @throws InvalidArgumentException
731
+	 */
732
+	public function create(
733
+		$class_name = false,
734
+		$arguments = array(),
735
+		$cache = false,
736
+		$from_db = false,
737
+		$load_only = false,
738
+		$addon = false
739
+	) {
740
+		$class_name = ltrim($class_name, '\\');
741
+		$class_name = $this->class_cache->getFqnForAlias($class_name);
742
+		$class_exists = $this->loadOrVerifyClassExists($class_name, $arguments);
743
+		// if a non-FQCN was passed, then
744
+		// verifyClassExists() might return an object
745
+		// or it could return null if the class just could not be found anywhere
746
+		if ($class_exists instanceof $class_name || $class_exists === null) {
747
+			// either way, return the results
748
+			return $class_exists;
749
+		}
750
+		$class_name = $class_exists;
751
+		// if we're only loading the class and it already exists, then let's just return true immediately
752
+		if ($load_only) {
753
+			return true;
754
+		}
755
+		$addon = $addon ? 'addon' : '';
756
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
757
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
758
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
759
+		if ($this->_cache_on && $cache && ! $load_only) {
760
+			// return object if it's already cached
761
+			$cached_class = $this->_get_cached_class($class_name, $addon, $arguments);
762
+			if ($cached_class !== null) {
763
+				return $cached_class;
764
+			}
765
+		}// obtain the loader method from the dependency map
766
+		$loader = $this->_dependency_map->class_loader($class_name);// instantiate the requested object
767
+		if ($loader instanceof Closure) {
768
+			$class_obj = $loader($arguments);
769
+		} else {
770
+			if ($loader && method_exists($this, $loader)) {
771
+				$class_obj = $this->{$loader}($class_name, $arguments);
772
+			} else {
773
+				$class_obj = $this->_create_object($class_name, $arguments, $addon, $from_db);
774
+			}
775
+		}
776
+		if (($this->_cache_on && $cache) || $this->get_class_abbreviation($class_name, '')) {
777
+			// save it for later... kinda like gum  { : $
778
+			$this->_set_cached_class(
779
+				$class_obj,
780
+				$class_name,
781
+				$addon,
782
+				$from_db,
783
+				$arguments
784
+			);
785
+		}
786
+		$this->_cache_on = true;
787
+		return $class_obj;
788
+	}
789
+
790
+
791
+	/**
792
+	 * Recursively checks that a class exists and potentially attempts to load classes with non-FQCNs
793
+	 *
794
+	 * @param string|object $class_name
795
+	 * @param array         $arguments
796
+	 * @param int           $attempt
797
+	 * @return mixed
798
+	 */
799
+	private function loadOrVerifyClassExists($class_name, array $arguments, $attempt = 1)
800
+	{
801
+		if (is_object($class_name) || class_exists($class_name)) {
802
+			return $class_name;
803
+		}
804
+		switch ($attempt) {
805
+			case 1:
806
+				// if it's a FQCN then maybe the class is registered with a preceding \
807
+				$class_name = strpos($class_name, '\\') !== false
808
+					? '\\' . ltrim($class_name, '\\')
809
+					: $class_name;
810
+				break;
811
+			case 2:
812
+				//
813
+				$loader = $this->_dependency_map->class_loader($class_name);
814
+				if ($loader && method_exists($this, $loader)) {
815
+					return $this->{$loader}($class_name, $arguments);
816
+				}
817
+				break;
818
+			case 3:
819
+			default:
820
+				return null;
821
+		}
822
+		$attempt++;
823
+		return $this->loadOrVerifyClassExists($class_name, $arguments, $attempt);
824
+	}
825
+
826
+
827
+	/**
828
+	 * instantiates, caches, and injects dependencies for classes
829
+	 *
830
+	 * @param array       $file_paths   an array of paths to folders to look in
831
+	 * @param string      $class_prefix EE  or EEM or... ???
832
+	 * @param bool|string $class_name   $class name
833
+	 * @param string      $type         file type - core? class? helper? model?
834
+	 * @param mixed       $arguments    an argument or array of arguments to pass to the class upon instantiation
835
+	 * @param bool        $from_db      some classes are instantiated from the db
836
+	 *                                  and thus call a different method to instantiate
837
+	 * @param bool        $cache        whether to cache the instantiated object for reuse
838
+	 * @param bool        $load_only    if true, will only load the file, but will NOT instantiate an object
839
+	 * @return bool|null|object null = failure to load or instantiate class object.
840
+	 *                                  object = class loaded and instantiated successfully.
841
+	 *                                  bool = fail or success when $load_only is true
842
+	 * @throws EE_Error
843
+	 * @throws ReflectionException
844
+	 * @throws InvalidInterfaceException
845
+	 * @throws InvalidDataTypeException
846
+	 * @throws InvalidArgumentException
847
+	 */
848
+	protected function _load(
849
+		$file_paths = array(),
850
+		$class_prefix = 'EE_',
851
+		$class_name = false,
852
+		$type = 'class',
853
+		$arguments = array(),
854
+		$from_db = false,
855
+		$cache = true,
856
+		$load_only = false
857
+	) {
858
+		$class_name = ltrim($class_name, '\\');
859
+		// strip php file extension
860
+		$class_name = str_replace('.php', '', trim($class_name));
861
+		// does the class have a prefix ?
862
+		if (! empty($class_prefix) && $class_prefix !== 'addon') {
863
+			// make sure $class_prefix is uppercase
864
+			$class_prefix = strtoupper(trim($class_prefix));
865
+			// add class prefix ONCE!!!
866
+			$class_name = $class_prefix . str_replace($class_prefix, '', $class_name);
867
+		}
868
+		$class_name = $this->class_cache->getFqnForAlias($class_name);
869
+		$class_exists = class_exists($class_name, false);
870
+		// if we're only loading the class and it already exists, then let's just return true immediately
871
+		if ($load_only && $class_exists) {
872
+			return true;
873
+		}
874
+		$arguments = is_array($arguments) ? $arguments : array($arguments);
875
+		// $this->_cache_on is toggled during the recursive loading that can occur with dependency injection
876
+		// $cache is controlled by individual calls to separate Registry loader methods like load_class()
877
+		// $load_only is also controlled by individual calls to separate Registry loader methods like load_file()
878
+		if ($this->_cache_on && $cache && ! $load_only) {
879
+			// return object if it's already cached
880
+			$cached_class = $this->_get_cached_class($class_name, $class_prefix, $arguments);
881
+			if ($cached_class !== null) {
882
+				return $cached_class;
883
+			}
884
+		}
885
+		// if the class doesn't already exist.. then we need to try and find the file and load it
886
+		if (! $class_exists) {
887
+			// get full path to file
888
+			$path = $this->_resolve_path($class_name, $type, $file_paths);
889
+			// load the file
890
+			$loaded = $this->_require_file($path, $class_name, $type, $file_paths);
891
+			// if we are only loading a file but NOT instantiating an object
892
+			// then return boolean for whether class was loaded or not
893
+			if ($load_only) {
894
+				return $loaded;
895
+			}
896
+			// if an object was expected but loading failed, then return nothing
897
+			if (! $loaded) {
898
+				return null;
899
+			}
900
+		}
901
+		// instantiate the requested object
902
+		$class_obj = $this->_create_object($class_name, $arguments, $type, $from_db);
903
+		if ($this->_cache_on && $cache) {
904
+			// save it for later... kinda like gum  { : $
905
+			$this->_set_cached_class(
906
+				$class_obj,
907
+				$class_name,
908
+				$class_prefix,
909
+				$from_db,
910
+				$arguments
911
+			);
912
+		}
913
+		$this->_cache_on = true;
914
+		return $class_obj;
915
+	}
916
+
917
+
918
+	/**
919
+	 * @param string $class_name
920
+	 * @param string $default have to specify something, but not anything that will conflict
921
+	 * @return mixed|string
922
+	 */
923
+	protected function get_class_abbreviation($class_name, $default = 'FANCY_BATMAN_PANTS')
924
+	{
925
+		return isset($this->_class_abbreviations[ $class_name ])
926
+			? $this->_class_abbreviations[ $class_name ]
927
+			: $default;
928
+	}
929
+
930
+
931
+	/**
932
+	 * attempts to find a cached version of the requested class
933
+	 * by looking in the following places:
934
+	 *        $this->{$class_abbreviation}            ie:    $this->CART
935
+	 *        $this->{$class_name}                        ie:    $this->Some_Class
936
+	 *        $this->LIB->{$class_name}                ie:    $this->LIB->Some_Class
937
+	 *        $this->addon->{$class_name}    ie:    $this->addon->Some_Addon_Class
938
+	 *
939
+	 * @param string $class_name
940
+	 * @param string $class_prefix
941
+	 * @param array  $arguments
942
+	 * @return mixed
943
+	 */
944
+	protected function _get_cached_class(
945
+		$class_name,
946
+		$class_prefix = '',
947
+		$arguments = array()
948
+	) {
949
+		if ($class_name === 'EE_Registry') {
950
+			return $this;
951
+		}
952
+		$class_abbreviation = $this->get_class_abbreviation($class_name);
953
+		// check if class has already been loaded, and return it if it has been
954
+		if (isset($this->{$class_abbreviation})) {
955
+			return $this->{$class_abbreviation};
956
+		}
957
+		$class_name = str_replace('\\', '_', $class_name);
958
+		if (isset($this->{$class_name})) {
959
+			return $this->{$class_name};
960
+		}
961
+		if ($class_prefix === 'addon' && isset($this->addons->{$class_name})) {
962
+			return $this->addons->{$class_name};
963
+		}
964
+		$object_identifier = $this->object_identifier->getIdentifier($class_name, $arguments);
965
+		if (isset($this->LIB->{$object_identifier})) {
966
+			return $this->LIB->{$object_identifier};
967
+		}
968
+		foreach ($this->LIB as $key => $object) {
969
+			if (// request does not contain new arguments and therefore no args identifier
970
+				! $this->object_identifier->hasArguments($object_identifier)
971
+				// but previously cached class with args was found
972
+				&& $this->object_identifier->fqcnMatchesObjectIdentifier($class_name, $key)
973
+			) {
974
+				return $object;
975
+			}
976
+		}
977
+		return null;
978
+	}
979
+
980
+
981
+	/**
982
+	 * removes a cached version of the requested class
983
+	 *
984
+	 * @param string  $class_name
985
+	 * @param boolean $addon
986
+	 * @param array   $arguments
987
+	 * @return boolean
988
+	 */
989
+	public function clear_cached_class(
990
+		$class_name,
991
+		$addon = false,
992
+		$arguments = array()
993
+	) {
994
+		$class_abbreviation = $this->get_class_abbreviation($class_name);
995
+		// check if class has already been loaded, and return it if it has been
996
+		if (isset($this->{$class_abbreviation})) {
997
+			$this->{$class_abbreviation} = null;
998
+			return true;
999
+		}
1000
+		$class_name = str_replace('\\', '_', $class_name);
1001
+		if (isset($this->{$class_name})) {
1002
+			$this->{$class_name} = null;
1003
+			return true;
1004
+		}
1005
+		if ($addon && isset($this->addons->{$class_name})) {
1006
+			unset($this->addons->{$class_name});
1007
+			return true;
1008
+		}
1009
+		$class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1010
+		if (isset($this->LIB->{$class_name})) {
1011
+			unset($this->LIB->{$class_name});
1012
+			return true;
1013
+		}
1014
+		return false;
1015
+	}
1016
+
1017
+
1018
+	/**
1019
+	 * _set_cached_class
1020
+	 * attempts to cache the instantiated class locally
1021
+	 * in one of the following places, in the following order:
1022
+	 *        $this->{class_abbreviation}   ie:    $this->CART
1023
+	 *        $this->{$class_name}          ie:    $this->Some_Class
1024
+	 *        $this->addon->{$$class_name}    ie:    $this->addon->Some_Addon_Class
1025
+	 *        $this->LIB->{$class_name}     ie:    $this->LIB->Some_Class
1026
+	 *
1027
+	 * @param object $class_obj
1028
+	 * @param string $class_name
1029
+	 * @param string $class_prefix
1030
+	 * @param bool   $from_db
1031
+	 * @param array  $arguments
1032
+	 * @return void
1033
+	 */
1034
+	protected function _set_cached_class(
1035
+		$class_obj,
1036
+		$class_name,
1037
+		$class_prefix = '',
1038
+		$from_db = false,
1039
+		$arguments = array()
1040
+	) {
1041
+		if ($class_name === 'EE_Registry' || empty($class_obj)) {
1042
+			return;
1043
+		}
1044
+		// return newly instantiated class
1045
+		$class_abbreviation = $this->get_class_abbreviation($class_name, '');
1046
+		if ($class_abbreviation) {
1047
+			$this->{$class_abbreviation} = $class_obj;
1048
+			return;
1049
+		}
1050
+		$class_name = str_replace('\\', '_', $class_name);
1051
+		if (property_exists($this, $class_name)) {
1052
+			$this->{$class_name} = $class_obj;
1053
+			return;
1054
+		}
1055
+		if ($class_prefix === 'addon') {
1056
+			$this->addons->{$class_name} = $class_obj;
1057
+			return;
1058
+		}
1059
+		if (! $from_db) {
1060
+			$class_name = $this->object_identifier->getIdentifier($class_name, $arguments);
1061
+			$this->LIB->{$class_name} = $class_obj;
1062
+		}
1063
+	}
1064
+
1065
+
1066
+	/**
1067
+	 * attempts to find a full valid filepath for the requested class.
1068
+	 * loops thru each of the base paths in the $file_paths array and appends : "{classname} . {file type} . php"
1069
+	 * then returns that path if the target file has been found and is readable
1070
+	 *
1071
+	 * @param string $class_name
1072
+	 * @param string $type
1073
+	 * @param array  $file_paths
1074
+	 * @return string | bool
1075
+	 */
1076
+	protected function _resolve_path($class_name, $type = '', $file_paths = array())
1077
+	{
1078
+		// make sure $file_paths is an array
1079
+		$file_paths = is_array($file_paths)
1080
+			? $file_paths
1081
+			: array($file_paths);
1082
+		// cycle thru paths
1083
+		foreach ($file_paths as $key => $file_path) {
1084
+			// convert all separators to proper DS, if no filepath, then use EE_CLASSES
1085
+			$file_path = $file_path
1086
+				? str_replace(array('/', '\\'), DS, $file_path)
1087
+				: EE_CLASSES;
1088
+			// prep file type
1089
+			$type = ! empty($type)
1090
+				? trim($type, '.') . '.'
1091
+				: '';
1092
+			// build full file path
1093
+			$file_paths[ $key ] = rtrim($file_path, DS) . DS . $class_name . '.' . $type . 'php';
1094
+			// does the file exist and can be read ?
1095
+			if (is_readable($file_paths[ $key ])) {
1096
+				return $file_paths[ $key ];
1097
+			}
1098
+		}
1099
+		return false;
1100
+	}
1101
+
1102
+
1103
+	/**
1104
+	 * basically just performs a require_once()
1105
+	 * but with some error handling
1106
+	 *
1107
+	 * @param  string $path
1108
+	 * @param  string $class_name
1109
+	 * @param  string $type
1110
+	 * @param  array  $file_paths
1111
+	 * @return bool
1112
+	 * @throws EE_Error
1113
+	 * @throws ReflectionException
1114
+	 */
1115
+	protected function _require_file($path, $class_name, $type = '', $file_paths = array())
1116
+	{
1117
+		$this->resolve_legacy_class_parent($class_name);
1118
+		// don't give up! you gotta...
1119
+		try {
1120
+			// does the file exist and can it be read ?
1121
+			if (! $path) {
1122
+				// just in case the file has already been autoloaded,
1123
+				// but discrepancies in the naming schema are preventing it from
1124
+				// being loaded via one of the EE_Registry::load_*() methods,
1125
+				// then let's try one last hail mary before throwing an exception
1126
+				// and call class_exists() again, but with autoloading turned ON
1127
+				if (class_exists($class_name)) {
1128
+					return true;
1129
+				}
1130
+				// so sorry, can't find the file
1131
+				throw new EE_Error(
1132
+					sprintf(
1133
+						esc_html__(
1134
+							'The %1$s file %2$s could not be located or is not readable due to file permissions. Please ensure that the following filepath(s) are correct: %3$s',
1135
+							'event_espresso'
1136
+						),
1137
+						trim($type, '.'),
1138
+						$class_name,
1139
+						'<br />' . implode(',<br />', $file_paths)
1140
+					)
1141
+				);
1142
+			}
1143
+			// get the file
1144
+			require_once($path);
1145
+			// if the class isn't already declared somewhere
1146
+			if (class_exists($class_name, false) === false) {
1147
+				// so sorry, not a class
1148
+				throw new EE_Error(
1149
+					sprintf(
1150
+						esc_html__(
1151
+							'The %s file %s does not appear to contain the %s Class.',
1152
+							'event_espresso'
1153
+						),
1154
+						$type,
1155
+						$path,
1156
+						$class_name
1157
+					)
1158
+				);
1159
+			}
1160
+		} catch (EE_Error $e) {
1161
+			$e->get_error();
1162
+			return false;
1163
+		}
1164
+		return true;
1165
+	}
1166
+
1167
+
1168
+	/**
1169
+	 * Some of our legacy classes that extended a parent class would simply use a require() statement
1170
+	 * before their class declaration in order to ensure that the parent class was loaded.
1171
+	 * This is not ideal, but it's nearly impossible to determine the parent class of a non-namespaced class,
1172
+	 * without triggering a fatal error because the parent class has yet to be loaded and therefore doesn't exist.
1173
+	 *
1174
+	 * @param string $class_name
1175
+	 */
1176
+	protected function resolve_legacy_class_parent($class_name = '')
1177
+	{
1178
+		try {
1179
+			$legacy_parent_class_map = array(
1180
+				'EE_Payment_Processor' => 'core/business/EE_Processor_Base.class.php',
1181
+			);
1182
+			if (isset($legacy_parent_class_map[ $class_name ])) {
1183
+				require_once EE_PLUGIN_DIR_PATH . $legacy_parent_class_map[ $class_name ];
1184
+			}
1185
+		} catch (Exception $exception) {
1186
+		}
1187
+	}
1188
+
1189
+
1190
+	/**
1191
+	 * _create_object
1192
+	 * Attempts to instantiate the requested class via any of the
1193
+	 * commonly used instantiation methods employed throughout EE.
1194
+	 * The priority for instantiation is as follows:
1195
+	 *        - abstract classes or any class flagged as "load only" (no instantiation occurs)
1196
+	 *        - model objects via their 'new_instance_from_db' method
1197
+	 *        - model objects via their 'new_instance' method
1198
+	 *        - "singleton" classes" via their 'instance' method
1199
+	 *    - standard instantiable classes via their __constructor
1200
+	 * Prior to instantiation, if the classname exists in the dependency_map,
1201
+	 * then the constructor for the requested class will be examined to determine
1202
+	 * if any dependencies exist, and if they can be injected.
1203
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1204
+	 *
1205
+	 * @param string $class_name
1206
+	 * @param array  $arguments
1207
+	 * @param string $type
1208
+	 * @param bool   $from_db
1209
+	 * @return null|object|bool
1210
+	 * @throws InvalidArgumentException
1211
+	 * @throws InvalidInterfaceException
1212
+	 * @throws EE_Error
1213
+	 * @throws ReflectionException
1214
+	 * @throws InvalidDataTypeException
1215
+	 */
1216
+	protected function _create_object($class_name, $arguments = array(), $type = '', $from_db = false)
1217
+	{
1218
+		// create reflection
1219
+		$reflector = $this->mirror->getReflectionClass($class_name);
1220
+		// make sure arguments are an array
1221
+		$arguments = is_array($arguments)
1222
+			? $arguments
1223
+			: array($arguments);
1224
+		// and if arguments array is numerically and sequentially indexed, then we want it to remain as is,
1225
+		// else wrap it in an additional array so that it doesn't get split into multiple parameters
1226
+		$arguments = $this->_array_is_numerically_and_sequentially_indexed($arguments)
1227
+			? $arguments
1228
+			: array($arguments);
1229
+		// attempt to inject dependencies ?
1230
+		if ($this->_dependency_map->has($class_name)) {
1231
+			$arguments = $this->_resolve_dependencies($reflector, $class_name, $arguments);
1232
+		}
1233
+		// instantiate the class if possible
1234
+		if ($reflector->isAbstract()) {
1235
+			// nothing to instantiate, loading file was enough
1236
+			// does not throw an exception so $instantiation_mode is unused
1237
+			// $instantiation_mode = "1) no constructor abstract class";
1238
+			return true;
1239
+		}
1240
+		if (empty($arguments)
1241
+			&& $this->mirror->getConstructorFromReflection($reflector) === null
1242
+			&& $reflector->isInstantiable()
1243
+		) {
1244
+			// no constructor = static methods only... nothing to instantiate, loading file was enough
1245
+			// $instantiation_mode = "2) no constructor but instantiable";
1246
+			return $reflector->newInstance();
1247
+		}
1248
+		if ($from_db && method_exists($class_name, 'new_instance_from_db')) {
1249
+			// $instantiation_mode = "3) new_instance_from_db()";
1250
+			return call_user_func_array(array($class_name, 'new_instance_from_db'), $arguments);
1251
+		}
1252
+		if (method_exists($class_name, 'new_instance')) {
1253
+			// $instantiation_mode = "4) new_instance()";
1254
+			return call_user_func_array(array($class_name, 'new_instance'), $arguments);
1255
+		}
1256
+		if (method_exists($class_name, 'instance')) {
1257
+			// $instantiation_mode = "5) instance()";
1258
+			return call_user_func_array(array($class_name, 'instance'), $arguments);
1259
+		}
1260
+		if ($reflector->isInstantiable()) {
1261
+			// $instantiation_mode = "6) constructor";
1262
+			return $reflector->newInstanceArgs($arguments);
1263
+		}
1264
+		// heh ? something's not right !
1265
+		throw new EE_Error(
1266
+			sprintf(
1267
+				__('The %s file %s could not be instantiated.', 'event_espresso'),
1268
+				$type,
1269
+				$class_name
1270
+			)
1271
+		);
1272
+	}
1273
+
1274
+
1275
+	/**
1276
+	 * @see http://stackoverflow.com/questions/173400/how-to-check-if-php-array-is-associative-or-sequential
1277
+	 * @param array $array
1278
+	 * @return bool
1279
+	 */
1280
+	protected function _array_is_numerically_and_sequentially_indexed(array $array)
1281
+	{
1282
+		return ! empty($array)
1283
+			? array_keys($array) === range(0, count($array) - 1)
1284
+			: true;
1285
+	}
1286
+
1287
+
1288
+	/**
1289
+	 * _resolve_dependencies
1290
+	 * examines the constructor for the requested class to determine
1291
+	 * if any dependencies exist, and if they can be injected.
1292
+	 * If so, then those classes will be added to the array of arguments passed to the constructor
1293
+	 * PLZ NOTE: this is achieved by type hinting the constructor params
1294
+	 * For example:
1295
+	 *        if attempting to load a class "Foo" with the following constructor:
1296
+	 *        __construct( Bar $bar_class, Fighter $grohl_class )
1297
+	 *        then $bar_class and $grohl_class will be added to the $arguments array,
1298
+	 *        but only IF they are NOT already present in the incoming arguments array,
1299
+	 *        and the correct classes can be loaded
1300
+	 *
1301
+	 * @param ReflectionClass $reflector
1302
+	 * @param string          $class_name
1303
+	 * @param array           $arguments
1304
+	 * @return array
1305
+	 * @throws InvalidArgumentException
1306
+	 * @throws InvalidDataTypeException
1307
+	 * @throws InvalidInterfaceException
1308
+	 * @throws ReflectionException
1309
+	 */
1310
+	protected function _resolve_dependencies(ReflectionClass $reflector, $class_name, array $arguments = array())
1311
+	{
1312
+		// let's examine the constructor
1313
+		$constructor = $this->mirror->getConstructorFromReflection($reflector);
1314
+		// whu? huh? nothing?
1315
+		if (! $constructor) {
1316
+			return $arguments;
1317
+		}
1318
+		// get constructor parameters
1319
+		$params = $this->mirror->getParametersFromReflection($reflector);
1320
+		// and the keys for the incoming arguments array so that we can compare existing arguments with what is expected
1321
+		$argument_keys = array_keys($arguments);
1322
+		// now loop thru all of the constructors expected parameters
1323
+		foreach ($params as $index => $param) {
1324
+			// is this a dependency for a specific class ?
1325
+			$param_class = $this->mirror->getParameterClassName($param, $class_name, $index);
1326
+			// BUT WAIT !!! This class may be an alias for something else (or getting replaced at runtime)
1327
+			$param_class = $this->class_cache->isAlias($param_class, $class_name)
1328
+				? $this->class_cache->getFqnForAlias($param_class, $class_name)
1329
+				: $param_class;
1330
+			if (// param is not even a class
1331
+				$param_class === null
1332
+				// and something already exists in the incoming arguments for this param
1333
+				&& array_key_exists($index, $argument_keys)
1334
+				&& array_key_exists($argument_keys[ $index ], $arguments)
1335
+			) {
1336
+				// so let's skip this argument and move on to the next
1337
+				continue;
1338
+			}
1339
+			if (// parameter is type hinted as a class, exists as an incoming argument, AND it's the correct class
1340
+				$param_class !== null
1341
+				&& isset($argument_keys[ $index ], $arguments[ $argument_keys[ $index ] ])
1342
+				&& $arguments[ $argument_keys[ $index ] ] instanceof $param_class
1343
+			) {
1344
+				// skip this argument and move on to the next
1345
+				continue;
1346
+			}
1347
+			if (// parameter is type hinted as a class, and should be injected
1348
+				$param_class !== null
1349
+				&& $this->_dependency_map->has_dependency_for_class($class_name, $param_class)
1350
+			) {
1351
+				$arguments = $this->_resolve_dependency(
1352
+					$class_name,
1353
+					$param_class,
1354
+					$arguments,
1355
+					$index
1356
+				);
1357
+			} else {
1358
+				$arguments[ $index ] = $this->mirror->getParameterDefaultValue(
1359
+					$param,
1360
+					$class_name,
1361
+					$index
1362
+				);
1363
+			}
1364
+		}
1365
+		return $arguments;
1366
+	}
1367
+
1368
+
1369
+	/**
1370
+	 * @param string $class_name
1371
+	 * @param string $param_class
1372
+	 * @param array  $arguments
1373
+	 * @param mixed  $index
1374
+	 * @return array
1375
+	 * @throws InvalidArgumentException
1376
+	 * @throws InvalidInterfaceException
1377
+	 * @throws InvalidDataTypeException
1378
+	 */
1379
+	protected function _resolve_dependency($class_name, $param_class, $arguments, $index)
1380
+	{
1381
+		$dependency = null;
1382
+		// should dependency be loaded from cache ?
1383
+		$cache_on = $this->_dependency_map->loading_strategy_for_class_dependency(
1384
+			$class_name,
1385
+			$param_class
1386
+		);
1387
+		$cache_on = $cache_on !== EE_Dependency_Map::load_new_object;
1388
+		// we might have a dependency...
1389
+		// let's MAYBE try and find it in our cache if that's what's been requested
1390
+		$cached_class = $cache_on
1391
+			? $this->_get_cached_class($param_class)
1392
+			: null;
1393
+		// and grab it if it exists
1394
+		if ($cached_class instanceof $param_class) {
1395
+			$dependency = $cached_class;
1396
+		} elseif ($param_class !== $class_name) {
1397
+			// obtain the loader method from the dependency map
1398
+			$loader = $this->_dependency_map->class_loader($param_class);
1399
+			// is loader a custom closure ?
1400
+			if ($loader instanceof Closure) {
1401
+				$dependency = $loader($arguments);
1402
+			} else {
1403
+				// set the cache on property for the recursive loading call
1404
+				$this->_cache_on = $cache_on;
1405
+				// if not, then let's try and load it via the registry
1406
+				if ($loader && method_exists($this, $loader)) {
1407
+					$dependency = $this->{$loader}($param_class);
1408
+				} else {
1409
+					$dependency = LoaderFactory::getLoader()->load(
1410
+						$param_class,
1411
+						array(),
1412
+						$cache_on
1413
+					);
1414
+				}
1415
+			}
1416
+		}
1417
+		// did we successfully find the correct dependency ?
1418
+		if ($dependency instanceof $param_class) {
1419
+			// then let's inject it into the incoming array of arguments at the correct location
1420
+			$arguments[ $index ] = $dependency;
1421
+		}
1422
+		return $arguments;
1423
+	}
1424
+
1425
+
1426
+	/**
1427
+	 * call any loader that's been registered in the EE_Dependency_Map::$_class_loaders array
1428
+	 *
1429
+	 * @param string $classname PLEASE NOTE: the class name needs to match what's registered
1430
+	 *                          in the EE_Dependency_Map::$_class_loaders array,
1431
+	 *                          including the class prefix, ie: "EE_", "EEM_", "EEH_", etc
1432
+	 * @param array  $arguments
1433
+	 * @return object
1434
+	 */
1435
+	public static function factory($classname, $arguments = array())
1436
+	{
1437
+		$loader = self::instance()->_dependency_map->class_loader($classname);
1438
+		if ($loader instanceof Closure) {
1439
+			return $loader($arguments);
1440
+		}
1441
+		if (method_exists(self::instance(), $loader)) {
1442
+			return self::instance()->{$loader}($classname, $arguments);
1443
+		}
1444
+		return null;
1445
+	}
1446
+
1447
+
1448
+	/**
1449
+	 * Gets the addon by its class name
1450
+	 *
1451
+	 * @param string $class_name
1452
+	 * @return EE_Addon
1453
+	 */
1454
+	public function getAddon($class_name)
1455
+	{
1456
+		$class_name = str_replace('\\', '_', $class_name);
1457
+		return $this->addons->{$class_name};
1458
+	}
1459
+
1460
+
1461
+	/**
1462
+	 * removes the addon from the internal cache
1463
+	 *
1464
+	 * @param string $class_name
1465
+	 * @return void
1466
+	 */
1467
+	public function removeAddon($class_name)
1468
+	{
1469
+		$class_name = str_replace('\\', '_', $class_name);
1470
+		unset($this->addons->{$class_name});
1471
+	}
1472
+
1473
+
1474
+	/**
1475
+	 * Gets the addon by its name/slug (not classname. For that, just
1476
+	 * use the get_addon() method above
1477
+	 *
1478
+	 * @param string $name
1479
+	 * @return EE_Addon
1480
+	 */
1481
+	public function get_addon_by_name($name)
1482
+	{
1483
+		foreach ($this->addons as $addon) {
1484
+			if ($addon->name() === $name) {
1485
+				return $addon;
1486
+			}
1487
+		}
1488
+		return null;
1489
+	}
1490
+
1491
+
1492
+	/**
1493
+	 * Gets an array of all the registered addons, where the keys are their names.
1494
+	 * (ie, what each returns for their name() function)
1495
+	 * They're already available on EE_Registry::instance()->addons as properties,
1496
+	 * where each property's name is the addon's classname,
1497
+	 * So if you just want to get the addon by classname,
1498
+	 * OR use the get_addon() method above.
1499
+	 * PLEASE  NOTE:
1500
+	 * addons with Fully Qualified Class Names
1501
+	 * have had the namespace separators converted to underscores,
1502
+	 * so a classname like Fully\Qualified\ClassName
1503
+	 * would have been converted to Fully_Qualified_ClassName
1504
+	 *
1505
+	 * @return EE_Addon[] where the KEYS are the addon's name()
1506
+	 */
1507
+	public function get_addons_by_name()
1508
+	{
1509
+		$addons = array();
1510
+		foreach ($this->addons as $addon) {
1511
+			$addons[ $addon->name() ] = $addon;
1512
+		}
1513
+		return $addons;
1514
+	}
1515
+
1516
+
1517
+	/**
1518
+	 * Resets the specified model's instance AND makes sure EE_Registry doesn't keep
1519
+	 * a stale copy of it around
1520
+	 *
1521
+	 * @param string $model_name
1522
+	 * @return \EEM_Base
1523
+	 * @throws \EE_Error
1524
+	 */
1525
+	public function reset_model($model_name)
1526
+	{
1527
+		$model_class_name = strpos($model_name, 'EEM_') !== 0
1528
+			? "EEM_{$model_name}"
1529
+			: $model_name;
1530
+		if (! isset($this->LIB->{$model_class_name}) || ! $this->LIB->{$model_class_name} instanceof EEM_Base) {
1531
+			return null;
1532
+		}
1533
+		// get that model reset it and make sure we nuke the old reference to it
1534
+		if ($this->LIB->{$model_class_name} instanceof $model_class_name
1535
+			&& is_callable(
1536
+				array($model_class_name, 'reset')
1537
+			)) {
1538
+			$this->LIB->{$model_class_name} = $this->LIB->{$model_class_name}->reset();
1539
+		} else {
1540
+			throw new EE_Error(
1541
+				sprintf(
1542
+					esc_html__('Model %s does not have a method "reset"', 'event_espresso'),
1543
+					$model_name
1544
+				)
1545
+			);
1546
+		}
1547
+		return $this->LIB->{$model_class_name};
1548
+	}
1549
+
1550
+
1551
+	/**
1552
+	 * Resets the registry.
1553
+	 * The criteria for what gets reset is based on what can be shared between sites on the same request when
1554
+	 * switch_to_blog is used in a multisite install.  Here is a list of things that are NOT reset.
1555
+	 * - $_dependency_map
1556
+	 * - $_class_abbreviations
1557
+	 * - $NET_CFG (EE_Network_Config): The config is shared network wide so no need to reset.
1558
+	 * - $REQ:  Still on the same request so no need to change.
1559
+	 * - $CAP: There is no site specific state in the EE_Capability class.
1560
+	 * - $SSN: Although ideally, the session should not be shared between site switches, we can't reset it because only
1561
+	 * one Session can be active in a single request.  Resetting could resolve in "headers already sent" errors.
1562
+	 * - $addons:  In multisite, the state of the addons is something controlled via hooks etc in a normal request.  So
1563
+	 *             for now, we won't reset the addons because it could break calls to an add-ons class/methods in the
1564
+	 *             switch or on the restore.
1565
+	 * - $modules
1566
+	 * - $shortcodes
1567
+	 * - $widgets
1568
+	 *
1569
+	 * @param boolean $hard             [deprecated]
1570
+	 * @param boolean $reinstantiate    whether to create new instances of EE_Registry's singletons too,
1571
+	 *                                  or just reset without re-instantiating (handy to set to FALSE if you're not
1572
+	 *                                  sure if you CAN currently reinstantiate the singletons at the moment)
1573
+	 * @param   bool  $reset_models     Defaults to true.  When false, then the models are not reset.  This is so
1574
+	 *                                  client
1575
+	 *                                  code instead can just change the model context to a different blog id if
1576
+	 *                                  necessary
1577
+	 * @return EE_Registry
1578
+	 * @throws InvalidInterfaceException
1579
+	 * @throws InvalidDataTypeException
1580
+	 * @throws EE_Error
1581
+	 * @throws ReflectionException
1582
+	 * @throws InvalidArgumentException
1583
+	 */
1584
+	public static function reset($hard = false, $reinstantiate = true, $reset_models = true)
1585
+	{
1586
+		$instance = self::instance();
1587
+		$instance->_cache_on = true;
1588
+		// reset some "special" classes
1589
+		EEH_Activation::reset();
1590
+		$hard = apply_filters('FHEE__EE_Registry__reset__hard', $hard);
1591
+		$instance->CFG = EE_Config::reset($hard, $reinstantiate);
1592
+		$instance->CART = null;
1593
+		$instance->MRM = null;
1594
+		$instance->AssetsRegistry = LoaderFactory::getLoader()->getShared(
1595
+			'EventEspresso\core\services\assets\Registry'
1596
+		);
1597
+		// messages reset
1598
+		EED_Messages::reset();
1599
+		// handle of objects cached on LIB
1600
+		foreach (array('LIB', 'modules') as $cache) {
1601
+			foreach ($instance->{$cache} as $class_name => $class) {
1602
+				if (self::_reset_and_unset_object($class, $reset_models)) {
1603
+					unset($instance->{$cache}->{$class_name});
1604
+				}
1605
+			}
1606
+		}
1607
+		return $instance;
1608
+	}
1609
+
1610
+
1611
+	/**
1612
+	 * if passed object implements ResettableInterface, then call it's reset() method
1613
+	 * if passed object implements InterminableInterface, then return false,
1614
+	 * to indicate that it should NOT be cleared from the Registry cache
1615
+	 *
1616
+	 * @param      $object
1617
+	 * @param bool $reset_models
1618
+	 * @return bool returns true if cached object should be unset
1619
+	 */
1620
+	private static function _reset_and_unset_object($object, $reset_models)
1621
+	{
1622
+		if (! is_object($object)) {
1623
+			// don't unset anything that's not an object
1624
+			return false;
1625
+		}
1626
+		if ($object instanceof EED_Module) {
1627
+			$object::reset();
1628
+			// don't unset modules
1629
+			return false;
1630
+		}
1631
+		if ($object instanceof ResettableInterface) {
1632
+			if ($object instanceof EEM_Base) {
1633
+				if ($reset_models) {
1634
+					$object->reset();
1635
+					return true;
1636
+				}
1637
+				return false;
1638
+			}
1639
+			$object->reset();
1640
+			return true;
1641
+		}
1642
+		if (! $object instanceof InterminableInterface) {
1643
+			return true;
1644
+		}
1645
+		return false;
1646
+	}
1647
+
1648
+
1649
+	/**
1650
+	 * Gets all the custom post type models defined
1651
+	 *
1652
+	 * @return array keys are model "short names" (Eg "Event") and keys are classnames (eg "EEM_Event")
1653
+	 */
1654
+	public function cpt_models()
1655
+	{
1656
+		$cpt_models = array();
1657
+		foreach ($this->non_abstract_db_models as $short_name => $classname) {
1658
+			if (is_subclass_of($classname, 'EEM_CPT_Base')) {
1659
+				$cpt_models[ $short_name ] = $classname;
1660
+			}
1661
+		}
1662
+		return $cpt_models;
1663
+	}
1664
+
1665
+
1666
+	/**
1667
+	 * @return \EE_Config
1668
+	 */
1669
+	public static function CFG()
1670
+	{
1671
+		return self::instance()->CFG;
1672
+	}
1673
+
1674
+
1675
+	/**
1676
+	 * @deprecated 4.9.62.p
1677
+	 * @param string $class_name
1678
+	 * @return ReflectionClass
1679
+	 * @throws ReflectionException
1680
+	 * @throws InvalidDataTypeException
1681
+	 */
1682
+	public function get_ReflectionClass($class_name)
1683
+	{
1684
+		return $this->mirror->getReflectionClass($class_name);
1685
+	}
1686 1686
 }
Please login to merge, or discard this patch.
core/services/assets/AssetManagerInterface.php 1 patch
Indentation   +81 added lines, -81 removed lines patch added patch discarded remove patch
@@ -20,85 +20,85 @@
 block discarded – undo
20 20
 interface AssetManagerInterface
21 21
 {
22 22
 
23
-    /**
24
-     * @since 4.9.62.p
25
-     */
26
-    public function addAssets();
27
-
28
-
29
-    /**
30
-     * @return ManifestFile
31
-     * @throws DuplicateCollectionIdentifierException
32
-     * @throws InvalidDataTypeException
33
-     * @throws InvalidEntityException
34
-     * @since 4.9.62.p
35
-     */
36
-    public function addManifestFile();
37
-
38
-
39
-    /**
40
-     * @return ManifestFile[]
41
-     * @since 4.9.62.p
42
-     */
43
-    public function getManifestFile();
44
-
45
-
46
-    /**
47
-     * @param string $handle
48
-     * @param string $source
49
-     * @param array  $dependencies
50
-     * @param bool   $load_in_footer
51
-     * @return JavascriptAsset
52
-     * @throws DuplicateCollectionIdentifierException
53
-     * @throws InvalidDataTypeException
54
-     * @throws InvalidEntityException
55
-     * @since 4.9.62.p
56
-     */
57
-    public function addJavascript(
58
-        $handle,
59
-        $source,
60
-        array $dependencies = array(),
61
-        $load_in_footer = true
62
-    );
63
-
64
-
65
-    /**
66
-     * @return JavascriptAsset[]
67
-     * @since 4.9.62.p
68
-     */
69
-    public function getJavascriptAssets();
70
-
71
-
72
-    /**
73
-     * @param string $handle
74
-     * @param string $source
75
-     * @param array  $dependencies
76
-     * @param string $media
77
-     * @return StylesheetAsset
78
-     * @throws DuplicateCollectionIdentifierException
79
-     * @throws InvalidDataTypeException
80
-     * @throws InvalidEntityException
81
-     * @since 4.9.62.p
82
-     */
83
-    public function addStylesheet(
84
-        $handle,
85
-        $source,
86
-        array $dependencies = array(),
87
-        $media = 'all'
88
-    );
89
-
90
-
91
-    /**
92
-     * @return StylesheetAsset[]
93
-     * @since 4.9.62.p
94
-     */
95
-    public function getStylesheetAssets();
96
-
97
-
98
-    /**
99
-     * @param string $handle
100
-     * @return bool
101
-     * @since 4.9.62.p
102
-     */
103
-    public function enqueueAsset($handle);
23
+	/**
24
+	 * @since 4.9.62.p
25
+	 */
26
+	public function addAssets();
27
+
28
+
29
+	/**
30
+	 * @return ManifestFile
31
+	 * @throws DuplicateCollectionIdentifierException
32
+	 * @throws InvalidDataTypeException
33
+	 * @throws InvalidEntityException
34
+	 * @since 4.9.62.p
35
+	 */
36
+	public function addManifestFile();
37
+
38
+
39
+	/**
40
+	 * @return ManifestFile[]
41
+	 * @since 4.9.62.p
42
+	 */
43
+	public function getManifestFile();
44
+
45
+
46
+	/**
47
+	 * @param string $handle
48
+	 * @param string $source
49
+	 * @param array  $dependencies
50
+	 * @param bool   $load_in_footer
51
+	 * @return JavascriptAsset
52
+	 * @throws DuplicateCollectionIdentifierException
53
+	 * @throws InvalidDataTypeException
54
+	 * @throws InvalidEntityException
55
+	 * @since 4.9.62.p
56
+	 */
57
+	public function addJavascript(
58
+		$handle,
59
+		$source,
60
+		array $dependencies = array(),
61
+		$load_in_footer = true
62
+	);
63
+
64
+
65
+	/**
66
+	 * @return JavascriptAsset[]
67
+	 * @since 4.9.62.p
68
+	 */
69
+	public function getJavascriptAssets();
70
+
71
+
72
+	/**
73
+	 * @param string $handle
74
+	 * @param string $source
75
+	 * @param array  $dependencies
76
+	 * @param string $media
77
+	 * @return StylesheetAsset
78
+	 * @throws DuplicateCollectionIdentifierException
79
+	 * @throws InvalidDataTypeException
80
+	 * @throws InvalidEntityException
81
+	 * @since 4.9.62.p
82
+	 */
83
+	public function addStylesheet(
84
+		$handle,
85
+		$source,
86
+		array $dependencies = array(),
87
+		$media = 'all'
88
+	);
89
+
90
+
91
+	/**
92
+	 * @return StylesheetAsset[]
93
+	 * @since 4.9.62.p
94
+	 */
95
+	public function getStylesheetAssets();
96
+
97
+
98
+	/**
99
+	 * @param string $handle
100
+	 * @return bool
101
+	 * @since 4.9.62.p
102
+	 */
103
+	public function enqueueAsset($handle);
104 104
 }
Please login to merge, or discard this patch.
core/services/assets/AssetManager.php 1 patch
Indentation   +157 added lines, -157 removed lines patch added patch discarded remove patch
@@ -21,161 +21,161 @@
 block discarded – undo
21 21
 abstract class AssetManager implements AssetManagerInterface
22 22
 {
23 23
 
24
-    /**
25
-     * @var AssetCollection $assets
26
-     */
27
-    protected $assets;
28
-
29
-    /**
30
-     * @var DomainInterface
31
-     */
32
-    protected $domain;
33
-
34
-    /**
35
-     * @var Registry $registry
36
-     */
37
-    protected $registry;
38
-
39
-
40
-    /**
41
-     * AssetRegister constructor.
42
-     *
43
-     * @param DomainInterface $domain
44
-     * @param AssetCollection $assets
45
-     * @param Registry        $registry
46
-     */
47
-    public function __construct(DomainInterface $domain, AssetCollection $assets, Registry $registry)
48
-    {
49
-        $this->domain = $domain;
50
-        $this->assets = $assets;
51
-        $this->registry = $registry;
52
-        add_action('wp_enqueue_scripts', array($this, 'addManifestFile'), 0);
53
-        add_action('admin_enqueue_scripts', array($this, 'addManifestFile'), 0);
54
-        add_action('wp_enqueue_scripts', array($this, 'addAssets'), 2);
55
-        add_action('admin_enqueue_scripts', array($this, 'addAssets'), 2);
56
-    }
57
-
58
-
59
-    /**
60
-     * @return void
61
-     * @throws DuplicateCollectionIdentifierException
62
-     * @throws InvalidDataTypeException
63
-     * @throws InvalidEntityException
64
-     * @since 4.9.62.p
65
-     */
66
-    public function addManifestFile()
67
-    {
68
-        // if a manifest file has already been added for this domain, then just return that one
69
-        if ($this->assets->has($this->domain->assetNamespace())) {
70
-            return;
71
-        }
72
-        $asset = new ManifestFile($this->domain);
73
-        $this->assets->add($asset, $this->domain->assetNamespace());
74
-    }
75
-
76
-
77
-    /**
78
-     * @return ManifestFile[]
79
-     * @since 4.9.62.p
80
-     */
81
-    public function getManifestFile()
82
-    {
83
-        return $this->assets->getManifestFiles();
84
-    }
85
-
86
-
87
-    /**
88
-     * @param string $handle
89
-     * @param string $source
90
-     * @param array  $dependencies
91
-     * @param bool   $load_in_footer
92
-     * @return JavascriptAsset
93
-     * @throws DuplicateCollectionIdentifierException
94
-     * @throws InvalidDataTypeException
95
-     * @throws InvalidEntityException
96
-     * @since 4.9.62.p
97
-     */
98
-    public function addJavascript(
99
-        $handle,
100
-        $source,
101
-        array $dependencies = array(),
102
-        $load_in_footer = true
103
-    ) {
104
-        $asset = new JavascriptAsset(
105
-            $handle,
106
-            $source,
107
-            $dependencies,
108
-            $load_in_footer,
109
-            $this->domain
110
-        );
111
-        $this->assets->add($asset, $handle);
112
-        return $asset;
113
-    }
114
-
115
-
116
-    /**
117
-     * @return JavascriptAsset[]
118
-     * @since 4.9.62.p
119
-     */
120
-    public function getJavascriptAssets()
121
-    {
122
-        return $this->assets->getJavascriptAssets();
123
-    }
124
-
125
-
126
-    /**
127
-     * @param string $handle
128
-     * @param string $source
129
-     * @param array  $dependencies
130
-     * @param string $media
131
-     * @return StylesheetAsset
132
-     * @throws DuplicateCollectionIdentifierException
133
-     * @throws InvalidDataTypeException
134
-     * @throws InvalidEntityException
135
-     * @since 4.9.62.p
136
-     */
137
-    public function addStylesheet(
138
-        $handle,
139
-        $source,
140
-        array $dependencies = array(),
141
-        $media = 'all'
142
-    ) {
143
-        $asset = new StylesheetAsset(
144
-            $handle,
145
-            $source,
146
-            $dependencies,
147
-            $this->domain,
148
-            $media
149
-        );
150
-        $this->assets->add($asset, $handle);
151
-        return $asset;
152
-    }
153
-
154
-
155
-    /**
156
-     * @return StylesheetAsset[]
157
-     * @since 4.9.62.p
158
-     */
159
-    public function getStylesheetAssets()
160
-    {
161
-        return $this->assets->getStylesheetAssets();
162
-    }
163
-
164
-
165
-    /**
166
-     * @param string $handle
167
-     * @return bool
168
-     * @since 4.9.62.p
169
-     */
170
-    public function enqueueAsset($handle)
171
-    {
172
-        if ($this->assets->has($handle)) {
173
-            $asset = $this->assets->get($handle);
174
-            if ($asset->isRegistered()) {
175
-                $asset->enqueueAsset();
176
-                return true;
177
-            }
178
-        }
179
-        return false;
180
-    }
24
+	/**
25
+	 * @var AssetCollection $assets
26
+	 */
27
+	protected $assets;
28
+
29
+	/**
30
+	 * @var DomainInterface
31
+	 */
32
+	protected $domain;
33
+
34
+	/**
35
+	 * @var Registry $registry
36
+	 */
37
+	protected $registry;
38
+
39
+
40
+	/**
41
+	 * AssetRegister constructor.
42
+	 *
43
+	 * @param DomainInterface $domain
44
+	 * @param AssetCollection $assets
45
+	 * @param Registry        $registry
46
+	 */
47
+	public function __construct(DomainInterface $domain, AssetCollection $assets, Registry $registry)
48
+	{
49
+		$this->domain = $domain;
50
+		$this->assets = $assets;
51
+		$this->registry = $registry;
52
+		add_action('wp_enqueue_scripts', array($this, 'addManifestFile'), 0);
53
+		add_action('admin_enqueue_scripts', array($this, 'addManifestFile'), 0);
54
+		add_action('wp_enqueue_scripts', array($this, 'addAssets'), 2);
55
+		add_action('admin_enqueue_scripts', array($this, 'addAssets'), 2);
56
+	}
57
+
58
+
59
+	/**
60
+	 * @return void
61
+	 * @throws DuplicateCollectionIdentifierException
62
+	 * @throws InvalidDataTypeException
63
+	 * @throws InvalidEntityException
64
+	 * @since 4.9.62.p
65
+	 */
66
+	public function addManifestFile()
67
+	{
68
+		// if a manifest file has already been added for this domain, then just return that one
69
+		if ($this->assets->has($this->domain->assetNamespace())) {
70
+			return;
71
+		}
72
+		$asset = new ManifestFile($this->domain);
73
+		$this->assets->add($asset, $this->domain->assetNamespace());
74
+	}
75
+
76
+
77
+	/**
78
+	 * @return ManifestFile[]
79
+	 * @since 4.9.62.p
80
+	 */
81
+	public function getManifestFile()
82
+	{
83
+		return $this->assets->getManifestFiles();
84
+	}
85
+
86
+
87
+	/**
88
+	 * @param string $handle
89
+	 * @param string $source
90
+	 * @param array  $dependencies
91
+	 * @param bool   $load_in_footer
92
+	 * @return JavascriptAsset
93
+	 * @throws DuplicateCollectionIdentifierException
94
+	 * @throws InvalidDataTypeException
95
+	 * @throws InvalidEntityException
96
+	 * @since 4.9.62.p
97
+	 */
98
+	public function addJavascript(
99
+		$handle,
100
+		$source,
101
+		array $dependencies = array(),
102
+		$load_in_footer = true
103
+	) {
104
+		$asset = new JavascriptAsset(
105
+			$handle,
106
+			$source,
107
+			$dependencies,
108
+			$load_in_footer,
109
+			$this->domain
110
+		);
111
+		$this->assets->add($asset, $handle);
112
+		return $asset;
113
+	}
114
+
115
+
116
+	/**
117
+	 * @return JavascriptAsset[]
118
+	 * @since 4.9.62.p
119
+	 */
120
+	public function getJavascriptAssets()
121
+	{
122
+		return $this->assets->getJavascriptAssets();
123
+	}
124
+
125
+
126
+	/**
127
+	 * @param string $handle
128
+	 * @param string $source
129
+	 * @param array  $dependencies
130
+	 * @param string $media
131
+	 * @return StylesheetAsset
132
+	 * @throws DuplicateCollectionIdentifierException
133
+	 * @throws InvalidDataTypeException
134
+	 * @throws InvalidEntityException
135
+	 * @since 4.9.62.p
136
+	 */
137
+	public function addStylesheet(
138
+		$handle,
139
+		$source,
140
+		array $dependencies = array(),
141
+		$media = 'all'
142
+	) {
143
+		$asset = new StylesheetAsset(
144
+			$handle,
145
+			$source,
146
+			$dependencies,
147
+			$this->domain,
148
+			$media
149
+		);
150
+		$this->assets->add($asset, $handle);
151
+		return $asset;
152
+	}
153
+
154
+
155
+	/**
156
+	 * @return StylesheetAsset[]
157
+	 * @since 4.9.62.p
158
+	 */
159
+	public function getStylesheetAssets()
160
+	{
161
+		return $this->assets->getStylesheetAssets();
162
+	}
163
+
164
+
165
+	/**
166
+	 * @param string $handle
167
+	 * @return bool
168
+	 * @since 4.9.62.p
169
+	 */
170
+	public function enqueueAsset($handle)
171
+	{
172
+		if ($this->assets->has($handle)) {
173
+			$asset = $this->assets->get($handle);
174
+			if ($asset->isRegistered()) {
175
+				$asset->enqueueAsset();
176
+				return true;
177
+			}
178
+		}
179
+		return false;
180
+	}
181 181
 }
Please login to merge, or discard this patch.