Completed
Branch master (0c34ee)
by
unknown
11:49 queued 09:41
created
registration_form/espresso_events_Registration_Form_Hooks.class.php 1 patch
Indentation   +196 added lines, -196 removed lines patch added patch discarded remove patch
@@ -16,95 +16,95 @@  discard block
 block discarded – undo
16 16
 class espresso_events_Registration_Form_Hooks extends EE_Admin_Hooks
17 17
 {
18 18
 
19
-    /**
20
-     * @var EE_Event|null
21
-     */
22
-    protected $_event;
23
-
24
-
25
-    protected function _set_hooks_properties()
26
-    {
27
-
28
-        $this->_name      = 'registration_form';
29
-        $this->_metaboxes = [
30
-            0 => [
31
-                'page_route' => ['edit', 'create_new'],
32
-                'func'       => 'primary_questions',
33
-                'label'      => esc_html__('Questions for Primary Registrant', 'event_espresso'),
34
-                'priority'   => 'default',
35
-                'context'    => 'side',
36
-            ],
37
-        ];
38
-
39
-        // hook into the handler for saving question groups
40
-        add_filter(
41
-            'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
42
-            [$this, 'modify_callbacks'],
43
-            10
44
-        );
45
-
46
-        // hook into revision restores (we're hooking into the global action because EE_Admin_Hooks classes are already
47
-        // restricted by page)
48
-        add_action('AHEE_EE_Admin_Page_CPT__restore_revision', [$this, 'restore_revision'], 10, 2);
49
-    }
50
-
51
-
52
-    /**
53
-     * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
54
-     *
55
-     * @param $callbacks
56
-     * @return array
57
-     */
58
-    public function modify_callbacks($callbacks)
59
-    {
60
-        // now let's add the question group callback
61
-        $callbacks[] = [$this, 'primary_question_group_update'];
62
-        return $callbacks;
63
-    }
64
-
65
-
66
-    /**
67
-     * Hooked into revision restores.
68
-     *
69
-     * @param $post_id
70
-     * @param $revision_id
71
-     * @return EE_Base_Class
72
-     * @throws EE_Error
73
-     * @throws InvalidArgumentException
74
-     * @throws InvalidDataTypeException
75
-     * @throws InvalidInterfaceException
76
-     */
77
-    public function restore_revision($post_id, $revision_id)
78
-    {
79
-        $post_evt = EEM_Event::instance()->get_one_by_ID($post_id);
80
-        // restore revision for primary questions
81
-        if ($post_evt instanceof EE_Event) {
82
-            $post_evt->restore_revision(
83
-                $revision_id,
84
-                ['Question_Group'],
85
-                ['Question_Group' => ['Event_Question_Group.EQG_primary' => true]]
86
-            );
87
-        }
88
-        return $post_evt;
89
-    }
90
-
91
-
92
-    /**
93
-     * Content of metabox.
94
-     *
95
-     * @param $post_id
96
-     * @param $post
97
-     * @throws EE_Error
98
-     * @throws InvalidArgumentException
99
-     * @throws InvalidDataTypeException
100
-     * @throws InvalidInterfaceException
101
-     * @throws ReflectionException
102
-     */
103
-    public function primary_questions($post_id, $post)
104
-    {
105
-        $this->_event = $this->_adminpage_obj->get_event_object();
106
-        $event_id     = $this->_event->ID();
107
-        ?>
19
+	/**
20
+	 * @var EE_Event|null
21
+	 */
22
+	protected $_event;
23
+
24
+
25
+	protected function _set_hooks_properties()
26
+	{
27
+
28
+		$this->_name      = 'registration_form';
29
+		$this->_metaboxes = [
30
+			0 => [
31
+				'page_route' => ['edit', 'create_new'],
32
+				'func'       => 'primary_questions',
33
+				'label'      => esc_html__('Questions for Primary Registrant', 'event_espresso'),
34
+				'priority'   => 'default',
35
+				'context'    => 'side',
36
+			],
37
+		];
38
+
39
+		// hook into the handler for saving question groups
40
+		add_filter(
41
+			'FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks',
42
+			[$this, 'modify_callbacks'],
43
+			10
44
+		);
45
+
46
+		// hook into revision restores (we're hooking into the global action because EE_Admin_Hooks classes are already
47
+		// restricted by page)
48
+		add_action('AHEE_EE_Admin_Page_CPT__restore_revision', [$this, 'restore_revision'], 10, 2);
49
+	}
50
+
51
+
52
+	/**
53
+	 * Callback for FHEE__Events_Admin_Page___insert_update_cpt_item__event_update_callbacks hook
54
+	 *
55
+	 * @param $callbacks
56
+	 * @return array
57
+	 */
58
+	public function modify_callbacks($callbacks)
59
+	{
60
+		// now let's add the question group callback
61
+		$callbacks[] = [$this, 'primary_question_group_update'];
62
+		return $callbacks;
63
+	}
64
+
65
+
66
+	/**
67
+	 * Hooked into revision restores.
68
+	 *
69
+	 * @param $post_id
70
+	 * @param $revision_id
71
+	 * @return EE_Base_Class
72
+	 * @throws EE_Error
73
+	 * @throws InvalidArgumentException
74
+	 * @throws InvalidDataTypeException
75
+	 * @throws InvalidInterfaceException
76
+	 */
77
+	public function restore_revision($post_id, $revision_id)
78
+	{
79
+		$post_evt = EEM_Event::instance()->get_one_by_ID($post_id);
80
+		// restore revision for primary questions
81
+		if ($post_evt instanceof EE_Event) {
82
+			$post_evt->restore_revision(
83
+				$revision_id,
84
+				['Question_Group'],
85
+				['Question_Group' => ['Event_Question_Group.EQG_primary' => true]]
86
+			);
87
+		}
88
+		return $post_evt;
89
+	}
90
+
91
+
92
+	/**
93
+	 * Content of metabox.
94
+	 *
95
+	 * @param $post_id
96
+	 * @param $post
97
+	 * @throws EE_Error
98
+	 * @throws InvalidArgumentException
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws InvalidInterfaceException
101
+	 * @throws ReflectionException
102
+	 */
103
+	public function primary_questions($post_id, $post)
104
+	{
105
+		$this->_event = $this->_adminpage_obj->get_event_object();
106
+		$event_id     = $this->_event->ID();
107
+		?>
108 108
         <div class="inside">
109 109
             <p>
110 110
                 <strong>
@@ -112,64 +112,64 @@  discard block
 block discarded – undo
112 112
                 </strong>
113 113
                 <br />
114 114
                 <?php
115
-                printf(
116
-                    esc_html__(
117
-                        'Add a pre-populated %1$sgroup of questions%2$s to your event. The personal information group is required for all events',
118
-                        'event_espresso'
119
-                    ),
120
-                    '<a href="admin.php?page=espresso_registration_form" target="_blank">',
121
-                    '</a>'
122
-                )
123
-                ?>
115
+				printf(
116
+					esc_html__(
117
+						'Add a pre-populated %1$sgroup of questions%2$s to your event. The personal information group is required for all events',
118
+						'event_espresso'
119
+					),
120
+					'<a href="admin.php?page=espresso_registration_form" target="_blank">',
121
+					'</a>'
122
+				)
123
+				?>
124 124
             </p>
125 125
             <?php
126 126
 
127
-            $qsg_where['QSG_deleted'] = false;
128
-            $query_params             = apply_filters(
129
-                'FHEE__espresso_events_Registration_Form_Hooks__primary_questions__question_group_query_parameters',
130
-                [$qsg_where, 'order_by' => ['QSG_order' => 'ASC']]
131
-            );
132
-            $QSGs                     = EEM_Question_Group::instance()->get_all($query_params);
133
-            $EQGs                     = ! empty($event_id)
134
-                ? $this->_event->get_many_related(
135
-                    'Question_Group',
136
-                    [['Event_Question_Group.EQG_primary' => true]]
137
-                )
138
-                : [];
139
-            $EQGids                   = array_keys($EQGs);
140
-
141
-            if (! empty($QSGs)) {
142
-                $html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
143
-                foreach ($QSGs as $QSG) {
144
-                    $QSG_ID          = absint($QSG->ID());
145
-                    $checked         = in_array($QSG_ID, $EQGids, true) || $QSG->get('QSG_system') === 1
146
-                        ? ' checked="checked"'
147
-                        : '';
148
-                    $visibility      = $QSG->get('QSG_system') === 1
149
-                        ? ' style="visibility:hidden"'
150
-                        : '';
151
-                    $edit_query_args = $this->_adminpage_obj->is_caf()
152
-                        ? [
153
-                            'action' => 'edit_question_group',
154
-                            'QSG_ID' => $QSG_ID,
155
-                        ]
156
-                        : ['action' => 'question_groups'];
157
-                    $edit_link       = EE_Admin_Page::add_query_args_and_nonce(
158
-                        $edit_query_args,
159
-                        EE_FORMS_ADMIN_URL
160
-                    );
161
-                    $edit_link_title = sprintf(
162
-                        esc_attr__('Edit %s Group', 'event_espresso'),
163
-                        $QSG->get('QSG_name')
164
-                    );
165
-
166
-                    $html .= '
127
+			$qsg_where['QSG_deleted'] = false;
128
+			$query_params             = apply_filters(
129
+				'FHEE__espresso_events_Registration_Form_Hooks__primary_questions__question_group_query_parameters',
130
+				[$qsg_where, 'order_by' => ['QSG_order' => 'ASC']]
131
+			);
132
+			$QSGs                     = EEM_Question_Group::instance()->get_all($query_params);
133
+			$EQGs                     = ! empty($event_id)
134
+				? $this->_event->get_many_related(
135
+					'Question_Group',
136
+					[['Event_Question_Group.EQG_primary' => true]]
137
+				)
138
+				: [];
139
+			$EQGids                   = array_keys($EQGs);
140
+
141
+			if (! empty($QSGs)) {
142
+				$html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
143
+				foreach ($QSGs as $QSG) {
144
+					$QSG_ID          = absint($QSG->ID());
145
+					$checked         = in_array($QSG_ID, $EQGids, true) || $QSG->get('QSG_system') === 1
146
+						? ' checked="checked"'
147
+						: '';
148
+					$visibility      = $QSG->get('QSG_system') === 1
149
+						? ' style="visibility:hidden"'
150
+						: '';
151
+					$edit_query_args = $this->_adminpage_obj->is_caf()
152
+						? [
153
+							'action' => 'edit_question_group',
154
+							'QSG_ID' => $QSG_ID,
155
+						]
156
+						: ['action' => 'question_groups'];
157
+					$edit_link       = EE_Admin_Page::add_query_args_and_nonce(
158
+						$edit_query_args,
159
+						EE_FORMS_ADMIN_URL
160
+					);
161
+					$edit_link_title = sprintf(
162
+						esc_attr__('Edit %s Group', 'event_espresso'),
163
+						$QSG->get('QSG_name')
164
+					);
165
+
166
+					$html .= '
167 167
 					<p id="event-question-group-' . $QSG_ID . '">
168 168
 						<input value="' . $QSG_ID . '" 
169 169
 						    type="checkbox"
170 170
 						    name="question_groups[' . $QSG_ID . ']" '
171
-                             . $visibility
172
-                             . $checked . ' 
171
+							 . $visibility
172
+							 . $checked . ' 
173 173
                         />
174 174
 						<a href="' . esc_url_raw($edit_link) . '" 
175 175
 						    title="' . esc_attr($edit_link_title) . '" 
@@ -178,62 +178,62 @@  discard block
 block discarded – undo
178 178
 						    ' . $QSG->get('QSG_name') . '
179 179
                         </a>
180 180
 					</p>';
181
-                }
182
-                $html .= count($QSGs) > 10 ? '</div>' : '';
183
-                echo wp_kses($html, AllowedTags::getWithFormTags());
184
-            } else {
185
-                esc_html_e(
186
-                    'There seems to be a problem with your questions. Please contact [email protected]',
187
-                    'event_espresso'
188
-                );
189
-            }
190
-            do_action('AHEE_event_editor_questions_notice');
191
-            ?>
181
+				}
182
+				$html .= count($QSGs) > 10 ? '</div>' : '';
183
+				echo wp_kses($html, AllowedTags::getWithFormTags());
184
+			} else {
185
+				esc_html_e(
186
+					'There seems to be a problem with your questions. Please contact [email protected]',
187
+					'event_espresso'
188
+				);
189
+			}
190
+			do_action('AHEE_event_editor_questions_notice');
191
+			?>
192 192
         </div>
193 193
         <?php
194
-    }
195
-
196
-
197
-    /**
198
-     * @param EE_Event $event
199
-     * @param array    $data
200
-     * @return bool
201
-     * @throws EE_Error
202
-     * @throws ReflectionException
203
-     */
204
-    public function primary_question_group_update($event, $data)
205
-    {
206
-        $question_groups = ! empty($data['question_groups']) ? (array) $data['question_groups'] : [];
207
-        $added_qgs       = array_keys($question_groups);
208
-        $success         = true;
209
-
210
-        // let's get all current question groups associated with this event.
211
-        $current_qgs = $event->get_many_related(
212
-            'Question_Group',
213
-            [['Event_Question_Group.EQG_primary' => true]]
214
-        );
215
-        $current_qgs = array_keys($current_qgs); // we just want the ids
216
-
217
-        // now let's get the groups selected in the editor and update (IF we have data)
218
-        if (! empty($question_groups)) {
219
-            foreach ($question_groups as $QSG_ID => $val) {
220
-                // add to event
221
-                if ($val) {
222
-                    $qg = $event->_add_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
223
-                }
224
-                // trip success to false if result is empty
225
-                $success = ! empty($qg) ? $success : false;
226
-            }
227
-        }
228
-
229
-        // wait a minute... are there question groups missing in the saved groups that ARE with the current event?
230
-        $removed_qgs = array_diff($current_qgs, $added_qgs);
231
-
232
-        foreach ($removed_qgs as $QSG_ID) {
233
-            $qg = $event->_remove_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
234
-            // trip success to false if result is empty
235
-            $success = ! empty($qg) ? $success : false;
236
-        }
237
-        return $success;
238
-    }
194
+	}
195
+
196
+
197
+	/**
198
+	 * @param EE_Event $event
199
+	 * @param array    $data
200
+	 * @return bool
201
+	 * @throws EE_Error
202
+	 * @throws ReflectionException
203
+	 */
204
+	public function primary_question_group_update($event, $data)
205
+	{
206
+		$question_groups = ! empty($data['question_groups']) ? (array) $data['question_groups'] : [];
207
+		$added_qgs       = array_keys($question_groups);
208
+		$success         = true;
209
+
210
+		// let's get all current question groups associated with this event.
211
+		$current_qgs = $event->get_many_related(
212
+			'Question_Group',
213
+			[['Event_Question_Group.EQG_primary' => true]]
214
+		);
215
+		$current_qgs = array_keys($current_qgs); // we just want the ids
216
+
217
+		// now let's get the groups selected in the editor and update (IF we have data)
218
+		if (! empty($question_groups)) {
219
+			foreach ($question_groups as $QSG_ID => $val) {
220
+				// add to event
221
+				if ($val) {
222
+					$qg = $event->_add_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
223
+				}
224
+				// trip success to false if result is empty
225
+				$success = ! empty($qg) ? $success : false;
226
+			}
227
+		}
228
+
229
+		// wait a minute... are there question groups missing in the saved groups that ARE with the current event?
230
+		$removed_qgs = array_diff($current_qgs, $added_qgs);
231
+
232
+		foreach ($removed_qgs as $QSG_ID) {
233
+			$qg = $event->_remove_relation_to($QSG_ID, 'Question_Group', ['EQG_primary' => true]);
234
+			// trip success to false if result is empty
235
+			$success = ! empty($qg) ? $success : false;
236
+		}
237
+		return $success;
238
+	}
239 239
 }
Please login to merge, or discard this patch.
admin_pages/payments/Payments_Admin_Page.core.php 2 patches
Indentation   +1191 added lines, -1191 removed lines patch added patch discarded remove patch
@@ -16,1195 +16,1195 @@
 block discarded – undo
16 16
 class Payments_Admin_Page extends EE_Admin_Page
17 17
 {
18 18
 
19
-    /**
20
-     * Variables used for when we're re-sorting the logs results,
21
-     * in case we needed to do two queries, and we need to resort
22
-     *
23
-     * @var string
24
-     */
25
-    private $_sort_logs_again_direction;
26
-
27
-
28
-    /**
29
-     * @Constructor
30
-     * @access public
31
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
32
-     * @throws EE_Error
33
-     * @throws InvalidArgumentException
34
-     * @throws InvalidDataTypeException
35
-     * @throws InvalidInterfaceException
36
-     * @throws ReflectionException
37
-     */
38
-    public function __construct($routing = true)
39
-    {
40
-        parent::__construct($routing);
41
-    }
42
-
43
-
44
-    protected function _init_page_props()
45
-    {
46
-        $this->page_slug = EE_PAYMENTS_PG_SLUG;
47
-        $this->page_label = esc_html__('Payment Methods', 'event_espresso');
48
-        $this->_admin_base_url = EE_PAYMENTS_ADMIN_URL;
49
-        $this->_admin_base_path = EE_PAYMENTS_ADMIN;
50
-    }
51
-
52
-
53
-    protected function _ajax_hooks()
54
-    {
55
-        // todo: all hooks for ajax goes here.
56
-    }
57
-
58
-
59
-    protected function _define_page_props()
60
-    {
61
-        $this->_admin_page_title = $this->page_label;
62
-        $this->_labels = array(
63
-            'publishbox' => esc_html__('Update Settings', 'event_espresso'),
64
-        );
65
-    }
66
-
67
-
68
-    protected function _set_page_routes()
69
-    {
70
-        /**
71
-         * note that with payment method capabilities, although we've implemented
72
-         * capability mapping which will be used for accessing payment methods owned by
73
-         * other users.  This is not fully implemented yet in the payment method ui.
74
-         * Currently, only the "plural" caps are in active use.
75
-         * When cap mapping is implemented, some routes will need to use the singular form of
76
-         * capability method and also include the $id of the payment method for the route.
77
-         **/
78
-        $this->_page_routes = array(
79
-            'default'                   => array(
80
-                'func'       => '_payment_methods_list',
81
-                'capability' => 'ee_edit_payment_methods',
82
-            ),
83
-            'payment_settings'          => array(
84
-                'func'       => '_payment_settings',
85
-                'capability' => 'ee_manage_gateways',
86
-            ),
87
-            'activate_payment_method'   => array(
88
-                'func'       => '_activate_payment_method',
89
-                'noheader'   => true,
90
-                'capability' => 'ee_edit_payment_methods',
91
-            ),
92
-            'deactivate_payment_method' => array(
93
-                'func'       => '_deactivate_payment_method',
94
-                'noheader'   => true,
95
-                'capability' => 'ee_delete_payment_methods',
96
-            ),
97
-            'update_payment_method'     => array(
98
-                'func'               => '_update_payment_method',
99
-                'noheader'           => true,
100
-                'headers_sent_route' => 'default',
101
-                'capability'         => 'ee_edit_payment_methods',
102
-            ),
103
-            'update_payment_settings'   => array(
104
-                'func'       => '_update_payment_settings',
105
-                'noheader'   => true,
106
-                'capability' => 'ee_manage_gateways',
107
-            ),
108
-            'payment_log'               => array(
109
-                'func'       => '_payment_log_overview_list_table',
110
-                'capability' => 'ee_read_payment_methods',
111
-            ),
112
-            'payment_log_details'       => array(
113
-                'func'       => '_payment_log_details',
114
-                'capability' => 'ee_read_payment_methods',
115
-            ),
116
-        );
117
-    }
118
-
119
-
120
-    /**
121
-     * @throws EE_Error
122
-     * @throws ReflectionException
123
-     */
124
-    protected function _set_page_config()
125
-    {
126
-        $payment_method_list_config = array(
127
-            'nav'           => array(
128
-                'label' => esc_html__('Payment Methods', 'event_espresso'),
129
-                'order' => 10,
130
-            ),
131
-            'metaboxes'     => $this->_default_espresso_metaboxes,
132
-            'help_tabs'     => array_merge(
133
-                array(
134
-                    'payment_methods_overview_help_tab' => array(
135
-                        'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
136
-                        'filename' => 'payment_methods_overview',
137
-                    ),
138
-                ),
139
-                $this->_add_payment_method_help_tabs()
140
-            ),
141
-            'require_nonce' => false,
142
-        );
143
-        $this->_page_config = array(
144
-            'default'          => $payment_method_list_config,
145
-            'payment_settings' => array(
146
-                'nav'           => array(
147
-                    'label' => esc_html__('Settings', 'event_espresso'),
148
-                    'order' => 20,
149
-                ),
150
-                'help_tabs'     => array(
151
-                    'payment_methods_settings_help_tab' => array(
152
-                        'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
153
-                        'filename' => 'payment_methods_settings',
154
-                    ),
155
-                ),
156
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
157
-                'require_nonce' => false,
158
-            ),
159
-            'payment_log'      => array(
160
-                'nav'           => array(
161
-                    'label' => esc_html__("Logs", 'event_espresso'),
162
-                    'order' => 30,
163
-                ),
164
-                'list_table'    => 'Payment_Log_Admin_List_Table',
165
-                'metaboxes'     => $this->_default_espresso_metaboxes,
166
-                'require_nonce' => false,
167
-            ),
168
-        );
169
-    }
170
-
171
-
172
-    /**
173
-     * @return array
174
-     * @throws DomainException
175
-     * @throws EE_Error
176
-     * @throws InvalidArgumentException
177
-     * @throws InvalidDataTypeException
178
-     * @throws InvalidInterfaceException
179
-     * @throws ReflectionException
180
-     */
181
-    protected function _add_payment_method_help_tabs()
182
-    {
183
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
184
-        $payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types();
185
-        $all_pmt_help_tabs_config = array();
186
-        foreach ($payment_method_types as $payment_method_type) {
187
-            if (
188
-                ! EE_Registry::instance()->CAP->current_user_can(
189
-                    $payment_method_type->cap_name(),
190
-                    'specific_payment_method_type_access'
191
-                )
192
-            ) {
193
-                continue;
194
-            }
195
-            foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
196
-                $template_args = isset($config['template_args']) ? $config['template_args'] : array();
197
-                $template_args['admin_page_obj'] = $this;
198
-                $all_pmt_help_tabs_config[ $help_tab_name ] = array(
199
-                    'title'   => $config['title'],
200
-                    'content' => EEH_Template::display_template(
201
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
202
-                        $template_args,
203
-                        true
204
-                    ),
205
-                );
206
-            }
207
-        }
208
-        return $all_pmt_help_tabs_config;
209
-    }
210
-
211
-
212
-    // none of the below group are currently used for Gateway Settings
213
-    protected function _add_screen_options()
214
-    {
215
-    }
216
-
217
-
218
-    protected function _add_feature_pointers()
219
-    {
220
-    }
221
-
222
-
223
-    public function admin_init()
224
-    {
225
-    }
226
-
227
-
228
-    public function admin_notices()
229
-    {
230
-    }
231
-
232
-
233
-    public function admin_footer_scripts()
234
-    {
235
-    }
236
-
237
-
238
-    public function load_scripts_styles()
239
-    {
240
-        // styles
241
-        wp_enqueue_style('espresso-ui-theme');
242
-        // scripts
243
-        wp_enqueue_script('ee_admin_js');
244
-        wp_enqueue_script('ee-text-links');
245
-        wp_enqueue_script(
246
-            'espresso_payments',
247
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
248
-            array('ee-datepicker'),
249
-            EVENT_ESPRESSO_VERSION,
250
-            true
251
-        );
252
-    }
253
-
254
-
255
-    public function load_scripts_styles_default()
256
-    {
257
-        // styles
258
-        wp_register_style(
259
-            'espresso_payments',
260
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
261
-            array(),
262
-            EVENT_ESPRESSO_VERSION
263
-        );
264
-        wp_enqueue_style('espresso_payments');
265
-        wp_enqueue_style('ee-text-links');
266
-        // scripts
267
-    }
268
-
269
-
270
-    /**
271
-     * @throws EE_Error
272
-     * @throws ReflectionException
273
-     */
274
-    protected function _payment_methods_list()
275
-    {
276
-        /**
277
-         * first let's ensure payment methods have been set up.
278
-         * We do this here because when people activate a payment method for the first time (as an addon),
279
-         * it may not set up its capabilities or get registered correctly due to the loading process.
280
-         * However, people MUST set up the details for the payment method,
281
-         * so it's safe to do a recheck here.
282
-         */
283
-        EE_Registry::instance()->load_lib('Payment_Method_Manager');
284
-        EEM_Payment_Method::instance()->verify_button_urls();
285
-        // set up tabs, one for each payment method type
286
-        $tabs = array();
287
-        $payment_methods = array();
288
-        foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
289
-            // we don't want to show admin-only PMTs for now
290
-            if ($pmt_obj instanceof EE_PMT_Admin_Only) {
291
-                continue;
292
-            }
293
-            // check access
294
-            if (
295
-                ! EE_Registry::instance()->CAP->current_user_can(
296
-                    $pmt_obj->cap_name(),
297
-                    'specific_payment_method_type_access'
298
-                )
299
-            ) {
300
-                continue;
301
-            }
302
-            // check for any active pms of that type
303
-            $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
304
-            if (! $payment_method instanceof EE_Payment_Method) {
305
-                $payment_method = EE_Payment_Method::new_instance(
306
-                    array(
307
-                        'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
308
-                        'PMD_type'       => $pmt_obj->system_name(),
309
-                        'PMD_name'       => $pmt_obj->pretty_name(),
310
-                        'PMD_admin_name' => $pmt_obj->pretty_name(),
311
-                    )
312
-                );
313
-            }
314
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
315
-        }
316
-        $payment_methods = apply_filters(
317
-            'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
318
-            $payment_methods
319
-        );
320
-        foreach ($payment_methods as $payment_method) {
321
-            if ($payment_method instanceof EE_Payment_Method) {
322
-                add_meta_box(
323
-                    // html id
324
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
325
-                    // title
326
-                    sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
327
-                    // callback
328
-                    array($this, 'payment_method_settings_meta_box'),
329
-                    // post type
330
-                    null,
331
-                    // context
332
-                    'normal',
333
-                    // priority
334
-                    'default',
335
-                    // callback args
336
-                    array('payment_method' => $payment_method)
337
-                );
338
-                // setup for tabbed content
339
-                $tabs[ $payment_method->slug() ] = array(
340
-                    'label' => $payment_method->admin_name(),
341
-                    'class' => $payment_method->active() ? 'gateway-active' : '',
342
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
343
-                    'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
344
-                    'slug'  => $payment_method->slug(),
345
-                );
346
-            }
347
-        }
348
-        $this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
349
-            $tabs,
350
-            'payment_method_links',
351
-            '|',
352
-            $this->_get_active_payment_method_slug()
353
-        );
354
-        $this->display_admin_page_with_sidebar();
355
-    }
356
-
357
-
358
-    /**
359
-     *   _get_active_payment_method_slug
360
-     *
361
-     * @return string
362
-     * @throws EE_Error
363
-     */
364
-    protected function _get_active_payment_method_slug()
365
-    {
366
-        $payment_method_slug = false;
367
-        // decide which payment method tab to open first, as dictated by the request's 'payment_method'
368
-        if (isset($this->_req_data['payment_method'])) {
369
-            // if they provided the current payment method, use it
370
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
371
-        }
372
-        /** @var EE_Payment_Method $payment_method */
373
-        $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug)));
374
-        // if that didn't work or wasn't provided, find another way to select the current pm
375
-        if (! $this->_verify_payment_method($payment_method)) {
376
-            // like, looking for an active one
377
-            $payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
378
-            // test that one as well
379
-            if ($this->_verify_payment_method($payment_method)) {
380
-                $payment_method_slug = $payment_method->slug();
381
-            } else {
382
-                $payment_method_slug = 'paypal_standard';
383
-            }
384
-        }
385
-        return $payment_method_slug;
386
-    }
387
-
388
-
389
-    /**
390
-     *    payment_method_settings_meta_box
391
-     *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
392
-     *    capabilities to access it
393
-     *
394
-     * @param EE_Payment_Method $payment_method
395
-     * @return boolean
396
-     * @throws EE_Error
397
-     */
398
-    protected function _verify_payment_method($payment_method)
399
-    {
400
-        if (
401
-            $payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base
402
-            && EE_Registry::instance()->CAP->current_user_can(
403
-                $payment_method->type_obj()->cap_name(),
404
-                'specific_payment_method_type_access'
405
-            )
406
-        ) {
407
-            return true;
408
-        }
409
-        return false;
410
-    }
411
-
412
-
413
-    /**
414
-     *    payment_method_settings_meta_box
415
-     *
416
-     * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
417
-     * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
418
-     *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
419
-     * @return void
420
-     * @throws EE_Error
421
-     * @throws ReflectionException
422
-     */
423
-    public function payment_method_settings_meta_box($post_obj_which_is_null, $metabox)
424
-    {
425
-        $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
426
-            ? $metabox['args']['payment_method'] : null;
427
-        if (! $payment_method instanceof EE_Payment_Method) {
428
-            throw new EE_Error(
429
-                esc_html__(
430
-                    'Payment method metabox setup incorrectly. No Payment method object was supplied',
431
-                    'event_espresso'
432
-                )
433
-            );
434
-        }
435
-        $payment_method_scopes = $payment_method->active();
436
-        // if the payment method really exists show its form, otherwise the activation template
437
-        if ($payment_method->ID() && ! empty($payment_method_scopes)) {
438
-            $form = $this->_generate_payment_method_settings_form($payment_method);
439
-            if ($form->form_data_present_in($this->_req_data)) {
440
-                $form->receive_form_submission($this->_req_data);
441
-            }
442
-            echo wp_kses($form->form_open() . $form->get_html_and_js() . $form->form_close(), AllowedTags::getWithFormTags());
443
-        } else {
444
-            echo wp_kses($this->_activate_payment_method_button($payment_method)->get_html_and_js(), AllowedTags::getWithFormTags());
445
-        }
446
-    }
447
-
448
-
449
-    /**
450
-     * Gets the form for all the settings related to this payment method type
451
-     *
452
-     * @access protected
453
-     * @param EE_Payment_Method $payment_method
454
-     * @return EE_Form_Section_Proper
455
-     * @throws EE_Error
456
-     */
457
-    protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method = null)
458
-    {
459
-        if (! $payment_method instanceof EE_Payment_Method) {
460
-            return new EE_Form_Section_Proper();
461
-        }
462
-        return new EE_Form_Section_Proper(
463
-            array(
464
-                'name'            => $payment_method->slug() . '_settings_form',
465
-                'html_id'         => $payment_method->slug() . '_settings_form',
466
-                'action'          => EE_Admin_Page::add_query_args_and_nonce(
467
-                    array(
468
-                        'action'         => 'update_payment_method',
469
-                        'payment_method' => $payment_method->slug(),
470
-                    ),
471
-                    EE_PAYMENTS_ADMIN_URL
472
-                ),
473
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
474
-                'subsections'     => apply_filters(
475
-                    'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
476
-                    array(
477
-                        'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
478
-                        'currency_support'        => $this->_currency_support($payment_method),
479
-                        'payment_method_settings' => $this->_payment_method_settings($payment_method),
480
-                        'update'                  => $this->_update_payment_method_button($payment_method),
481
-                        'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
482
-                        'fine_print'              => $this->_fine_print(),
483
-                    ),
484
-                    $payment_method
485
-                ),
486
-            )
487
-        );
488
-    }
489
-
490
-
491
-    /**
492
-     * _pci_dss_compliance
493
-     *
494
-     * @access protected
495
-     * @param EE_Payment_Method $payment_method
496
-     * @return EE_Form_Section_HTML
497
-     * @throws EE_Error
498
-     */
499
-    protected function _pci_dss_compliance(EE_Payment_Method $payment_method)
500
-    {
501
-        if ($payment_method->type_obj()->requires_https()) {
502
-            return new EE_Form_Section_HTML(
503
-                EEH_HTML::table(
504
-                    EEH_HTML::tr(
505
-                        EEH_HTML::th(
506
-                            EEH_HTML::label(
507
-                                EEH_HTML::strong(
508
-                                    esc_html__('IMPORTANT', 'event_espresso'),
509
-                                    '',
510
-                                    'important-notice'
511
-                                )
512
-                            )
513
-                        ) .
514
-                        EEH_HTML::td(
515
-                            EEH_HTML::strong(
516
-                                esc_html__(
517
-                                    'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
518
-                                    'event_espresso'
519
-                                )
520
-                            )
521
-                            .
522
-                            EEH_HTML::br()
523
-                            .
524
-                            esc_html__('Learn more about ', 'event_espresso')
525
-                            . EEH_HTML::link(
526
-                                'https://www.pcisecuritystandards.org/merchants/index.php',
527
-                                esc_html__('PCI DSS compliance', 'event_espresso')
528
-                            )
529
-                        )
530
-                    )
531
-                )
532
-            );
533
-        }
534
-        return new EE_Form_Section_HTML('');
535
-    }
536
-
537
-
538
-    /**
539
-     * _currency_support
540
-     *
541
-     * @access protected
542
-     * @param EE_Payment_Method $payment_method
543
-     * @return EE_Form_Section_HTML
544
-     * @throws EE_Error
545
-     */
546
-    protected function _currency_support(EE_Payment_Method $payment_method)
547
-    {
548
-        if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
549
-            return new EE_Form_Section_HTML(
550
-                EEH_HTML::table(
551
-                    EEH_HTML::tr(
552
-                        EEH_HTML::th(
553
-                            EEH_HTML::label(
554
-                                EEH_HTML::strong(
555
-                                    esc_html__('IMPORTANT', 'event_espresso'),
556
-                                    '',
557
-                                    'important-notice'
558
-                                )
559
-                            )
560
-                        ) .
561
-                        EEH_HTML::td(
562
-                            EEH_HTML::strong(
563
-                                sprintf(
564
-                                    esc_html__(
565
-                                        'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
566
-                                        'event_espresso'
567
-                                    ),
568
-                                    EE_Config::instance()->currency->code
569
-                                )
570
-                            )
571
-                        )
572
-                    )
573
-                )
574
-            );
575
-        }
576
-        return new EE_Form_Section_HTML('');
577
-    }
578
-
579
-
580
-    /**
581
-     * _update_payment_method_button
582
-     *
583
-     * @access protected
584
-     * @param EE_Payment_Method $payment_method
585
-     * @return EE_Payment_Method_Form
586
-     * @throws EE_Error
587
-     */
588
-    protected function _payment_method_settings(EE_Payment_Method $payment_method)
589
-    {
590
-        // modify the form, so we only have/show fields that will be implemented for this version
591
-        return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
592
-    }
593
-
594
-
595
-    /**
596
-     * Simplifies the form to merely reproduce 4.1's gateway settings functionality
597
-     *
598
-     * @param EE_Form_Section_Proper $form_section
599
-     * @param string                 $payment_method_name
600
-     * @return EE_Payment_Method_Form
601
-     * @throws EE_Error
602
-     */
603
-    protected function _simplify_form($form_section, $payment_method_name = '')
604
-    {
605
-        if ($form_section instanceof EE_Payment_Method_Form) {
606
-            $form_section->exclude(
607
-                array(
608
-                    'PMD_type', // don't want them changing the type
609
-                    'PMD_slug', // or the slug (probably never)
610
-                    'PMD_wp_user', // or the user's ID
611
-                    'Currency' // or the currency, until the rest of EE supports simultaneous currencies
612
-                )
613
-            );
614
-            return $form_section;
615
-        } else {
616
-            throw new EE_Error(
617
-                sprintf(
618
-                    esc_html__(
619
-                        'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
620
-                        'event_espresso'
621
-                    ),
622
-                    $payment_method_name
623
-                )
624
-            );
625
-        }
626
-    }
627
-
628
-
629
-    /**
630
-     * _update_payment_method_button
631
-     *
632
-     * @access protected
633
-     * @param EE_Payment_Method $payment_method
634
-     * @return EE_Form_Section_HTML
635
-     * @throws EE_Error
636
-     */
637
-    protected function _update_payment_method_button(EE_Payment_Method $payment_method)
638
-    {
639
-        $update_button = new EE_Submit_Input(
640
-            array(
641
-                'name'       => 'submit',
642
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
643
-                'default'    => sprintf(
644
-                    esc_html__('Update %s Payment Settings', 'event_espresso'),
645
-                    $payment_method->admin_name()
646
-                ),
647
-                'html_label' => EEH_HTML::nbsp(),
648
-            )
649
-        );
650
-        return new EE_Form_Section_HTML(
651
-            EEH_HTML::table(
652
-                EEH_HTML::no_row(EEH_HTML::br(2)) .
653
-                EEH_HTML::tr(
654
-                    EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')) .
655
-                    EEH_HTML::td(
656
-                        $update_button->get_html_for_input()
657
-                    )
658
-                )
659
-            )
660
-        );
661
-    }
662
-
663
-
664
-    /**
665
-     * _deactivate_payment_method_button
666
-     *
667
-     * @access protected
668
-     * @param EE_Payment_Method $payment_method
669
-     * @return EE_Form_Section_HTML
670
-     */
671
-    protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method)
672
-    {
673
-        $link_text_and_title = sprintf(
674
-            esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
675
-            $payment_method->admin_name()
676
-        );
677
-        return new EE_Form_Section_HTML(
678
-            EEH_HTML::table(
679
-                EEH_HTML::tr(
680
-                    EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')) .
681
-                    EEH_HTML::td(
682
-                        EEH_HTML::link(
683
-                            EE_Admin_Page::add_query_args_and_nonce(
684
-                                array(
685
-                                    'action'         => 'deactivate_payment_method',
686
-                                    'payment_method' => $payment_method->slug(),
687
-                                ),
688
-                                EE_PAYMENTS_ADMIN_URL
689
-                            ),
690
-                            $link_text_and_title,
691
-                            $link_text_and_title,
692
-                            'deactivate_' . $payment_method->slug(),
693
-                            'espresso-button button-secondary'
694
-                        )
695
-                    )
696
-                )
697
-            )
698
-        );
699
-    }
700
-
701
-
702
-    /**
703
-     * _activate_payment_method_button
704
-     *
705
-     * @access protected
706
-     * @param EE_Payment_Method $payment_method
707
-     * @return EE_Form_Section_Proper
708
-     * @throws EE_Error
709
-     */
710
-    protected function _activate_payment_method_button(EE_Payment_Method $payment_method)
711
-    {
712
-        $link_text_and_title = sprintf(
713
-            esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
714
-            $payment_method->admin_name()
715
-        );
716
-        return new EE_Form_Section_Proper(
717
-            array(
718
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
719
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
720
-                'action'          => '#',
721
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
722
-                'subsections'     => apply_filters(
723
-                    'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
724
-                    array(
725
-                        new EE_Form_Section_HTML(
726
-                            EEH_HTML::table(
727
-                                EEH_HTML::tr(
728
-                                    EEH_HTML::td(
729
-                                        $payment_method->type_obj()->introductory_html(),
730
-                                        '',
731
-                                        '',
732
-                                        '',
733
-                                        'colspan="2"'
734
-                                    )
735
-                                ) .
736
-                                EEH_HTML::tr(
737
-                                    EEH_HTML::th(
738
-                                        EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
739
-                                    ) .
740
-                                    EEH_HTML::td(
741
-                                        EEH_HTML::link(
742
-                                            EE_Admin_Page::add_query_args_and_nonce(
743
-                                                array(
744
-                                                    'action'              => 'activate_payment_method',
745
-                                                    'payment_method_type' => $payment_method->type(),
746
-                                                ),
747
-                                                EE_PAYMENTS_ADMIN_URL
748
-                                            ),
749
-                                            $link_text_and_title,
750
-                                            $link_text_and_title,
751
-                                            'activate_' . $payment_method->slug(),
752
-                                            'espresso-button-green button-primary'
753
-                                        )
754
-                                    )
755
-                                )
756
-                            )
757
-                        ),
758
-                    ),
759
-                    $payment_method
760
-                ),
761
-            )
762
-        );
763
-    }
764
-
765
-
766
-    /**
767
-     * _fine_print
768
-     *
769
-     * @access protected
770
-     * @return EE_Form_Section_HTML
771
-     */
772
-    protected function _fine_print()
773
-    {
774
-        return new EE_Form_Section_HTML(
775
-            EEH_HTML::table(
776
-                EEH_HTML::tr(
777
-                    EEH_HTML::th() .
778
-                    EEH_HTML::td(
779
-                        EEH_HTML::p(esc_html__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text')
780
-                    )
781
-                )
782
-            )
783
-        );
784
-    }
785
-
786
-
787
-    /**
788
-     * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
789
-     *
790
-     * @throws EE_Error
791
-     * @throws ReflectionException
792
-     * @global WP_User $current_user
793
-     */
794
-    protected function _activate_payment_method()
795
-    {
796
-        if (isset($this->_req_data['payment_method_type'])) {
797
-            $payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
798
-            // see if one exists
799
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
800
-            $payment_method = EE_Payment_Method_Manager::instance()
801
-                                                       ->activate_a_payment_method_of_type($payment_method_type);
802
-            $this->_redirect_after_action(
803
-                1,
804
-                'Payment Method',
805
-                'activated',
806
-                array('action' => 'default', 'payment_method' => $payment_method->slug())
807
-            );
808
-        } else {
809
-            $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
810
-        }
811
-    }
812
-
813
-
814
-    /**
815
-     * @throws EE_Error
816
-     * @throws ReflectionException
817
-     */
818
-    protected function _deactivate_payment_method()
819
-    {
820
-        if (isset($this->_req_data['payment_method'])) {
821
-            $payment_method_slug = sanitize_key($this->_req_data['payment_method']);
822
-            // deactivate it
823
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
824
-            $count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
825
-            $this->_redirect_after_action(
826
-                $count_updated,
827
-                'Payment Method',
828
-                'deactivated',
829
-                array('action' => 'default', 'payment_method' => $payment_method_slug)
830
-            );
831
-        } else {
832
-            $this->_redirect_after_action(false, 'Payment Method', 'deactivated', array('action' => 'default'));
833
-        }
834
-    }
835
-
836
-
837
-    /**
838
-     * Processes the payment method form that was submitted. This is slightly trickier than usual form
839
-     * processing because we first need to identify WHICH form was processed and which payment method
840
-     * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
841
-     * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
842
-     * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
843
-     * subsequently called 'headers_sent_func' which is _payment_methods_list)
844
-     *
845
-     * @return void
846
-     * @throws EE_Error
847
-     * @throws ReflectionException
848
-     */
849
-    protected function _update_payment_method()
850
-    {
851
-        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
852
-            // ok let's find which gateway form to use based on the form input
853
-            EE_Registry::instance()->load_lib('Payment_Method_Manager');
854
-            /** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
855
-            $correct_pmt_form_to_use = null;
856
-            $payment_method = null;
857
-            foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
858
-                if ($payment_method instanceof EE_Payment_Method) {
859
-                    // get the form and simplify it, like what we do when we display it
860
-                    $pmt_form = $this->_generate_payment_method_settings_form($payment_method);
861
-                    if ($pmt_form->form_data_present_in($this->_req_data)) {
862
-                        $correct_pmt_form_to_use = $pmt_form;
863
-                        break;
864
-                    }
865
-                }
866
-            }
867
-            // if we couldn't find the correct payment method type...
868
-            if (! $correct_pmt_form_to_use) {
869
-                EE_Error::add_error(
870
-                    esc_html__(
871
-                        "We could not find which payment method type your form submission related to. Please contact support",
872
-                        'event_espresso'
873
-                    ),
874
-                    __FILE__,
875
-                    __FUNCTION__,
876
-                    __LINE__
877
-                );
878
-                $this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
879
-            }
880
-            $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
881
-            if ($correct_pmt_form_to_use->is_valid()) {
882
-                $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
883
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
884
-                    throw new EE_Error(
885
-                        sprintf(
886
-                            esc_html__(
887
-                                'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
888
-                                'event_espresso'
889
-                            ),
890
-                            'payment_method_settings'
891
-                        )
892
-                    );
893
-                }
894
-                $payment_settings_subform->save();
895
-                /** @var $pm EE_Payment_Method */
896
-                $this->_redirect_after_action(
897
-                    true,
898
-                    'Payment Method',
899
-                    'updated',
900
-                    array('action' => 'default', 'payment_method' => $payment_method->slug())
901
-                );
902
-            } else {
903
-                EE_Error::add_error(
904
-                    sprintf(
905
-                        esc_html__(
906
-                            'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
907
-                            'event_espresso'
908
-                        ),
909
-                        $payment_method instanceof EE_Payment_Method ? $payment_method->type_obj()->pretty_name()
910
-                            : esc_html__('"(unknown)"', 'event_espresso')
911
-                    ),
912
-                    __FILE__,
913
-                    __FUNCTION__,
914
-                    __LINE__
915
-                );
916
-            }
917
-        }
918
-    }
919
-
920
-
921
-    /**
922
-     * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
923
-     * @throws DomainException
924
-     * @throws EE_Error
925
-     * @throws InvalidArgumentException
926
-     * @throws InvalidDataTypeException
927
-     * @throws InvalidInterfaceException
928
-     */
929
-    protected function _payment_settings()
930
-    {
931
-        $form = $this->getPaymentSettingsForm();
932
-        $this->_set_add_edit_form_tags('update_payment_settings');
933
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
934
-        $this->_template_args['admin_page_content'] =  $form->get_html_and_js();
935
-        $this->display_admin_page_with_sidebar();
936
-    }
937
-
938
-
939
-    /**
940
-     *        _update_payment_settings
941
-     *
942
-     * @access protected
943
-     * @return void
944
-     * @throws EE_Error
945
-     * @throws InvalidArgumentException
946
-     * @throws InvalidDataTypeException
947
-     * @throws InvalidInterfaceException
948
-     */
949
-    protected function _update_payment_settings()
950
-    {
951
-        $form = $this->getPaymentSettingsForm();
952
-        if ($form->was_submitted($this->_req_data)) {
953
-            $form->receive_form_submission($this->_req_data);
954
-            if ($form->is_valid()) {
955
-                /**
956
-                 * @var $reg_config EE_Registration_Config
957
-                 */
958
-                $loader = LoaderFactory::getLoader();
959
-                $reg_config = $loader->getShared('EE_Registration_Config');
960
-                $valid_data = $form->valid_data();
961
-                $reg_config->show_pending_payment_options = $valid_data['show_pending_payment_options'];
962
-                $reg_config->gateway_log_lifespan = $valid_data['gateway_log_lifespan'];
963
-            }
964
-        }
965
-        EE_Registry::instance()->CFG = apply_filters(
966
-            'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
967
-            EE_Registry::instance()->CFG
968
-        );
969
-
970
-        $what = esc_html__('Payment Settings', 'event_espresso');
971
-        $success = $this->_update_espresso_configuration(
972
-            $what,
973
-            EE_Registry::instance()->CFG,
974
-            __FILE__,
975
-            __FUNCTION__,
976
-            __LINE__
977
-        );
978
-        $this->_redirect_after_action(
979
-            $success,
980
-            $what,
981
-            esc_html__('updated', 'event_espresso'),
982
-            array('action' => 'payment_settings')
983
-        );
984
-    }
985
-
986
-
987
-    /**
988
-     * Gets the form used for updating payment settings
989
-     *
990
-     * @return EE_Form_Section_Proper
991
-     * @throws EE_Error
992
-     * @throws InvalidArgumentException
993
-     * @throws InvalidDataTypeException
994
-     * @throws InvalidInterfaceException
995
-     */
996
-    protected function getPaymentSettingsForm()
997
-    {
998
-        /**
999
-         * @var $reg_config EE_Registration_Config
1000
-         */
1001
-        $reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1002
-        return new EE_Form_Section_Proper(
1003
-            array(
1004
-                'name' => 'payment-settings',
1005
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1006
-                'subsections' => array(
1007
-                    'show_pending_payment_options' => new EE_Yes_No_Input(
1008
-                        array(
1009
-                            'html_name' => 'show_pending_payment_options',
1010
-                            'default' => $reg_config->show_pending_payment_options,
1011
-                            'html_help_text' => esc_html__(
1012
-                                "If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1013
-                                'event_espresso'
1014
-                            )
1015
-                        )
1016
-                    ),
1017
-                    'gateway_log_lifespan' => new EE_Select_Input(
1018
-                        $reg_config->gatewayLogLifespanOptions(),
1019
-                        array(
1020
-                            'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1021
-                            'html_help_text' => esc_html__('If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.', 'event_espresso'),
1022
-                            'default' => $reg_config->gateway_log_lifespan,
1023
-                        )
1024
-                    )
1025
-                )
1026
-            )
1027
-        );
1028
-    }
1029
-
1030
-
1031
-    /**
1032
-     * @throws EE_Error
1033
-     */
1034
-    protected function _payment_log_overview_list_table()
1035
-    {
1036
-        $this->display_admin_list_table_page_with_sidebar();
1037
-    }
1038
-
1039
-
1040
-    protected function _set_list_table_views_payment_log()
1041
-    {
1042
-        $this->_views = array(
1043
-            'all' => array(
1044
-                'slug'  => 'all',
1045
-                'label' => esc_html__('View All Logs', 'event_espresso'),
1046
-                'count' => 0,
1047
-            ),
1048
-        );
1049
-    }
1050
-
1051
-
1052
-    /**
1053
-     * @param int  $per_page
1054
-     * @param int  $current_page
1055
-     * @param bool $count
1056
-     * @return array|int
1057
-     * @throws EE_Error
1058
-     * @throws ReflectionException
1059
-     */
1060
-    public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1061
-    {
1062
-        EE_Registry::instance()->load_model('Change_Log');
1063
-        // we may need to do multiple queries (joining differently), so we actually want an array of query params
1064
-        $query_params = array(array('LOG_type' => EEM_Change_Log::type_gateway));
1065
-        // check if they've selected a specific payment method
1066
-        if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1067
-            $query_params[0]['OR*pm_or_pay_pm'] = array(
1068
-                'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1069
-                'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1070
-            );
1071
-        }
1072
-        // take into account search
1073
-        if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1074
-            $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%');
1075
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1076
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1077
-            $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1078
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_name'] = $similarity_string;
1079
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name'] = $similarity_string;
1080
-            $query_params[0]['OR*s']['Payment.Payment_Method.PMD_type'] = $similarity_string;
1081
-            $query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1082
-            $query_params[0]['OR*s']['Payment_Method.PMD_name'] = $similarity_string;
1083
-            $query_params[0]['OR*s']['Payment_Method.PMD_admin_name'] = $similarity_string;
1084
-            $query_params[0]['OR*s']['Payment_Method.PMD_type'] = $similarity_string;
1085
-            $query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1086
-        }
1087
-        if (
1088
-            isset($this->_req_data['payment-filter-start-date'])
1089
-            && isset($this->_req_data['payment-filter-end-date'])
1090
-        ) {
1091
-            // add date
1092
-            $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1093
-            $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1094
-            // make sure our timestamps start and end right at the boundaries for each day
1095
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1096
-            $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1097
-            // convert to timestamps
1098
-            $start_date = strtotime($start_date);
1099
-            $end_date = strtotime($end_date);
1100
-            // makes sure start date is the lowest value and vice versa
1101
-            $start_date = min($start_date, $end_date);
1102
-            $end_date = max($start_date, $end_date);
1103
-            // convert for query
1104
-            $start_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1105
-                'LOG_time',
1106
-                date('Y-m-d H:i:s', $start_date),
1107
-                'Y-m-d H:i:s'
1108
-            );
1109
-            $end_date   = EEM_Change_Log::instance()->convert_datetime_for_query(
1110
-                'LOG_time',
1111
-                date('Y-m-d H:i:s', $end_date),
1112
-                'Y-m-d H:i:s'
1113
-            );
1114
-            $query_params[0]['LOG_time'] = array('BETWEEN', array($start_date, $end_date));
1115
-        }
1116
-        if ($count) {
1117
-            return EEM_Change_Log::instance()->count($query_params);
1118
-        }
1119
-        if (isset($this->_req_data['order'])) {
1120
-            $sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1121
-                ? $this->_req_data['order']
1122
-                : 'DESC';
1123
-            $query_params['order_by'] = array('LOG_time' => $sort);
1124
-        } else {
1125
-            $query_params['order_by'] = array('LOG_time' => 'DESC');
1126
-        }
1127
-        $offset = ($current_page - 1) * $per_page;
1128
-        if (! isset($this->_req_data['download_results'])) {
1129
-            $query_params['limit'] = array($offset, $per_page);
1130
-        }
1131
-        // now they've requested to instead just download the file instead of viewing it.
1132
-        if (isset($this->_req_data['download_results'])) {
1133
-            $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1134
-            header('Content-Disposition: attachment');
1135
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1136
-            echo '<h1> '
1137
-                . sprintf(
1138
-                    esc_html__('Payment Logs for %1$s', 'event_espresso'),
1139
-                    esc_url_raw(site_url())
1140
-                )
1141
-                . '</h1 >';
1142
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1143
-            echo esc_html(var_export($query_params, true));
1144
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1145
-            echo esc_html(var_export($wpdb_results, true));
1146
-            die;
1147
-        }
1148
-        return EEM_Change_Log::instance()->get_all($query_params);
1149
-    }
1150
-
1151
-
1152
-    /**
1153
-     * Used by usort to RE-sort log query results, because we lose the ordering
1154
-     * because we're possibly combining the results from two queries
1155
-     *
1156
-     * @param EE_Change_Log $logA
1157
-     * @param EE_Change_Log $logB
1158
-     * @return int
1159
-     * @throws EE_Error
1160
-     * @throws ReflectionException
1161
-     */
1162
-    protected function _sort_logs_again($logA, $logB)
1163
-    {
1164
-        $timeA = $logA->get_raw('LOG_time');
1165
-        $timeB = $logB->get_raw('LOG_time');
1166
-        if ($timeA == $timeB) {
1167
-            return 0;
1168
-        }
1169
-        $comparison = $timeA < $timeB ? -1 : 1;
1170
-        if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1171
-            return $comparison * -1;
1172
-        }
1173
-        return $comparison;
1174
-    }
1175
-
1176
-
1177
-    /**
1178
-     * @throws EE_Error
1179
-     * @throws ReflectionException
1180
-     */
1181
-    protected function _payment_log_details()
1182
-    {
1183
-        EE_Registry::instance()->load_model('Change_Log');
1184
-        /** @var $payment_log EE_Change_Log */
1185
-        $payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1186
-        $payment_method = null;
1187
-        $transaction = null;
1188
-        if ($payment_log instanceof EE_Change_Log) {
1189
-            if ($payment_log->object() instanceof EE_Payment) {
1190
-                $payment_method = $payment_log->object()->payment_method();
1191
-                $transaction = $payment_log->object()->transaction();
1192
-            } elseif ($payment_log->object() instanceof EE_Payment_Method) {
1193
-                $payment_method = $payment_log->object();
1194
-            } elseif ($payment_log->object() instanceof EE_Transaction) {
1195
-                $transaction = $payment_log->object();
1196
-                $payment_method = $transaction->payment_method();
1197
-            }
1198
-        }
1199
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1200
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1201
-            array(
1202
-                'payment_log'    => $payment_log,
1203
-                'payment_method' => $payment_method,
1204
-                'transaction'    => $transaction,
1205
-            ),
1206
-            true
1207
-        );
1208
-        $this->display_admin_page_with_sidebar();
1209
-    }
19
+	/**
20
+	 * Variables used for when we're re-sorting the logs results,
21
+	 * in case we needed to do two queries, and we need to resort
22
+	 *
23
+	 * @var string
24
+	 */
25
+	private $_sort_logs_again_direction;
26
+
27
+
28
+	/**
29
+	 * @Constructor
30
+	 * @access public
31
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
32
+	 * @throws EE_Error
33
+	 * @throws InvalidArgumentException
34
+	 * @throws InvalidDataTypeException
35
+	 * @throws InvalidInterfaceException
36
+	 * @throws ReflectionException
37
+	 */
38
+	public function __construct($routing = true)
39
+	{
40
+		parent::__construct($routing);
41
+	}
42
+
43
+
44
+	protected function _init_page_props()
45
+	{
46
+		$this->page_slug = EE_PAYMENTS_PG_SLUG;
47
+		$this->page_label = esc_html__('Payment Methods', 'event_espresso');
48
+		$this->_admin_base_url = EE_PAYMENTS_ADMIN_URL;
49
+		$this->_admin_base_path = EE_PAYMENTS_ADMIN;
50
+	}
51
+
52
+
53
+	protected function _ajax_hooks()
54
+	{
55
+		// todo: all hooks for ajax goes here.
56
+	}
57
+
58
+
59
+	protected function _define_page_props()
60
+	{
61
+		$this->_admin_page_title = $this->page_label;
62
+		$this->_labels = array(
63
+			'publishbox' => esc_html__('Update Settings', 'event_espresso'),
64
+		);
65
+	}
66
+
67
+
68
+	protected function _set_page_routes()
69
+	{
70
+		/**
71
+		 * note that with payment method capabilities, although we've implemented
72
+		 * capability mapping which will be used for accessing payment methods owned by
73
+		 * other users.  This is not fully implemented yet in the payment method ui.
74
+		 * Currently, only the "plural" caps are in active use.
75
+		 * When cap mapping is implemented, some routes will need to use the singular form of
76
+		 * capability method and also include the $id of the payment method for the route.
77
+		 **/
78
+		$this->_page_routes = array(
79
+			'default'                   => array(
80
+				'func'       => '_payment_methods_list',
81
+				'capability' => 'ee_edit_payment_methods',
82
+			),
83
+			'payment_settings'          => array(
84
+				'func'       => '_payment_settings',
85
+				'capability' => 'ee_manage_gateways',
86
+			),
87
+			'activate_payment_method'   => array(
88
+				'func'       => '_activate_payment_method',
89
+				'noheader'   => true,
90
+				'capability' => 'ee_edit_payment_methods',
91
+			),
92
+			'deactivate_payment_method' => array(
93
+				'func'       => '_deactivate_payment_method',
94
+				'noheader'   => true,
95
+				'capability' => 'ee_delete_payment_methods',
96
+			),
97
+			'update_payment_method'     => array(
98
+				'func'               => '_update_payment_method',
99
+				'noheader'           => true,
100
+				'headers_sent_route' => 'default',
101
+				'capability'         => 'ee_edit_payment_methods',
102
+			),
103
+			'update_payment_settings'   => array(
104
+				'func'       => '_update_payment_settings',
105
+				'noheader'   => true,
106
+				'capability' => 'ee_manage_gateways',
107
+			),
108
+			'payment_log'               => array(
109
+				'func'       => '_payment_log_overview_list_table',
110
+				'capability' => 'ee_read_payment_methods',
111
+			),
112
+			'payment_log_details'       => array(
113
+				'func'       => '_payment_log_details',
114
+				'capability' => 'ee_read_payment_methods',
115
+			),
116
+		);
117
+	}
118
+
119
+
120
+	/**
121
+	 * @throws EE_Error
122
+	 * @throws ReflectionException
123
+	 */
124
+	protected function _set_page_config()
125
+	{
126
+		$payment_method_list_config = array(
127
+			'nav'           => array(
128
+				'label' => esc_html__('Payment Methods', 'event_espresso'),
129
+				'order' => 10,
130
+			),
131
+			'metaboxes'     => $this->_default_espresso_metaboxes,
132
+			'help_tabs'     => array_merge(
133
+				array(
134
+					'payment_methods_overview_help_tab' => array(
135
+						'title'    => esc_html__('Payment Methods Overview', 'event_espresso'),
136
+						'filename' => 'payment_methods_overview',
137
+					),
138
+				),
139
+				$this->_add_payment_method_help_tabs()
140
+			),
141
+			'require_nonce' => false,
142
+		);
143
+		$this->_page_config = array(
144
+			'default'          => $payment_method_list_config,
145
+			'payment_settings' => array(
146
+				'nav'           => array(
147
+					'label' => esc_html__('Settings', 'event_espresso'),
148
+					'order' => 20,
149
+				),
150
+				'help_tabs'     => array(
151
+					'payment_methods_settings_help_tab' => array(
152
+						'title'    => esc_html__('Payment Method Settings', 'event_espresso'),
153
+						'filename' => 'payment_methods_settings',
154
+					),
155
+				),
156
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
157
+				'require_nonce' => false,
158
+			),
159
+			'payment_log'      => array(
160
+				'nav'           => array(
161
+					'label' => esc_html__("Logs", 'event_espresso'),
162
+					'order' => 30,
163
+				),
164
+				'list_table'    => 'Payment_Log_Admin_List_Table',
165
+				'metaboxes'     => $this->_default_espresso_metaboxes,
166
+				'require_nonce' => false,
167
+			),
168
+		);
169
+	}
170
+
171
+
172
+	/**
173
+	 * @return array
174
+	 * @throws DomainException
175
+	 * @throws EE_Error
176
+	 * @throws InvalidArgumentException
177
+	 * @throws InvalidDataTypeException
178
+	 * @throws InvalidInterfaceException
179
+	 * @throws ReflectionException
180
+	 */
181
+	protected function _add_payment_method_help_tabs()
182
+	{
183
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
184
+		$payment_method_types = EE_Payment_Method_Manager::instance()->payment_method_types();
185
+		$all_pmt_help_tabs_config = array();
186
+		foreach ($payment_method_types as $payment_method_type) {
187
+			if (
188
+				! EE_Registry::instance()->CAP->current_user_can(
189
+					$payment_method_type->cap_name(),
190
+					'specific_payment_method_type_access'
191
+				)
192
+			) {
193
+				continue;
194
+			}
195
+			foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
196
+				$template_args = isset($config['template_args']) ? $config['template_args'] : array();
197
+				$template_args['admin_page_obj'] = $this;
198
+				$all_pmt_help_tabs_config[ $help_tab_name ] = array(
199
+					'title'   => $config['title'],
200
+					'content' => EEH_Template::display_template(
201
+						$payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
202
+						$template_args,
203
+						true
204
+					),
205
+				);
206
+			}
207
+		}
208
+		return $all_pmt_help_tabs_config;
209
+	}
210
+
211
+
212
+	// none of the below group are currently used for Gateway Settings
213
+	protected function _add_screen_options()
214
+	{
215
+	}
216
+
217
+
218
+	protected function _add_feature_pointers()
219
+	{
220
+	}
221
+
222
+
223
+	public function admin_init()
224
+	{
225
+	}
226
+
227
+
228
+	public function admin_notices()
229
+	{
230
+	}
231
+
232
+
233
+	public function admin_footer_scripts()
234
+	{
235
+	}
236
+
237
+
238
+	public function load_scripts_styles()
239
+	{
240
+		// styles
241
+		wp_enqueue_style('espresso-ui-theme');
242
+		// scripts
243
+		wp_enqueue_script('ee_admin_js');
244
+		wp_enqueue_script('ee-text-links');
245
+		wp_enqueue_script(
246
+			'espresso_payments',
247
+			EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
248
+			array('ee-datepicker'),
249
+			EVENT_ESPRESSO_VERSION,
250
+			true
251
+		);
252
+	}
253
+
254
+
255
+	public function load_scripts_styles_default()
256
+	{
257
+		// styles
258
+		wp_register_style(
259
+			'espresso_payments',
260
+			EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
261
+			array(),
262
+			EVENT_ESPRESSO_VERSION
263
+		);
264
+		wp_enqueue_style('espresso_payments');
265
+		wp_enqueue_style('ee-text-links');
266
+		// scripts
267
+	}
268
+
269
+
270
+	/**
271
+	 * @throws EE_Error
272
+	 * @throws ReflectionException
273
+	 */
274
+	protected function _payment_methods_list()
275
+	{
276
+		/**
277
+		 * first let's ensure payment methods have been set up.
278
+		 * We do this here because when people activate a payment method for the first time (as an addon),
279
+		 * it may not set up its capabilities or get registered correctly due to the loading process.
280
+		 * However, people MUST set up the details for the payment method,
281
+		 * so it's safe to do a recheck here.
282
+		 */
283
+		EE_Registry::instance()->load_lib('Payment_Method_Manager');
284
+		EEM_Payment_Method::instance()->verify_button_urls();
285
+		// set up tabs, one for each payment method type
286
+		$tabs = array();
287
+		$payment_methods = array();
288
+		foreach (EE_Payment_Method_Manager::instance()->payment_method_types() as $pmt_obj) {
289
+			// we don't want to show admin-only PMTs for now
290
+			if ($pmt_obj instanceof EE_PMT_Admin_Only) {
291
+				continue;
292
+			}
293
+			// check access
294
+			if (
295
+				! EE_Registry::instance()->CAP->current_user_can(
296
+					$pmt_obj->cap_name(),
297
+					'specific_payment_method_type_access'
298
+				)
299
+			) {
300
+				continue;
301
+			}
302
+			// check for any active pms of that type
303
+			$payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
304
+			if (! $payment_method instanceof EE_Payment_Method) {
305
+				$payment_method = EE_Payment_Method::new_instance(
306
+					array(
307
+						'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
308
+						'PMD_type'       => $pmt_obj->system_name(),
309
+						'PMD_name'       => $pmt_obj->pretty_name(),
310
+						'PMD_admin_name' => $pmt_obj->pretty_name(),
311
+					)
312
+				);
313
+			}
314
+			$payment_methods[ $payment_method->slug() ] = $payment_method;
315
+		}
316
+		$payment_methods = apply_filters(
317
+			'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
318
+			$payment_methods
319
+		);
320
+		foreach ($payment_methods as $payment_method) {
321
+			if ($payment_method instanceof EE_Payment_Method) {
322
+				add_meta_box(
323
+					// html id
324
+					'espresso_' . $payment_method->slug() . '_payment_settings',
325
+					// title
326
+					sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
327
+					// callback
328
+					array($this, 'payment_method_settings_meta_box'),
329
+					// post type
330
+					null,
331
+					// context
332
+					'normal',
333
+					// priority
334
+					'default',
335
+					// callback args
336
+					array('payment_method' => $payment_method)
337
+				);
338
+				// setup for tabbed content
339
+				$tabs[ $payment_method->slug() ] = array(
340
+					'label' => $payment_method->admin_name(),
341
+					'class' => $payment_method->active() ? 'gateway-active' : '',
342
+					'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
343
+					'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
344
+					'slug'  => $payment_method->slug(),
345
+				);
346
+			}
347
+		}
348
+		$this->_template_args['admin_page_header'] = EEH_Tabbed_Content::tab_text_links(
349
+			$tabs,
350
+			'payment_method_links',
351
+			'|',
352
+			$this->_get_active_payment_method_slug()
353
+		);
354
+		$this->display_admin_page_with_sidebar();
355
+	}
356
+
357
+
358
+	/**
359
+	 *   _get_active_payment_method_slug
360
+	 *
361
+	 * @return string
362
+	 * @throws EE_Error
363
+	 */
364
+	protected function _get_active_payment_method_slug()
365
+	{
366
+		$payment_method_slug = false;
367
+		// decide which payment method tab to open first, as dictated by the request's 'payment_method'
368
+		if (isset($this->_req_data['payment_method'])) {
369
+			// if they provided the current payment method, use it
370
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
371
+		}
372
+		/** @var EE_Payment_Method $payment_method */
373
+		$payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug)));
374
+		// if that didn't work or wasn't provided, find another way to select the current pm
375
+		if (! $this->_verify_payment_method($payment_method)) {
376
+			// like, looking for an active one
377
+			$payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
378
+			// test that one as well
379
+			if ($this->_verify_payment_method($payment_method)) {
380
+				$payment_method_slug = $payment_method->slug();
381
+			} else {
382
+				$payment_method_slug = 'paypal_standard';
383
+			}
384
+		}
385
+		return $payment_method_slug;
386
+	}
387
+
388
+
389
+	/**
390
+	 *    payment_method_settings_meta_box
391
+	 *    returns TRUE if the passed payment method is properly constructed and the logged-in user has the correct
392
+	 *    capabilities to access it
393
+	 *
394
+	 * @param EE_Payment_Method $payment_method
395
+	 * @return boolean
396
+	 * @throws EE_Error
397
+	 */
398
+	protected function _verify_payment_method($payment_method)
399
+	{
400
+		if (
401
+			$payment_method instanceof EE_Payment_Method && $payment_method->type_obj() instanceof EE_PMT_Base
402
+			&& EE_Registry::instance()->CAP->current_user_can(
403
+				$payment_method->type_obj()->cap_name(),
404
+				'specific_payment_method_type_access'
405
+			)
406
+		) {
407
+			return true;
408
+		}
409
+		return false;
410
+	}
411
+
412
+
413
+	/**
414
+	 *    payment_method_settings_meta_box
415
+	 *
416
+	 * @param NULL  $post_obj_which_is_null is an object containing the current post (as a $post object)
417
+	 * @param array $metabox                is an array with metabox id, title, callback, and args elements. the value
418
+	 *                                      at 'args' has key 'payment_method', as set within _payment_methods_list
419
+	 * @return void
420
+	 * @throws EE_Error
421
+	 * @throws ReflectionException
422
+	 */
423
+	public function payment_method_settings_meta_box($post_obj_which_is_null, $metabox)
424
+	{
425
+		$payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
426
+			? $metabox['args']['payment_method'] : null;
427
+		if (! $payment_method instanceof EE_Payment_Method) {
428
+			throw new EE_Error(
429
+				esc_html__(
430
+					'Payment method metabox setup incorrectly. No Payment method object was supplied',
431
+					'event_espresso'
432
+				)
433
+			);
434
+		}
435
+		$payment_method_scopes = $payment_method->active();
436
+		// if the payment method really exists show its form, otherwise the activation template
437
+		if ($payment_method->ID() && ! empty($payment_method_scopes)) {
438
+			$form = $this->_generate_payment_method_settings_form($payment_method);
439
+			if ($form->form_data_present_in($this->_req_data)) {
440
+				$form->receive_form_submission($this->_req_data);
441
+			}
442
+			echo wp_kses($form->form_open() . $form->get_html_and_js() . $form->form_close(), AllowedTags::getWithFormTags());
443
+		} else {
444
+			echo wp_kses($this->_activate_payment_method_button($payment_method)->get_html_and_js(), AllowedTags::getWithFormTags());
445
+		}
446
+	}
447
+
448
+
449
+	/**
450
+	 * Gets the form for all the settings related to this payment method type
451
+	 *
452
+	 * @access protected
453
+	 * @param EE_Payment_Method $payment_method
454
+	 * @return EE_Form_Section_Proper
455
+	 * @throws EE_Error
456
+	 */
457
+	protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method = null)
458
+	{
459
+		if (! $payment_method instanceof EE_Payment_Method) {
460
+			return new EE_Form_Section_Proper();
461
+		}
462
+		return new EE_Form_Section_Proper(
463
+			array(
464
+				'name'            => $payment_method->slug() . '_settings_form',
465
+				'html_id'         => $payment_method->slug() . '_settings_form',
466
+				'action'          => EE_Admin_Page::add_query_args_and_nonce(
467
+					array(
468
+						'action'         => 'update_payment_method',
469
+						'payment_method' => $payment_method->slug(),
470
+					),
471
+					EE_PAYMENTS_ADMIN_URL
472
+				),
473
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
474
+				'subsections'     => apply_filters(
475
+					'FHEE__Payments_Admin_Page___generate_payment_method_settings_form__form_subsections',
476
+					array(
477
+						'pci_dss_compliance'      => $this->_pci_dss_compliance($payment_method),
478
+						'currency_support'        => $this->_currency_support($payment_method),
479
+						'payment_method_settings' => $this->_payment_method_settings($payment_method),
480
+						'update'                  => $this->_update_payment_method_button($payment_method),
481
+						'deactivate'              => $this->_deactivate_payment_method_button($payment_method),
482
+						'fine_print'              => $this->_fine_print(),
483
+					),
484
+					$payment_method
485
+				),
486
+			)
487
+		);
488
+	}
489
+
490
+
491
+	/**
492
+	 * _pci_dss_compliance
493
+	 *
494
+	 * @access protected
495
+	 * @param EE_Payment_Method $payment_method
496
+	 * @return EE_Form_Section_HTML
497
+	 * @throws EE_Error
498
+	 */
499
+	protected function _pci_dss_compliance(EE_Payment_Method $payment_method)
500
+	{
501
+		if ($payment_method->type_obj()->requires_https()) {
502
+			return new EE_Form_Section_HTML(
503
+				EEH_HTML::table(
504
+					EEH_HTML::tr(
505
+						EEH_HTML::th(
506
+							EEH_HTML::label(
507
+								EEH_HTML::strong(
508
+									esc_html__('IMPORTANT', 'event_espresso'),
509
+									'',
510
+									'important-notice'
511
+								)
512
+							)
513
+						) .
514
+						EEH_HTML::td(
515
+							EEH_HTML::strong(
516
+								esc_html__(
517
+									'You are responsible for your own website security and Payment Card Industry Data Security Standards (PCI DSS) compliance.',
518
+									'event_espresso'
519
+								)
520
+							)
521
+							.
522
+							EEH_HTML::br()
523
+							.
524
+							esc_html__('Learn more about ', 'event_espresso')
525
+							. EEH_HTML::link(
526
+								'https://www.pcisecuritystandards.org/merchants/index.php',
527
+								esc_html__('PCI DSS compliance', 'event_espresso')
528
+							)
529
+						)
530
+					)
531
+				)
532
+			);
533
+		}
534
+		return new EE_Form_Section_HTML('');
535
+	}
536
+
537
+
538
+	/**
539
+	 * _currency_support
540
+	 *
541
+	 * @access protected
542
+	 * @param EE_Payment_Method $payment_method
543
+	 * @return EE_Form_Section_HTML
544
+	 * @throws EE_Error
545
+	 */
546
+	protected function _currency_support(EE_Payment_Method $payment_method)
547
+	{
548
+		if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
549
+			return new EE_Form_Section_HTML(
550
+				EEH_HTML::table(
551
+					EEH_HTML::tr(
552
+						EEH_HTML::th(
553
+							EEH_HTML::label(
554
+								EEH_HTML::strong(
555
+									esc_html__('IMPORTANT', 'event_espresso'),
556
+									'',
557
+									'important-notice'
558
+								)
559
+							)
560
+						) .
561
+						EEH_HTML::td(
562
+							EEH_HTML::strong(
563
+								sprintf(
564
+									esc_html__(
565
+										'This payment method does not support the currency set on your site (%1$s). Please activate a different payment method or change your site\'s country and associated currency.',
566
+										'event_espresso'
567
+									),
568
+									EE_Config::instance()->currency->code
569
+								)
570
+							)
571
+						)
572
+					)
573
+				)
574
+			);
575
+		}
576
+		return new EE_Form_Section_HTML('');
577
+	}
578
+
579
+
580
+	/**
581
+	 * _update_payment_method_button
582
+	 *
583
+	 * @access protected
584
+	 * @param EE_Payment_Method $payment_method
585
+	 * @return EE_Payment_Method_Form
586
+	 * @throws EE_Error
587
+	 */
588
+	protected function _payment_method_settings(EE_Payment_Method $payment_method)
589
+	{
590
+		// modify the form, so we only have/show fields that will be implemented for this version
591
+		return $this->_simplify_form($payment_method->type_obj()->settings_form(), $payment_method->name());
592
+	}
593
+
594
+
595
+	/**
596
+	 * Simplifies the form to merely reproduce 4.1's gateway settings functionality
597
+	 *
598
+	 * @param EE_Form_Section_Proper $form_section
599
+	 * @param string                 $payment_method_name
600
+	 * @return EE_Payment_Method_Form
601
+	 * @throws EE_Error
602
+	 */
603
+	protected function _simplify_form($form_section, $payment_method_name = '')
604
+	{
605
+		if ($form_section instanceof EE_Payment_Method_Form) {
606
+			$form_section->exclude(
607
+				array(
608
+					'PMD_type', // don't want them changing the type
609
+					'PMD_slug', // or the slug (probably never)
610
+					'PMD_wp_user', // or the user's ID
611
+					'Currency' // or the currency, until the rest of EE supports simultaneous currencies
612
+				)
613
+			);
614
+			return $form_section;
615
+		} else {
616
+			throw new EE_Error(
617
+				sprintf(
618
+					esc_html__(
619
+						'The EE_Payment_Method_Form for the "%1$s" payment method is missing or invalid.',
620
+						'event_espresso'
621
+					),
622
+					$payment_method_name
623
+				)
624
+			);
625
+		}
626
+	}
627
+
628
+
629
+	/**
630
+	 * _update_payment_method_button
631
+	 *
632
+	 * @access protected
633
+	 * @param EE_Payment_Method $payment_method
634
+	 * @return EE_Form_Section_HTML
635
+	 * @throws EE_Error
636
+	 */
637
+	protected function _update_payment_method_button(EE_Payment_Method $payment_method)
638
+	{
639
+		$update_button = new EE_Submit_Input(
640
+			array(
641
+				'name'       => 'submit',
642
+				'html_id'    => 'save_' . $payment_method->slug() . '_settings',
643
+				'default'    => sprintf(
644
+					esc_html__('Update %s Payment Settings', 'event_espresso'),
645
+					$payment_method->admin_name()
646
+				),
647
+				'html_label' => EEH_HTML::nbsp(),
648
+			)
649
+		);
650
+		return new EE_Form_Section_HTML(
651
+			EEH_HTML::table(
652
+				EEH_HTML::no_row(EEH_HTML::br(2)) .
653
+				EEH_HTML::tr(
654
+					EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')) .
655
+					EEH_HTML::td(
656
+						$update_button->get_html_for_input()
657
+					)
658
+				)
659
+			)
660
+		);
661
+	}
662
+
663
+
664
+	/**
665
+	 * _deactivate_payment_method_button
666
+	 *
667
+	 * @access protected
668
+	 * @param EE_Payment_Method $payment_method
669
+	 * @return EE_Form_Section_HTML
670
+	 */
671
+	protected function _deactivate_payment_method_button(EE_Payment_Method $payment_method)
672
+	{
673
+		$link_text_and_title = sprintf(
674
+			esc_html__('Deactivate %1$s Payments?', 'event_espresso'),
675
+			$payment_method->admin_name()
676
+		);
677
+		return new EE_Form_Section_HTML(
678
+			EEH_HTML::table(
679
+				EEH_HTML::tr(
680
+					EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')) .
681
+					EEH_HTML::td(
682
+						EEH_HTML::link(
683
+							EE_Admin_Page::add_query_args_and_nonce(
684
+								array(
685
+									'action'         => 'deactivate_payment_method',
686
+									'payment_method' => $payment_method->slug(),
687
+								),
688
+								EE_PAYMENTS_ADMIN_URL
689
+							),
690
+							$link_text_and_title,
691
+							$link_text_and_title,
692
+							'deactivate_' . $payment_method->slug(),
693
+							'espresso-button button-secondary'
694
+						)
695
+					)
696
+				)
697
+			)
698
+		);
699
+	}
700
+
701
+
702
+	/**
703
+	 * _activate_payment_method_button
704
+	 *
705
+	 * @access protected
706
+	 * @param EE_Payment_Method $payment_method
707
+	 * @return EE_Form_Section_Proper
708
+	 * @throws EE_Error
709
+	 */
710
+	protected function _activate_payment_method_button(EE_Payment_Method $payment_method)
711
+	{
712
+		$link_text_and_title = sprintf(
713
+			esc_html__('Activate %1$s Payment Method?', 'event_espresso'),
714
+			$payment_method->admin_name()
715
+		);
716
+		return new EE_Form_Section_Proper(
717
+			array(
718
+				'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
719
+				'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
720
+				'action'          => '#',
721
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
722
+				'subsections'     => apply_filters(
723
+					'FHEE__Payments_Admin_Page___activate_payment_method_button__form_subsections',
724
+					array(
725
+						new EE_Form_Section_HTML(
726
+							EEH_HTML::table(
727
+								EEH_HTML::tr(
728
+									EEH_HTML::td(
729
+										$payment_method->type_obj()->introductory_html(),
730
+										'',
731
+										'',
732
+										'',
733
+										'colspan="2"'
734
+									)
735
+								) .
736
+								EEH_HTML::tr(
737
+									EEH_HTML::th(
738
+										EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
739
+									) .
740
+									EEH_HTML::td(
741
+										EEH_HTML::link(
742
+											EE_Admin_Page::add_query_args_and_nonce(
743
+												array(
744
+													'action'              => 'activate_payment_method',
745
+													'payment_method_type' => $payment_method->type(),
746
+												),
747
+												EE_PAYMENTS_ADMIN_URL
748
+											),
749
+											$link_text_and_title,
750
+											$link_text_and_title,
751
+											'activate_' . $payment_method->slug(),
752
+											'espresso-button-green button-primary'
753
+										)
754
+									)
755
+								)
756
+							)
757
+						),
758
+					),
759
+					$payment_method
760
+				),
761
+			)
762
+		);
763
+	}
764
+
765
+
766
+	/**
767
+	 * _fine_print
768
+	 *
769
+	 * @access protected
770
+	 * @return EE_Form_Section_HTML
771
+	 */
772
+	protected function _fine_print()
773
+	{
774
+		return new EE_Form_Section_HTML(
775
+			EEH_HTML::table(
776
+				EEH_HTML::tr(
777
+					EEH_HTML::th() .
778
+					EEH_HTML::td(
779
+						EEH_HTML::p(esc_html__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text')
780
+					)
781
+				)
782
+			)
783
+		);
784
+	}
785
+
786
+
787
+	/**
788
+	 * Activates a payment method of that type. Mostly assuming there is only 1 of that type (or none so far)
789
+	 *
790
+	 * @throws EE_Error
791
+	 * @throws ReflectionException
792
+	 * @global WP_User $current_user
793
+	 */
794
+	protected function _activate_payment_method()
795
+	{
796
+		if (isset($this->_req_data['payment_method_type'])) {
797
+			$payment_method_type = sanitize_text_field($this->_req_data['payment_method_type']);
798
+			// see if one exists
799
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
800
+			$payment_method = EE_Payment_Method_Manager::instance()
801
+													   ->activate_a_payment_method_of_type($payment_method_type);
802
+			$this->_redirect_after_action(
803
+				1,
804
+				'Payment Method',
805
+				'activated',
806
+				array('action' => 'default', 'payment_method' => $payment_method->slug())
807
+			);
808
+		} else {
809
+			$this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
810
+		}
811
+	}
812
+
813
+
814
+	/**
815
+	 * @throws EE_Error
816
+	 * @throws ReflectionException
817
+	 */
818
+	protected function _deactivate_payment_method()
819
+	{
820
+		if (isset($this->_req_data['payment_method'])) {
821
+			$payment_method_slug = sanitize_key($this->_req_data['payment_method']);
822
+			// deactivate it
823
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
824
+			$count_updated = EE_Payment_Method_Manager::instance()->deactivate_payment_method($payment_method_slug);
825
+			$this->_redirect_after_action(
826
+				$count_updated,
827
+				'Payment Method',
828
+				'deactivated',
829
+				array('action' => 'default', 'payment_method' => $payment_method_slug)
830
+			);
831
+		} else {
832
+			$this->_redirect_after_action(false, 'Payment Method', 'deactivated', array('action' => 'default'));
833
+		}
834
+	}
835
+
836
+
837
+	/**
838
+	 * Processes the payment method form that was submitted. This is slightly trickier than usual form
839
+	 * processing because we first need to identify WHICH form was processed and which payment method
840
+	 * it corresponds to. Once we have done that, we see if the form is valid. If it is, the
841
+	 * form's data is saved, and we redirect to the default payment methods page, setting the updated payment method
842
+	 * as the currently-selected one. If it DOESN'T validate, we render the page with the form's errors (in the
843
+	 * subsequently called 'headers_sent_func' which is _payment_methods_list)
844
+	 *
845
+	 * @return void
846
+	 * @throws EE_Error
847
+	 * @throws ReflectionException
848
+	 */
849
+	protected function _update_payment_method()
850
+	{
851
+		if ($_SERVER['REQUEST_METHOD'] == 'POST') {
852
+			// ok let's find which gateway form to use based on the form input
853
+			EE_Registry::instance()->load_lib('Payment_Method_Manager');
854
+			/** @var $correct_pmt_form_to_use EE_Payment_Method_Form */
855
+			$correct_pmt_form_to_use = null;
856
+			$payment_method = null;
857
+			foreach (EEM_Payment_Method::instance()->get_all() as $payment_method) {
858
+				if ($payment_method instanceof EE_Payment_Method) {
859
+					// get the form and simplify it, like what we do when we display it
860
+					$pmt_form = $this->_generate_payment_method_settings_form($payment_method);
861
+					if ($pmt_form->form_data_present_in($this->_req_data)) {
862
+						$correct_pmt_form_to_use = $pmt_form;
863
+						break;
864
+					}
865
+				}
866
+			}
867
+			// if we couldn't find the correct payment method type...
868
+			if (! $correct_pmt_form_to_use) {
869
+				EE_Error::add_error(
870
+					esc_html__(
871
+						"We could not find which payment method type your form submission related to. Please contact support",
872
+						'event_espresso'
873
+					),
874
+					__FILE__,
875
+					__FUNCTION__,
876
+					__LINE__
877
+				);
878
+				$this->_redirect_after_action(false, 'Payment Method', 'activated', array('action' => 'default'));
879
+			}
880
+			$correct_pmt_form_to_use->receive_form_submission($this->_req_data);
881
+			if ($correct_pmt_form_to_use->is_valid()) {
882
+				$payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
883
+				if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
884
+					throw new EE_Error(
885
+						sprintf(
886
+							esc_html__(
887
+								'The payment method could not be saved because the form sections were misnamed. We expected to find %1$s, but did not.',
888
+								'event_espresso'
889
+							),
890
+							'payment_method_settings'
891
+						)
892
+					);
893
+				}
894
+				$payment_settings_subform->save();
895
+				/** @var $pm EE_Payment_Method */
896
+				$this->_redirect_after_action(
897
+					true,
898
+					'Payment Method',
899
+					'updated',
900
+					array('action' => 'default', 'payment_method' => $payment_method->slug())
901
+				);
902
+			} else {
903
+				EE_Error::add_error(
904
+					sprintf(
905
+						esc_html__(
906
+							'Payment method of type %s was not saved because there were validation errors. They have been marked in the form',
907
+							'event_espresso'
908
+						),
909
+						$payment_method instanceof EE_Payment_Method ? $payment_method->type_obj()->pretty_name()
910
+							: esc_html__('"(unknown)"', 'event_espresso')
911
+					),
912
+					__FILE__,
913
+					__FUNCTION__,
914
+					__LINE__
915
+				);
916
+			}
917
+		}
918
+	}
919
+
920
+
921
+	/**
922
+	 * Displays payment settings (not payment METHOD settings, that's _payment_method_settings)
923
+	 * @throws DomainException
924
+	 * @throws EE_Error
925
+	 * @throws InvalidArgumentException
926
+	 * @throws InvalidDataTypeException
927
+	 * @throws InvalidInterfaceException
928
+	 */
929
+	protected function _payment_settings()
930
+	{
931
+		$form = $this->getPaymentSettingsForm();
932
+		$this->_set_add_edit_form_tags('update_payment_settings');
933
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
934
+		$this->_template_args['admin_page_content'] =  $form->get_html_and_js();
935
+		$this->display_admin_page_with_sidebar();
936
+	}
937
+
938
+
939
+	/**
940
+	 *        _update_payment_settings
941
+	 *
942
+	 * @access protected
943
+	 * @return void
944
+	 * @throws EE_Error
945
+	 * @throws InvalidArgumentException
946
+	 * @throws InvalidDataTypeException
947
+	 * @throws InvalidInterfaceException
948
+	 */
949
+	protected function _update_payment_settings()
950
+	{
951
+		$form = $this->getPaymentSettingsForm();
952
+		if ($form->was_submitted($this->_req_data)) {
953
+			$form->receive_form_submission($this->_req_data);
954
+			if ($form->is_valid()) {
955
+				/**
956
+				 * @var $reg_config EE_Registration_Config
957
+				 */
958
+				$loader = LoaderFactory::getLoader();
959
+				$reg_config = $loader->getShared('EE_Registration_Config');
960
+				$valid_data = $form->valid_data();
961
+				$reg_config->show_pending_payment_options = $valid_data['show_pending_payment_options'];
962
+				$reg_config->gateway_log_lifespan = $valid_data['gateway_log_lifespan'];
963
+			}
964
+		}
965
+		EE_Registry::instance()->CFG = apply_filters(
966
+			'FHEE__Payments_Admin_Page___update_payment_settings__CFG',
967
+			EE_Registry::instance()->CFG
968
+		);
969
+
970
+		$what = esc_html__('Payment Settings', 'event_espresso');
971
+		$success = $this->_update_espresso_configuration(
972
+			$what,
973
+			EE_Registry::instance()->CFG,
974
+			__FILE__,
975
+			__FUNCTION__,
976
+			__LINE__
977
+		);
978
+		$this->_redirect_after_action(
979
+			$success,
980
+			$what,
981
+			esc_html__('updated', 'event_espresso'),
982
+			array('action' => 'payment_settings')
983
+		);
984
+	}
985
+
986
+
987
+	/**
988
+	 * Gets the form used for updating payment settings
989
+	 *
990
+	 * @return EE_Form_Section_Proper
991
+	 * @throws EE_Error
992
+	 * @throws InvalidArgumentException
993
+	 * @throws InvalidDataTypeException
994
+	 * @throws InvalidInterfaceException
995
+	 */
996
+	protected function getPaymentSettingsForm()
997
+	{
998
+		/**
999
+		 * @var $reg_config EE_Registration_Config
1000
+		 */
1001
+		$reg_config = LoaderFactory::getLoader()->getShared('EE_Registration_Config');
1002
+		return new EE_Form_Section_Proper(
1003
+			array(
1004
+				'name' => 'payment-settings',
1005
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1006
+				'subsections' => array(
1007
+					'show_pending_payment_options' => new EE_Yes_No_Input(
1008
+						array(
1009
+							'html_name' => 'show_pending_payment_options',
1010
+							'default' => $reg_config->show_pending_payment_options,
1011
+							'html_help_text' => esc_html__(
1012
+								"If a payment is marked as 'Pending Payment', or if payment is deferred (ie, an offline gateway like Check, Bank, or Invoice is used), then give registrants the option to retry payment. ",
1013
+								'event_espresso'
1014
+							)
1015
+						)
1016
+					),
1017
+					'gateway_log_lifespan' => new EE_Select_Input(
1018
+						$reg_config->gatewayLogLifespanOptions(),
1019
+						array(
1020
+							'html_label_text' => esc_html__('Gateway Logs Lifespan', 'event_espresso'),
1021
+							'html_help_text' => esc_html__('If issues arise with payments being made through a payment gateway, it\'s helpful to log non-sensitive communications with the payment gateway. But it\'s a security responsibility, so it\'s a good idea to not keep them for any longer than necessary.', 'event_espresso'),
1022
+							'default' => $reg_config->gateway_log_lifespan,
1023
+						)
1024
+					)
1025
+				)
1026
+			)
1027
+		);
1028
+	}
1029
+
1030
+
1031
+	/**
1032
+	 * @throws EE_Error
1033
+	 */
1034
+	protected function _payment_log_overview_list_table()
1035
+	{
1036
+		$this->display_admin_list_table_page_with_sidebar();
1037
+	}
1038
+
1039
+
1040
+	protected function _set_list_table_views_payment_log()
1041
+	{
1042
+		$this->_views = array(
1043
+			'all' => array(
1044
+				'slug'  => 'all',
1045
+				'label' => esc_html__('View All Logs', 'event_espresso'),
1046
+				'count' => 0,
1047
+			),
1048
+		);
1049
+	}
1050
+
1051
+
1052
+	/**
1053
+	 * @param int  $per_page
1054
+	 * @param int  $current_page
1055
+	 * @param bool $count
1056
+	 * @return array|int
1057
+	 * @throws EE_Error
1058
+	 * @throws ReflectionException
1059
+	 */
1060
+	public function get_payment_logs($per_page = 50, $current_page = 0, $count = false)
1061
+	{
1062
+		EE_Registry::instance()->load_model('Change_Log');
1063
+		// we may need to do multiple queries (joining differently), so we actually want an array of query params
1064
+		$query_params = array(array('LOG_type' => EEM_Change_Log::type_gateway));
1065
+		// check if they've selected a specific payment method
1066
+		if (isset($this->_req_data['_payment_method']) && $this->_req_data['_payment_method'] !== 'all') {
1067
+			$query_params[0]['OR*pm_or_pay_pm'] = array(
1068
+				'Payment.Payment_Method.PMD_ID' => $this->_req_data['_payment_method'],
1069
+				'Payment_Method.PMD_ID'         => $this->_req_data['_payment_method'],
1070
+			);
1071
+		}
1072
+		// take into account search
1073
+		if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1074
+			$similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%');
1075
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1076
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1077
+			$query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
1078
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_name'] = $similarity_string;
1079
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_admin_name'] = $similarity_string;
1080
+			$query_params[0]['OR*s']['Payment.Payment_Method.PMD_type'] = $similarity_string;
1081
+			$query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1082
+			$query_params[0]['OR*s']['Payment_Method.PMD_name'] = $similarity_string;
1083
+			$query_params[0]['OR*s']['Payment_Method.PMD_admin_name'] = $similarity_string;
1084
+			$query_params[0]['OR*s']['Payment_Method.PMD_type'] = $similarity_string;
1085
+			$query_params[0]['OR*s']['LOG_message'] = $similarity_string;
1086
+		}
1087
+		if (
1088
+			isset($this->_req_data['payment-filter-start-date'])
1089
+			&& isset($this->_req_data['payment-filter-end-date'])
1090
+		) {
1091
+			// add date
1092
+			$start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1093
+			$end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1094
+			// make sure our timestamps start and end right at the boundaries for each day
1095
+			$start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1096
+			$end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1097
+			// convert to timestamps
1098
+			$start_date = strtotime($start_date);
1099
+			$end_date = strtotime($end_date);
1100
+			// makes sure start date is the lowest value and vice versa
1101
+			$start_date = min($start_date, $end_date);
1102
+			$end_date = max($start_date, $end_date);
1103
+			// convert for query
1104
+			$start_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1105
+				'LOG_time',
1106
+				date('Y-m-d H:i:s', $start_date),
1107
+				'Y-m-d H:i:s'
1108
+			);
1109
+			$end_date   = EEM_Change_Log::instance()->convert_datetime_for_query(
1110
+				'LOG_time',
1111
+				date('Y-m-d H:i:s', $end_date),
1112
+				'Y-m-d H:i:s'
1113
+			);
1114
+			$query_params[0]['LOG_time'] = array('BETWEEN', array($start_date, $end_date));
1115
+		}
1116
+		if ($count) {
1117
+			return EEM_Change_Log::instance()->count($query_params);
1118
+		}
1119
+		if (isset($this->_req_data['order'])) {
1120
+			$sort = (isset($this->_req_data['order']) && ! empty($this->_req_data['order']))
1121
+				? $this->_req_data['order']
1122
+				: 'DESC';
1123
+			$query_params['order_by'] = array('LOG_time' => $sort);
1124
+		} else {
1125
+			$query_params['order_by'] = array('LOG_time' => 'DESC');
1126
+		}
1127
+		$offset = ($current_page - 1) * $per_page;
1128
+		if (! isset($this->_req_data['download_results'])) {
1129
+			$query_params['limit'] = array($offset, $per_page);
1130
+		}
1131
+		// now they've requested to instead just download the file instead of viewing it.
1132
+		if (isset($this->_req_data['download_results'])) {
1133
+			$wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1134
+			header('Content-Disposition: attachment');
1135
+			header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1136
+			echo '<h1> '
1137
+				. sprintf(
1138
+					esc_html__('Payment Logs for %1$s', 'event_espresso'),
1139
+					esc_url_raw(site_url())
1140
+				)
1141
+				. '</h1 >';
1142
+			echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1143
+			echo esc_html(var_export($query_params, true));
1144
+			echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1145
+			echo esc_html(var_export($wpdb_results, true));
1146
+			die;
1147
+		}
1148
+		return EEM_Change_Log::instance()->get_all($query_params);
1149
+	}
1150
+
1151
+
1152
+	/**
1153
+	 * Used by usort to RE-sort log query results, because we lose the ordering
1154
+	 * because we're possibly combining the results from two queries
1155
+	 *
1156
+	 * @param EE_Change_Log $logA
1157
+	 * @param EE_Change_Log $logB
1158
+	 * @return int
1159
+	 * @throws EE_Error
1160
+	 * @throws ReflectionException
1161
+	 */
1162
+	protected function _sort_logs_again($logA, $logB)
1163
+	{
1164
+		$timeA = $logA->get_raw('LOG_time');
1165
+		$timeB = $logB->get_raw('LOG_time');
1166
+		if ($timeA == $timeB) {
1167
+			return 0;
1168
+		}
1169
+		$comparison = $timeA < $timeB ? -1 : 1;
1170
+		if (strtoupper($this->_sort_logs_again_direction) == 'DESC') {
1171
+			return $comparison * -1;
1172
+		}
1173
+		return $comparison;
1174
+	}
1175
+
1176
+
1177
+	/**
1178
+	 * @throws EE_Error
1179
+	 * @throws ReflectionException
1180
+	 */
1181
+	protected function _payment_log_details()
1182
+	{
1183
+		EE_Registry::instance()->load_model('Change_Log');
1184
+		/** @var $payment_log EE_Change_Log */
1185
+		$payment_log = EEM_Change_Log::instance()->get_one_by_ID($this->_req_data['ID']);
1186
+		$payment_method = null;
1187
+		$transaction = null;
1188
+		if ($payment_log instanceof EE_Change_Log) {
1189
+			if ($payment_log->object() instanceof EE_Payment) {
1190
+				$payment_method = $payment_log->object()->payment_method();
1191
+				$transaction = $payment_log->object()->transaction();
1192
+			} elseif ($payment_log->object() instanceof EE_Payment_Method) {
1193
+				$payment_method = $payment_log->object();
1194
+			} elseif ($payment_log->object() instanceof EE_Transaction) {
1195
+				$transaction = $payment_log->object();
1196
+				$payment_method = $transaction->payment_method();
1197
+			}
1198
+		}
1199
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1200
+			EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1201
+			array(
1202
+				'payment_log'    => $payment_log,
1203
+				'payment_method' => $payment_method,
1204
+				'transaction'    => $transaction,
1205
+			),
1206
+			true
1207
+		);
1208
+		$this->display_admin_page_with_sidebar();
1209
+	}
1210 1210
 }
Please login to merge, or discard this patch.
Spacing   +41 added lines, -41 removed lines patch added patch discarded remove patch
@@ -195,10 +195,10 @@  discard block
 block discarded – undo
195 195
             foreach ($payment_method_type->help_tabs_config() as $help_tab_name => $config) {
196 196
                 $template_args = isset($config['template_args']) ? $config['template_args'] : array();
197 197
                 $template_args['admin_page_obj'] = $this;
198
-                $all_pmt_help_tabs_config[ $help_tab_name ] = array(
198
+                $all_pmt_help_tabs_config[$help_tab_name] = array(
199 199
                     'title'   => $config['title'],
200 200
                     'content' => EEH_Template::display_template(
201
-                        $payment_method_type->file_folder() . 'help_tabs/' . $config['filename'] . '.help_tab.php',
201
+                        $payment_method_type->file_folder().'help_tabs/'.$config['filename'].'.help_tab.php',
202 202
                         $template_args,
203 203
                         true
204 204
                     ),
@@ -244,7 +244,7 @@  discard block
 block discarded – undo
244 244
         wp_enqueue_script('ee-text-links');
245 245
         wp_enqueue_script(
246 246
             'espresso_payments',
247
-            EE_PAYMENTS_ASSETS_URL . 'espresso_payments_admin.js',
247
+            EE_PAYMENTS_ASSETS_URL.'espresso_payments_admin.js',
248 248
             array('ee-datepicker'),
249 249
             EVENT_ESPRESSO_VERSION,
250 250
             true
@@ -257,7 +257,7 @@  discard block
 block discarded – undo
257 257
         // styles
258 258
         wp_register_style(
259 259
             'espresso_payments',
260
-            EE_PAYMENTS_ASSETS_URL . 'ee-payments.css',
260
+            EE_PAYMENTS_ASSETS_URL.'ee-payments.css',
261 261
             array(),
262 262
             EVENT_ESPRESSO_VERSION
263 263
         );
@@ -301,7 +301,7 @@  discard block
 block discarded – undo
301 301
             }
302 302
             // check for any active pms of that type
303 303
             $payment_method = EEM_Payment_Method::instance()->get_one_of_type($pmt_obj->system_name());
304
-            if (! $payment_method instanceof EE_Payment_Method) {
304
+            if ( ! $payment_method instanceof EE_Payment_Method) {
305 305
                 $payment_method = EE_Payment_Method::new_instance(
306 306
                     array(
307 307
                         'PMD_slug'       => sanitize_key($pmt_obj->system_name()),
@@ -311,7 +311,7 @@  discard block
 block discarded – undo
311 311
                     )
312 312
                 );
313 313
             }
314
-            $payment_methods[ $payment_method->slug() ] = $payment_method;
314
+            $payment_methods[$payment_method->slug()] = $payment_method;
315 315
         }
316 316
         $payment_methods = apply_filters(
317 317
             'FHEE__Payments_Admin_Page___payment_methods_list__payment_methods',
@@ -321,7 +321,7 @@  discard block
 block discarded – undo
321 321
             if ($payment_method instanceof EE_Payment_Method) {
322 322
                 add_meta_box(
323 323
                     // html id
324
-                    'espresso_' . $payment_method->slug() . '_payment_settings',
324
+                    'espresso_'.$payment_method->slug().'_payment_settings',
325 325
                     // title
326 326
                     sprintf(esc_html__('%s Settings', 'event_espresso'), $payment_method->admin_name()),
327 327
                     // callback
@@ -336,10 +336,10 @@  discard block
 block discarded – undo
336 336
                     array('payment_method' => $payment_method)
337 337
                 );
338 338
                 // setup for tabbed content
339
-                $tabs[ $payment_method->slug() ] = array(
339
+                $tabs[$payment_method->slug()] = array(
340 340
                     'label' => $payment_method->admin_name(),
341 341
                     'class' => $payment_method->active() ? 'gateway-active' : '',
342
-                    'href'  => 'espresso_' . $payment_method->slug() . '_payment_settings',
342
+                    'href'  => 'espresso_'.$payment_method->slug().'_payment_settings',
343 343
                     'title' => esc_html__('Modify this Payment Method', 'event_espresso'),
344 344
                     'slug'  => $payment_method->slug(),
345 345
                 );
@@ -372,7 +372,7 @@  discard block
 block discarded – undo
372 372
         /** @var EE_Payment_Method $payment_method */
373 373
         $payment_method = EEM_Payment_Method::instance()->get_one(array(array('PMD_slug' => $payment_method_slug)));
374 374
         // if that didn't work or wasn't provided, find another way to select the current pm
375
-        if (! $this->_verify_payment_method($payment_method)) {
375
+        if ( ! $this->_verify_payment_method($payment_method)) {
376 376
             // like, looking for an active one
377 377
             $payment_method = EEM_Payment_Method::instance()->get_one_active('CART');
378 378
             // test that one as well
@@ -424,7 +424,7 @@  discard block
 block discarded – undo
424 424
     {
425 425
         $payment_method = isset($metabox['args'], $metabox['args']['payment_method'])
426 426
             ? $metabox['args']['payment_method'] : null;
427
-        if (! $payment_method instanceof EE_Payment_Method) {
427
+        if ( ! $payment_method instanceof EE_Payment_Method) {
428 428
             throw new EE_Error(
429 429
                 esc_html__(
430 430
                     'Payment method metabox setup incorrectly. No Payment method object was supplied',
@@ -439,7 +439,7 @@  discard block
 block discarded – undo
439 439
             if ($form->form_data_present_in($this->_req_data)) {
440 440
                 $form->receive_form_submission($this->_req_data);
441 441
             }
442
-            echo wp_kses($form->form_open() . $form->get_html_and_js() . $form->form_close(), AllowedTags::getWithFormTags());
442
+            echo wp_kses($form->form_open().$form->get_html_and_js().$form->form_close(), AllowedTags::getWithFormTags());
443 443
         } else {
444 444
             echo wp_kses($this->_activate_payment_method_button($payment_method)->get_html_and_js(), AllowedTags::getWithFormTags());
445 445
         }
@@ -456,13 +456,13 @@  discard block
 block discarded – undo
456 456
      */
457 457
     protected function _generate_payment_method_settings_form(EE_Payment_Method $payment_method = null)
458 458
     {
459
-        if (! $payment_method instanceof EE_Payment_Method) {
459
+        if ( ! $payment_method instanceof EE_Payment_Method) {
460 460
             return new EE_Form_Section_Proper();
461 461
         }
462 462
         return new EE_Form_Section_Proper(
463 463
             array(
464
-                'name'            => $payment_method->slug() . '_settings_form',
465
-                'html_id'         => $payment_method->slug() . '_settings_form',
464
+                'name'            => $payment_method->slug().'_settings_form',
465
+                'html_id'         => $payment_method->slug().'_settings_form',
466 466
                 'action'          => EE_Admin_Page::add_query_args_and_nonce(
467 467
                     array(
468 468
                         'action'         => 'update_payment_method',
@@ -510,7 +510,7 @@  discard block
 block discarded – undo
510 510
                                     'important-notice'
511 511
                                 )
512 512
                             )
513
-                        ) .
513
+                        ).
514 514
                         EEH_HTML::td(
515 515
                             EEH_HTML::strong(
516 516
                                 esc_html__(
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
      */
546 546
     protected function _currency_support(EE_Payment_Method $payment_method)
547 547
     {
548
-        if (! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
548
+        if ( ! $payment_method->usable_for_currency(EE_Config::instance()->currency->code)) {
549 549
             return new EE_Form_Section_HTML(
550 550
                 EEH_HTML::table(
551 551
                     EEH_HTML::tr(
@@ -557,7 +557,7 @@  discard block
 block discarded – undo
557 557
                                     'important-notice'
558 558
                                 )
559 559
                             )
560
-                        ) .
560
+                        ).
561 561
                         EEH_HTML::td(
562 562
                             EEH_HTML::strong(
563 563
                                 sprintf(
@@ -639,7 +639,7 @@  discard block
 block discarded – undo
639 639
         $update_button = new EE_Submit_Input(
640 640
             array(
641 641
                 'name'       => 'submit',
642
-                'html_id'    => 'save_' . $payment_method->slug() . '_settings',
642
+                'html_id'    => 'save_'.$payment_method->slug().'_settings',
643 643
                 'default'    => sprintf(
644 644
                     esc_html__('Update %s Payment Settings', 'event_espresso'),
645 645
                     $payment_method->admin_name()
@@ -649,9 +649,9 @@  discard block
 block discarded – undo
649 649
         );
650 650
         return new EE_Form_Section_HTML(
651 651
             EEH_HTML::table(
652
-                EEH_HTML::no_row(EEH_HTML::br(2)) .
652
+                EEH_HTML::no_row(EEH_HTML::br(2)).
653 653
                 EEH_HTML::tr(
654
-                    EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')) .
654
+                    EEH_HTML::th(esc_html__('Update Settings', 'event_espresso')).
655 655
                     EEH_HTML::td(
656 656
                         $update_button->get_html_for_input()
657 657
                     )
@@ -677,7 +677,7 @@  discard block
 block discarded – undo
677 677
         return new EE_Form_Section_HTML(
678 678
             EEH_HTML::table(
679 679
                 EEH_HTML::tr(
680
-                    EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')) .
680
+                    EEH_HTML::th(esc_html__('Deactivate Payment Method', 'event_espresso')).
681 681
                     EEH_HTML::td(
682 682
                         EEH_HTML::link(
683 683
                             EE_Admin_Page::add_query_args_and_nonce(
@@ -689,7 +689,7 @@  discard block
 block discarded – undo
689 689
                             ),
690 690
                             $link_text_and_title,
691 691
                             $link_text_and_title,
692
-                            'deactivate_' . $payment_method->slug(),
692
+                            'deactivate_'.$payment_method->slug(),
693 693
                             'espresso-button button-secondary'
694 694
                         )
695 695
                     )
@@ -715,8 +715,8 @@  discard block
 block discarded – undo
715 715
         );
716 716
         return new EE_Form_Section_Proper(
717 717
             array(
718
-                'name'            => 'activate_' . $payment_method->slug() . '_settings_form',
719
-                'html_id'         => 'activate_' . $payment_method->slug() . '_settings_form',
718
+                'name'            => 'activate_'.$payment_method->slug().'_settings_form',
719
+                'html_id'         => 'activate_'.$payment_method->slug().'_settings_form',
720 720
                 'action'          => '#',
721 721
                 'layout_strategy' => new EE_Admin_Two_Column_Layout(),
722 722
                 'subsections'     => apply_filters(
@@ -732,11 +732,11 @@  discard block
 block discarded – undo
732 732
                                         '',
733 733
                                         'colspan="2"'
734 734
                                     )
735
-                                ) .
735
+                                ).
736 736
                                 EEH_HTML::tr(
737 737
                                     EEH_HTML::th(
738 738
                                         EEH_HTML::label(esc_html__('Click to Activate ', 'event_espresso'))
739
-                                    ) .
739
+                                    ).
740 740
                                     EEH_HTML::td(
741 741
                                         EEH_HTML::link(
742 742
                                             EE_Admin_Page::add_query_args_and_nonce(
@@ -748,7 +748,7 @@  discard block
 block discarded – undo
748 748
                                             ),
749 749
                                             $link_text_and_title,
750 750
                                             $link_text_and_title,
751
-                                            'activate_' . $payment_method->slug(),
751
+                                            'activate_'.$payment_method->slug(),
752 752
                                             'espresso-button-green button-primary'
753 753
                                         )
754 754
                                     )
@@ -774,7 +774,7 @@  discard block
 block discarded – undo
774 774
         return new EE_Form_Section_HTML(
775 775
             EEH_HTML::table(
776 776
                 EEH_HTML::tr(
777
-                    EEH_HTML::th() .
777
+                    EEH_HTML::th().
778 778
                     EEH_HTML::td(
779 779
                         EEH_HTML::p(esc_html__('All fields marked with a * are required fields', 'event_espresso'), '', 'grey-text')
780 780
                     )
@@ -865,7 +865,7 @@  discard block
 block discarded – undo
865 865
                 }
866 866
             }
867 867
             // if we couldn't find the correct payment method type...
868
-            if (! $correct_pmt_form_to_use) {
868
+            if ( ! $correct_pmt_form_to_use) {
869 869
                 EE_Error::add_error(
870 870
                     esc_html__(
871 871
                         "We could not find which payment method type your form submission related to. Please contact support",
@@ -880,7 +880,7 @@  discard block
 block discarded – undo
880 880
             $correct_pmt_form_to_use->receive_form_submission($this->_req_data);
881 881
             if ($correct_pmt_form_to_use->is_valid()) {
882 882
                 $payment_settings_subform = $correct_pmt_form_to_use->get_subsection('payment_method_settings');
883
-                if (! $payment_settings_subform instanceof EE_Payment_Method_Form) {
883
+                if ( ! $payment_settings_subform instanceof EE_Payment_Method_Form) {
884 884
                     throw new EE_Error(
885 885
                         sprintf(
886 886
                             esc_html__(
@@ -931,7 +931,7 @@  discard block
 block discarded – undo
931 931
         $form = $this->getPaymentSettingsForm();
932 932
         $this->_set_add_edit_form_tags('update_payment_settings');
933 933
         $this->_set_publish_post_box_vars(null, false, false, null, false);
934
-        $this->_template_args['admin_page_content'] =  $form->get_html_and_js();
934
+        $this->_template_args['admin_page_content'] = $form->get_html_and_js();
935 935
         $this->display_admin_page_with_sidebar();
936 936
     }
937 937
 
@@ -1071,7 +1071,7 @@  discard block
 block discarded – undo
1071 1071
         }
1072 1072
         // take into account search
1073 1073
         if (isset($this->_req_data['s']) && $this->_req_data['s']) {
1074
-            $similarity_string = array('LIKE', '%' . str_replace("", "%", $this->_req_data['s']) . '%');
1074
+            $similarity_string = array('LIKE', '%'.str_replace("", "%", $this->_req_data['s']).'%');
1075 1075
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_fname'] = $similarity_string;
1076 1076
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_lname'] = $similarity_string;
1077 1077
             $query_params[0]['OR*s']['Payment.Transaction.Registration.Attendee.ATT_email'] = $similarity_string;
@@ -1092,8 +1092,8 @@  discard block
 block discarded – undo
1092 1092
             $start_date = wp_strip_all_tags($this->_req_data['payment-filter-start-date']);
1093 1093
             $end_date = wp_strip_all_tags($this->_req_data['payment-filter-end-date']);
1094 1094
             // make sure our timestamps start and end right at the boundaries for each day
1095
-            $start_date = date('Y-m-d', strtotime($start_date)) . ' 00:00:00';
1096
-            $end_date = date('Y-m-d', strtotime($end_date)) . ' 23:59:59';
1095
+            $start_date = date('Y-m-d', strtotime($start_date)).' 00:00:00';
1096
+            $end_date = date('Y-m-d', strtotime($end_date)).' 23:59:59';
1097 1097
             // convert to timestamps
1098 1098
             $start_date = strtotime($start_date);
1099 1099
             $end_date = strtotime($end_date);
@@ -1106,7 +1106,7 @@  discard block
 block discarded – undo
1106 1106
                 date('Y-m-d H:i:s', $start_date),
1107 1107
                 'Y-m-d H:i:s'
1108 1108
             );
1109
-            $end_date   = EEM_Change_Log::instance()->convert_datetime_for_query(
1109
+            $end_date = EEM_Change_Log::instance()->convert_datetime_for_query(
1110 1110
                 'LOG_time',
1111 1111
                 date('Y-m-d H:i:s', $end_date),
1112 1112
                 'Y-m-d H:i:s'
@@ -1125,23 +1125,23 @@  discard block
 block discarded – undo
1125 1125
             $query_params['order_by'] = array('LOG_time' => 'DESC');
1126 1126
         }
1127 1127
         $offset = ($current_page - 1) * $per_page;
1128
-        if (! isset($this->_req_data['download_results'])) {
1128
+        if ( ! isset($this->_req_data['download_results'])) {
1129 1129
             $query_params['limit'] = array($offset, $per_page);
1130 1130
         }
1131 1131
         // now they've requested to instead just download the file instead of viewing it.
1132 1132
         if (isset($this->_req_data['download_results'])) {
1133 1133
             $wpdb_results = EEM_Change_Log::instance()->get_all_efficiently($query_params);
1134 1134
             header('Content-Disposition: attachment');
1135
-            header("Content-Disposition: attachment; filename=ee_payment_logs_for_" . sanitize_key(site_url()));
1135
+            header("Content-Disposition: attachment; filename=ee_payment_logs_for_".sanitize_key(site_url()));
1136 1136
             echo '<h1> '
1137 1137
                 . sprintf(
1138 1138
                     esc_html__('Payment Logs for %1$s', 'event_espresso'),
1139 1139
                     esc_url_raw(site_url())
1140 1140
                 )
1141 1141
                 . '</h1 >';
1142
-            echo '<h3>' . esc_html__('Query:', 'event_espresso') . '</h3>';
1142
+            echo '<h3>'.esc_html__('Query:', 'event_espresso').'</h3>';
1143 1143
             echo esc_html(var_export($query_params, true));
1144
-            echo '<h3>' . esc_html__('Results:', 'event_espresso') . '</h3>';
1144
+            echo '<h3>'.esc_html__('Results:', 'event_espresso').'</h3>';
1145 1145
             echo esc_html(var_export($wpdb_results, true));
1146 1146
             die;
1147 1147
         }
@@ -1197,7 +1197,7 @@  discard block
 block discarded – undo
1197 1197
             }
1198 1198
         }
1199 1199
         $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1200
-            EE_PAYMENTS_TEMPLATE_PATH . 'payment_log_details.template.php',
1200
+            EE_PAYMENTS_TEMPLATE_PATH.'payment_log_details.template.php',
1201 1201
             array(
1202 1202
                 'payment_log'    => $payment_log,
1203 1203
                 'payment_method' => $payment_method,
Please login to merge, or discard this patch.
admin/extend/registration_form/Extend_Registration_Form_Admin_Page.core.php 1 patch
Indentation   +1432 added lines, -1432 removed lines patch added patch discarded remove patch
@@ -15,1436 +15,1436 @@
 block discarded – undo
15 15
 class Extend_Registration_Form_Admin_Page extends Registration_Form_Admin_Page
16 16
 {
17 17
 
18
-    /**
19
-     * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
20
-     */
21
-    public function __construct($routing = true)
22
-    {
23
-        define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
24
-        define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
25
-        define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
26
-        define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
27
-        define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
28
-        parent::__construct($routing);
29
-    }
30
-
31
-
32
-    /**
33
-     * @return void
34
-     */
35
-    protected function _extend_page_config()
36
-    {
37
-        $this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
38
-        $qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
39
-            ? $this->_req_data['QST_ID'] : 0;
40
-        $qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
41
-            ? $this->_req_data['QSG_ID'] : 0;
42
-
43
-        $new_page_routes = array(
44
-            'question_groups'    => array(
45
-                'func'       => '_question_groups_overview_list_table',
46
-                'capability' => 'ee_read_question_groups',
47
-            ),
48
-            'add_question'       => array(
49
-                'func'       => '_edit_question',
50
-                'capability' => 'ee_edit_questions',
51
-            ),
52
-            'insert_question'    => array(
53
-                'func'       => '_insert_or_update_question',
54
-                'args'       => array('new_question' => true),
55
-                'capability' => 'ee_edit_questions',
56
-                'noheader'   => true,
57
-            ),
58
-            'duplicate_question' => array(
59
-                'func'       => '_duplicate_question',
60
-                'capability' => 'ee_edit_questions',
61
-                'noheader'   => true,
62
-            ),
63
-            'trash_question'     => array(
64
-                'func'       => '_trash_question',
65
-                'capability' => 'ee_delete_question',
66
-                'obj_id'     => $qst_id,
67
-                'noheader'   => true,
68
-            ),
69
-
70
-            'restore_question' => array(
71
-                'func'       => '_trash_or_restore_questions',
72
-                'capability' => 'ee_delete_question',
73
-                'obj_id'     => $qst_id,
74
-                'args'       => array('trash' => false),
75
-                'noheader'   => true,
76
-            ),
77
-
78
-            'delete_question' => array(
79
-                'func'       => '_delete_question',
80
-                'capability' => 'ee_delete_question',
81
-                'obj_id'     => $qst_id,
82
-                'noheader'   => true,
83
-            ),
84
-
85
-            'trash_questions' => array(
86
-                'func'       => '_trash_or_restore_questions',
87
-                'capability' => 'ee_delete_questions',
88
-                'args'       => array('trash' => true),
89
-                'noheader'   => true,
90
-            ),
91
-
92
-            'restore_questions' => array(
93
-                'func'       => '_trash_or_restore_questions',
94
-                'capability' => 'ee_delete_questions',
95
-                'args'       => array('trash' => false),
96
-                'noheader'   => true,
97
-            ),
98
-
99
-            'delete_questions' => array(
100
-                'func'       => '_delete_questions',
101
-                'args'       => array(),
102
-                'capability' => 'ee_delete_questions',
103
-                'noheader'   => true,
104
-            ),
105
-
106
-            'add_question_group' => array(
107
-                'func'       => '_edit_question_group',
108
-                'capability' => 'ee_edit_question_groups',
109
-            ),
110
-
111
-            'edit_question_group' => array(
112
-                'func'       => '_edit_question_group',
113
-                'capability' => 'ee_edit_question_group',
114
-                'obj_id'     => $qsg_id,
115
-                'args'       => array('edit'),
116
-            ),
117
-
118
-            'delete_question_groups' => array(
119
-                'func'       => '_delete_question_groups',
120
-                'capability' => 'ee_delete_question_groups',
121
-                'noheader'   => true,
122
-            ),
123
-
124
-            'delete_question_group' => array(
125
-                'func'       => '_delete_question_groups',
126
-                'capability' => 'ee_delete_question_group',
127
-                'obj_id'     => $qsg_id,
128
-                'noheader'   => true,
129
-            ),
130
-
131
-            'trash_question_group' => array(
132
-                'func'       => '_trash_or_restore_question_groups',
133
-                'args'       => array('trash' => true),
134
-                'capability' => 'ee_delete_question_group',
135
-                'obj_id'     => $qsg_id,
136
-                'noheader'   => true,
137
-            ),
138
-
139
-            'restore_question_group' => array(
140
-                'func'       => '_trash_or_restore_question_groups',
141
-                'args'       => array('trash' => false),
142
-                'capability' => 'ee_delete_question_group',
143
-                'obj_id'     => $qsg_id,
144
-                'noheader'   => true,
145
-            ),
146
-
147
-            'insert_question_group' => array(
148
-                'func'       => '_insert_or_update_question_group',
149
-                'args'       => array('new_question_group' => true),
150
-                'capability' => 'ee_edit_question_groups',
151
-                'noheader'   => true,
152
-            ),
153
-
154
-            'update_question_group' => array(
155
-                'func'       => '_insert_or_update_question_group',
156
-                'args'       => array('new_question_group' => false),
157
-                'capability' => 'ee_edit_question_group',
158
-                'obj_id'     => $qsg_id,
159
-                'noheader'   => true,
160
-            ),
161
-
162
-            'trash_question_groups' => array(
163
-                'func'       => '_trash_or_restore_question_groups',
164
-                'args'       => array('trash' => true),
165
-                'capability' => 'ee_delete_question_groups',
166
-                'noheader'   => array('trash' => false),
167
-            ),
168
-
169
-            'restore_question_groups' => array(
170
-                'func'       => '_trash_or_restore_question_groups',
171
-                'args'       => array('trash' => false),
172
-                'capability' => 'ee_delete_question_groups',
173
-                'noheader'   => true,
174
-            ),
175
-
176
-
177
-            'espresso_update_question_group_order' => array(
178
-                'func'       => 'update_question_group_order',
179
-                'capability' => 'ee_edit_question_groups',
180
-                'noheader'   => true,
181
-            ),
182
-
183
-            'view_reg_form_settings' => array(
184
-                'func'       => '_reg_form_settings',
185
-                'capability' => 'manage_options',
186
-            ),
187
-
188
-            'update_reg_form_settings' => array(
189
-                'func'       => '_update_reg_form_settings',
190
-                'capability' => 'manage_options',
191
-                'noheader'   => true,
192
-            ),
193
-        );
194
-        $this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
195
-
196
-        $new_page_config = array(
197
-
198
-            'question_groups' => array(
199
-                'nav'           => array(
200
-                    'label' => esc_html__('Question Groups', 'event_espresso'),
201
-                    'order' => 20,
202
-                ),
203
-                'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
204
-                'help_tabs'     => array(
205
-                    'registration_form_question_groups_help_tab'                           => array(
206
-                        'title'    => esc_html__('Question Groups', 'event_espresso'),
207
-                        'filename' => 'registration_form_question_groups',
208
-                    ),
209
-                    'registration_form_question_groups_table_column_headings_help_tab'     => array(
210
-                        'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
211
-                        'filename' => 'registration_form_question_groups_table_column_headings',
212
-                    ),
213
-                    'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
214
-                        'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
215
-                        'filename' => 'registration_form_question_groups_views_bulk_actions_search',
216
-                    ),
217
-                ),
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
-                'require_nonce' => false,
239
-            ),
240
-
241
-            'add_question_group' => array(
242
-                'nav'           => array(
243
-                    'label'      => esc_html__('Add Question Group', 'event_espresso'),
244
-                    'order'      => 5,
245
-                    'persistent' => false,
246
-                ),
247
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
248
-                'help_tabs'     => array(
249
-                    'registration_form_add_question_group_help_tab' => array(
250
-                        'title'    => esc_html__('Add Question Group', 'event_espresso'),
251
-                        'filename' => 'registration_form_add_question_group',
252
-                    ),
253
-                ),
254
-                'require_nonce' => false,
255
-            ),
256
-
257
-            'edit_question_group' => array(
258
-                'nav'           => array(
259
-                    'label'      => esc_html__('Edit Question Group', 'event_espresso'),
260
-                    'order'      => 5,
261
-                    'persistent' => false,
262
-                    'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
263
-                        array('question_group_id' => $this->_req_data['question_group_id']),
264
-                        $this->_current_page_view_url
265
-                    ) : $this->_admin_base_url,
266
-                ),
267
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
268
-                'help_tabs'     => array(
269
-                    'registration_form_edit_question_group_help_tab' => array(
270
-                        'title'    => esc_html__('Edit Question Group', 'event_espresso'),
271
-                        'filename' => 'registration_form_edit_question_group',
272
-                    ),
273
-                ),
274
-                'require_nonce' => false,
275
-            ),
276
-
277
-            'view_reg_form_settings' => array(
278
-                'nav'           => array(
279
-                    'label' => esc_html__('Reg Form Settings', 'event_espresso'),
280
-                    'order' => 40,
281
-                ),
282
-                'labels'        => array(
283
-                    'publishbox' => esc_html__('Update Settings', 'event_espresso'),
284
-                ),
285
-                'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
286
-                'help_tabs'     => array(
287
-                    'registration_form_reg_form_settings_help_tab' => array(
288
-                        'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
289
-                        'filename' => 'registration_form_reg_form_settings',
290
-                    ),
291
-                ),
292
-                'require_nonce' => false,
293
-            ),
294
-
295
-        );
296
-        $this->_page_config = array_merge($this->_page_config, $new_page_config);
297
-
298
-        // change the list table we're going to use so it's the NEW list table!
299
-        $this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
300
-
301
-
302
-        // additional labels
303
-        $new_labels = array(
304
-            'add_question'          => esc_html__('Add New Question', 'event_espresso'),
305
-            'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
306
-            'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
307
-            'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
308
-            'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
309
-        );
310
-        $this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
311
-    }
312
-
313
-
314
-    /**
315
-     * @return void
316
-     */
317
-    protected function _ajax_hooks()
318
-    {
319
-        add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
320
-    }
321
-
322
-
323
-    /**
324
-     * @return void
325
-     */
326
-    public function load_scripts_styles_question_groups()
327
-    {
328
-        wp_enqueue_script('espresso_ajax_table_sorting');
329
-    }
330
-
331
-
332
-    /**
333
-     * @return void
334
-     */
335
-    public function load_scripts_styles_add_question_group()
336
-    {
337
-        $this->load_scripts_styles_forms();
338
-        $this->load_sortable_question_script();
339
-    }
340
-
341
-
342
-    /**
343
-     * @return void
344
-     */
345
-    public function load_scripts_styles_edit_question_group()
346
-    {
347
-        $this->load_scripts_styles_forms();
348
-        $this->load_sortable_question_script();
349
-    }
350
-
351
-
352
-    /**
353
-     * registers and enqueues script for questions
354
-     *
355
-     * @return void
356
-     */
357
-    public function load_sortable_question_script()
358
-    {
359
-        wp_register_script(
360
-            'ee-question-sortable',
361
-            REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
362
-            array('jquery-ui-sortable'),
363
-            EVENT_ESPRESSO_VERSION,
364
-            true
365
-        );
366
-        wp_enqueue_script('ee-question-sortable');
367
-    }
368
-
369
-
370
-    /**
371
-     * @return void
372
-     */
373
-    protected function _set_list_table_views_default()
374
-    {
375
-        $this->_views = array(
376
-            'all' => array(
377
-                'slug'        => 'all',
378
-                'label'       => esc_html__('View All Questions', 'event_espresso'),
379
-                'count'       => 0,
380
-                'bulk_action' => array(
381
-                    'trash_questions' => esc_html__('Trash', 'event_espresso'),
382
-                ),
383
-            ),
384
-        );
385
-
386
-        if (
387
-            EE_Registry::instance()->CAP->current_user_can(
388
-                'ee_delete_questions',
389
-                'espresso_registration_form_trash_questions'
390
-            )
391
-        ) {
392
-            $this->_views['trash'] = array(
393
-                'slug'        => 'trash',
394
-                'label'       => esc_html__('Trash', 'event_espresso'),
395
-                'count'       => 0,
396
-                'bulk_action' => array(
397
-                    'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
398
-                    'restore_questions' => esc_html__('Restore', 'event_espresso'),
399
-                ),
400
-            );
401
-        }
402
-    }
403
-
404
-
405
-    /**
406
-     * @return void
407
-     */
408
-    protected function _set_list_table_views_question_groups()
409
-    {
410
-        $this->_views = array(
411
-            'all' => array(
412
-                'slug'        => 'all',
413
-                'label'       => esc_html__('All', 'event_espresso'),
414
-                'count'       => 0,
415
-                'bulk_action' => array(
416
-                    'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
417
-                ),
418
-            ),
419
-        );
420
-
421
-        if (
422
-            EE_Registry::instance()->CAP->current_user_can(
423
-                'ee_delete_question_groups',
424
-                'espresso_registration_form_trash_question_groups'
425
-            )
426
-        ) {
427
-            $this->_views['trash'] = array(
428
-                'slug'        => 'trash',
429
-                'label'       => esc_html__('Trash', 'event_espresso'),
430
-                'count'       => 0,
431
-                'bulk_action' => array(
432
-                    'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
433
-                    'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
434
-                ),
435
-            );
436
-        }
437
-    }
438
-
439
-
440
-    /**
441
-     * @return void
442
-     * @throws EE_Error
443
-     * @throws InvalidArgumentException
444
-     * @throws InvalidDataTypeException
445
-     * @throws InvalidInterfaceException
446
-     */
447
-    protected function _questions_overview_list_table()
448
-    {
449
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
450
-            'add_question',
451
-            'add_question',
452
-            array(),
453
-            'add-new-h2'
454
-        );
455
-        parent::_questions_overview_list_table();
456
-    }
457
-
458
-
459
-    /**
460
-     * @return void
461
-     * @throws DomainException
462
-     * @throws EE_Error
463
-     * @throws InvalidArgumentException
464
-     * @throws InvalidDataTypeException
465
-     * @throws InvalidInterfaceException
466
-     */
467
-    protected function _question_groups_overview_list_table()
468
-    {
469
-        $this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
470
-        $this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
471
-            'add_question_group',
472
-            'add_question_group',
473
-            array(),
474
-            'add-new-h2'
475
-        );
476
-        $this->display_admin_list_table_page_with_sidebar();
477
-    }
478
-
479
-
480
-    /**
481
-     * @return void
482
-     * @throws EE_Error
483
-     * @throws InvalidArgumentException
484
-     * @throws InvalidDataTypeException
485
-     * @throws InvalidInterfaceException
486
-     */
487
-    protected function _delete_question()
488
-    {
489
-        $success = $this->_delete_items($this->_question_model);
490
-        $this->_redirect_after_action(
491
-            $success,
492
-            $this->_question_model->item_name($success),
493
-            'deleted',
494
-            array('action' => 'default', 'status' => 'all')
495
-        );
496
-    }
497
-
498
-
499
-    /**
500
-     * @return void
501
-     * @throws EE_Error
502
-     * @throws InvalidArgumentException
503
-     * @throws InvalidDataTypeException
504
-     * @throws InvalidInterfaceException
505
-     */
506
-    protected function _delete_questions()
507
-    {
508
-        $success = $this->_delete_items($this->_question_model);
509
-        $this->_redirect_after_action(
510
-            $success,
511
-            $this->_question_model->item_name($success),
512
-            'deleted permanently',
513
-            array('action' => 'default', 'status' => 'trash')
514
-        );
515
-    }
516
-
517
-
518
-    /**
519
-     * Performs the deletion of a single or multiple questions or question groups.
520
-     *
521
-     * @param EEM_Soft_Delete_Base $model
522
-     * @return int number of items deleted permanently
523
-     * @throws EE_Error
524
-     * @throws InvalidArgumentException
525
-     * @throws InvalidDataTypeException
526
-     * @throws InvalidInterfaceException
527
-     */
528
-    private function _delete_items(EEM_Soft_Delete_Base $model)
529
-    {
530
-        $success = 0;
531
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
532
-        if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
533
-            // if array has more than one element than success message should be plural
534
-            $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
535
-            // cycle thru bulk action checkboxes
536
-            while (list($ID, $value) = each($this->_req_data['checkbox'])) {
537
-                if (! $this->_delete_item($ID, $model)) {
538
-                    $success = 0;
539
-                }
540
-            }
541
-        } elseif (! empty($this->_req_data['QSG_ID'])) {
542
-            $success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
543
-        } elseif (! empty($this->_req_data['QST_ID'])) {
544
-            $success = $this->_delete_item($this->_req_data['QST_ID'], $model);
545
-        } else {
546
-            EE_Error::add_error(
547
-                sprintf(
548
-                    esc_html__(
549
-                        "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.",
550
-                        "event_espresso"
551
-                    )
552
-                ),
553
-                __FILE__,
554
-                __FUNCTION__,
555
-                __LINE__
556
-            );
557
-        }
558
-        return $success;
559
-    }
560
-
561
-
562
-    /**
563
-     * Deletes the specified question (and its associated question options) or question group
564
-     *
565
-     * @param int                  $id
566
-     * @param EEM_Soft_Delete_Base $model
567
-     * @return boolean
568
-     * @throws EE_Error
569
-     * @throws InvalidArgumentException
570
-     * @throws InvalidDataTypeException
571
-     * @throws InvalidInterfaceException
572
-     */
573
-    protected function _delete_item($id, $model)
574
-    {
575
-        if ($model instanceof EEM_Question) {
576
-            EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
577
-        }
578
-        return $model->delete_permanently_by_ID(absint($id));
579
-    }
580
-
581
-
582
-    /******************************    QUESTION GROUPS    ******************************/
583
-
584
-
585
-    /**
586
-     * @param string $type
587
-     * @return void
588
-     * @throws DomainException
589
-     * @throws EE_Error
590
-     * @throws InvalidArgumentException
591
-     * @throws InvalidDataTypeException
592
-     * @throws InvalidInterfaceException
593
-     */
594
-    protected function _edit_question_group($type = 'add')
595
-    {
596
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
597
-        $ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
598
-            ? absint($this->_req_data['QSG_ID'])
599
-            : false;
600
-
601
-        switch ($this->_req_action) {
602
-            case 'add_question_group':
603
-                $this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
604
-                break;
605
-            case 'edit_question_group':
606
-                $this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
607
-                break;
608
-            default:
609
-                $this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
610
-        }
611
-        // add ID to title if editing
612
-        $this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
613
-        if ($ID) {
614
-            /** @var EE_Question_Group $questionGroup */
615
-            $questionGroup = $this->_question_group_model->get_one_by_ID($ID);
616
-            $additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
617
-            $this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
618
-        } else {
619
-            /** @var EE_Question_Group $questionGroup */
620
-            $questionGroup = EEM_Question_Group::instance()->create_default_object();
621
-            $questionGroup->set_order_to_latest();
622
-            $this->_set_add_edit_form_tags('insert_question_group');
623
-        }
624
-        $this->_template_args['values'] = $this->_yes_no_values;
625
-        $this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
626
-        $this->_template_args['QSG_ID'] = $ID ? $ID : true;
627
-        $this->_template_args['question_group'] = $questionGroup;
628
-
629
-        $redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
630
-        $this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
631
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
632
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
633
-            $this->_template_args,
634
-            true
635
-        );
636
-
637
-        // the details template wrapper
638
-        $this->display_admin_page_with_sidebar();
639
-    }
640
-
641
-
642
-    /**
643
-     * @return void
644
-     * @throws EE_Error
645
-     * @throws InvalidArgumentException
646
-     * @throws InvalidDataTypeException
647
-     * @throws InvalidInterfaceException
648
-     */
649
-    protected function _delete_question_groups()
650
-    {
651
-        $success = $this->_delete_items($this->_question_group_model);
652
-        $this->_redirect_after_action(
653
-            $success,
654
-            $this->_question_group_model->item_name($success),
655
-            'deleted permanently',
656
-            array('action' => 'question_groups', 'status' => 'trash')
657
-        );
658
-    }
659
-
660
-
661
-    /**
662
-     * @param bool $new_question_group
663
-     * @throws EE_Error
664
-     * @throws InvalidArgumentException
665
-     * @throws InvalidDataTypeException
666
-     * @throws InvalidInterfaceException
667
-     */
668
-    protected function _insert_or_update_question_group($new_question_group = true)
669
-    {
670
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
671
-        $set_column_values = $this->_set_column_values_for($this->_question_group_model);
672
-        if ($new_question_group) {
673
-            // make sure identifier is unique
674
-            $identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
675
-            $identifier_exists = ! empty($identifier_value)
676
-                ? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
677
-                : false;
678
-            if ($identifier_exists) {
679
-                $set_column_values['QSG_identifier'] .= uniqid('id', true);
680
-            }
681
-            $QSG_ID = $this->_question_group_model->insert($set_column_values);
682
-            $success = $QSG_ID ? 1 : 0;
683
-            if ($success === 0) {
684
-                EE_Error::add_error(
685
-                    esc_html__('Something went wrong saving the question group.', 'event_espresso'),
686
-                    __FILE__,
687
-                    __FUNCTION__,
688
-                    __LINE__
689
-                );
690
-                $this->_redirect_after_action(
691
-                    false,
692
-                    '',
693
-                    '',
694
-                    array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
695
-                    true
696
-                );
697
-            }
698
-        } else {
699
-            $QSG_ID = absint($this->_req_data['QSG_ID']);
700
-            unset($set_column_values['QSG_ID']);
701
-            $success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
702
-        }
703
-
704
-        $phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
705
-            EEM_Attendee::system_question_phone
706
-        );
707
-        // update the existing related questions
708
-        // BUT FIRST...  delete the phone question from the Question_Group_Question
709
-        // if it is being added to this question group (therefore removed from the existing group)
710
-        if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
711
-            // delete where QST ID = system phone question ID and Question Group ID is NOT this group
712
-            EEM_Question_Group_Question::instance()->delete(
713
-                array(
714
-                    array(
715
-                        'QST_ID' => $phone_question_id,
716
-                        'QSG_ID' => array('!=', $QSG_ID),
717
-                    ),
718
-                )
719
-            );
720
-        }
721
-        /** @type EE_Question_Group $question_group */
722
-        $question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
723
-        $questions = $question_group->questions();
724
-        // make sure system phone question is added to list of questions for this group
725
-        if (! isset($questions[ $phone_question_id ])) {
726
-            $questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
727
-        }
728
-
729
-        foreach ($questions as $question_ID => $question) {
730
-            // first we always check for order.
731
-            if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
732
-                // update question order
733
-                $question_group->update_question_order(
734
-                    $question_ID,
735
-                    $this->_req_data['question_orders'][ $question_ID ]
736
-                );
737
-            }
738
-
739
-            // then we always check if adding or removing.
740
-            if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
741
-                $question_group->add_question($question_ID);
742
-            } else {
743
-                // not found, remove it (but only if not a system question for the personal group
744
-                // with the exception of lname system question - we allow removal of it)
745
-                if (
746
-                    in_array(
747
-                        $question->system_ID(),
748
-                        EEM_Question::instance()->required_system_questions_in_system_question_group(
749
-                            $question_group->system_group()
750
-                        )
751
-                    )
752
-                ) {
753
-                    continue;
754
-                } else {
755
-                    $question_group->remove_question($question_ID);
756
-                }
757
-            }
758
-        }
759
-        // save new related questions
760
-        if (isset($this->_req_data['questions'])) {
761
-            foreach ($this->_req_data['questions'] as $QST_ID) {
762
-                $question_group->add_question($QST_ID);
763
-                if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
764
-                    $question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
765
-                }
766
-            }
767
-        }
768
-
769
-        if ($success !== false) {
770
-            $msg = $new_question_group
771
-                ? sprintf(
772
-                    esc_html__('The %s has been created', 'event_espresso'),
773
-                    $this->_question_group_model->item_name()
774
-                )
775
-                : sprintf(
776
-                    esc_html__(
777
-                        'The %s has been updated',
778
-                        'event_espresso'
779
-                    ),
780
-                    $this->_question_group_model->item_name()
781
-                );
782
-            EE_Error::add_success($msg);
783
-        }
784
-        $this->_redirect_after_action(
785
-            false,
786
-            '',
787
-            '',
788
-            array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
789
-            true
790
-        );
791
-    }
792
-
793
-
794
-    /**
795
-     * duplicates a question and all its question options and redirects to the new question.
796
-     *
797
-     * @return void
798
-     * @throws EE_Error
799
-     * @throws InvalidArgumentException
800
-     * @throws ReflectionException
801
-     * @throws InvalidDataTypeException
802
-     * @throws InvalidInterfaceException
803
-     */
804
-    public function _duplicate_question()
805
-    {
806
-        $question_ID = (int) $this->_req_data['QST_ID'];
807
-        $question = EEM_Question::instance()->get_one_by_ID($question_ID);
808
-        if ($question instanceof EE_Question) {
809
-            $new_question = $question->duplicate();
810
-            if ($new_question instanceof EE_Question) {
811
-                $this->_redirect_after_action(
812
-                    true,
813
-                    esc_html__('Question', 'event_espresso'),
814
-                    esc_html__('Duplicated', 'event_espresso'),
815
-                    array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
816
-                    true
817
-                );
818
-            } else {
819
-                global $wpdb;
820
-                EE_Error::add_error(
821
-                    sprintf(
822
-                        esc_html__(
823
-                            'Could not duplicate question with ID %1$d because: %2$s',
824
-                            'event_espresso'
825
-                        ),
826
-                        $question_ID,
827
-                        $wpdb->last_error
828
-                    ),
829
-                    __FILE__,
830
-                    __FUNCTION__,
831
-                    __LINE__
832
-                );
833
-                $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
834
-            }
835
-        } else {
836
-            EE_Error::add_error(
837
-                sprintf(
838
-                    esc_html__(
839
-                        'Could not duplicate question with ID %d because it didn\'t exist!',
840
-                        'event_espresso'
841
-                    ),
842
-                    $question_ID
843
-                ),
844
-                __FILE__,
845
-                __FUNCTION__,
846
-                __LINE__
847
-            );
848
-            $this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
849
-        }
850
-    }
851
-
852
-
853
-    /**
854
-     * @param bool $trash
855
-     * @throws EE_Error
856
-     */
857
-    protected function _trash_or_restore_question_groups($trash = true)
858
-    {
859
-        $this->_trash_or_restore_items($this->_question_group_model, $trash);
860
-    }
861
-
862
-
863
-    /**
864
-     *_trash_question
865
-     *
866
-     * @return void
867
-     * @throws EE_Error
868
-     */
869
-    protected function _trash_question()
870
-    {
871
-        $success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
872
-        $query_args = array('action' => 'default', 'status' => 'all');
873
-        $this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
874
-    }
875
-
876
-
877
-    /**
878
-     * @param bool $trash
879
-     * @throws EE_Error
880
-     */
881
-    protected function _trash_or_restore_questions($trash = true)
882
-    {
883
-        $this->_trash_or_restore_items($this->_question_model, $trash);
884
-    }
885
-
886
-
887
-    /**
888
-     * Internally used to delete or restore items, using the request data. Meant to be
889
-     * flexible between question or question groups
890
-     *
891
-     * @param EEM_Soft_Delete_Base $model
892
-     * @param boolean              $trash whether to trash or restore
893
-     * @throws EE_Error
894
-     */
895
-    private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
896
-    {
897
-
898
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
899
-
900
-        $success = 1;
901
-        // Checkboxes
902
-        // echo "trash $trash";
903
-        // var_dump($this->_req_data['checkbox']);die;
904
-        if (isset($this->_req_data['checkbox'])) {
905
-            if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
906
-                // if array has more than one element than success message should be plural
907
-                $success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
908
-                // cycle thru bulk action checkboxes
909
-                while (list($ID, $value) = each($this->_req_data['checkbox'])) {
910
-                    if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
911
-                        $success = 0;
912
-                    }
913
-                }
914
-            } else {
915
-                // grab single id and delete
916
-                $ID = absint($this->_req_data['checkbox']);
917
-                if (! $model->delete_or_restore_by_ID($trash, $ID)) {
918
-                    $success = 0;
919
-                }
920
-            }
921
-        } else {
922
-            // delete via trash link
923
-            // grab single id and delete
924
-            $ID = absint($this->_req_data[ $model->primary_key_name() ]);
925
-            if (! $model->delete_or_restore_by_ID($trash, $ID)) {
926
-                $success = 0;
927
-            }
928
-        }
929
-
930
-
931
-        $action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
932
-        // echo "action :$action";
933
-        // $action = 'questions' ? 'default' : $action;
934
-        if ($trash) {
935
-            $action_desc = 'trashed';
936
-            $status = 'trash';
937
-        } else {
938
-            $action_desc = 'restored';
939
-            $status = 'all';
940
-        }
941
-        $this->_redirect_after_action(
942
-            $success,
943
-            $model->item_name($success),
944
-            $action_desc,
945
-            array('action' => $action, 'status' => $status)
946
-        );
947
-    }
948
-
949
-
950
-    /**
951
-     * @param            $per_page
952
-     * @param int        $current_page
953
-     * @param bool|false $count
954
-     * @return EE_Soft_Delete_Base_Class[]|int
955
-     * @throws EE_Error
956
-     * @throws InvalidArgumentException
957
-     * @throws InvalidDataTypeException
958
-     * @throws InvalidInterfaceException
959
-     */
960
-    public function get_trashed_questions($per_page, $current_page = 1, $count = false)
961
-    {
962
-        $query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
963
-
964
-        if ($count) {
965
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
966
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
967
-            $results = $this->_question_model->count_deleted($where);
968
-        } else {
969
-            // note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
970
-            $results = $this->_question_model->get_all_deleted($query_params);
971
-        }
972
-        return $results;
973
-    }
974
-
975
-
976
-    /**
977
-     * @param            $per_page
978
-     * @param int        $current_page
979
-     * @param bool|false $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_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
-            $results = $questionGroupModel->count($where);
993
-        } else {
994
-            $results = $questionGroupModel->get_all($query_params);
995
-        }
996
-        return $results;
997
-    }
998
-
999
-
1000
-    /**
1001
-     * @param      $per_page
1002
-     * @param int  $current_page
1003
-     * @param bool $count
1004
-     * @return EE_Soft_Delete_Base_Class[]|int
1005
-     * @throws EE_Error
1006
-     * @throws InvalidArgumentException
1007
-     * @throws InvalidDataTypeException
1008
-     * @throws InvalidInterfaceException
1009
-     */
1010
-    public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1011
-    {
1012
-        $questionGroupModel = EEM_Question_Group::instance();
1013
-        $query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1014
-        if ($count) {
1015
-            $where = isset($query_params[0]) ? array($query_params[0]) : array();
1016
-            $query_params['limit'] = null;
1017
-            $results = $questionGroupModel->count_deleted($where);
1018
-        } else {
1019
-            $results = $questionGroupModel->get_all_deleted($query_params);
1020
-        }
1021
-        return $results;
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * method for performing updates to question order
1027
-     *
1028
-     * @return void results array
1029
-     * @throws EE_Error
1030
-     * @throws InvalidArgumentException
1031
-     * @throws InvalidDataTypeException
1032
-     * @throws InvalidInterfaceException
1033
-     */
1034
-    public function update_question_group_order()
1035
-    {
1036
-
1037
-        $success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1038
-
1039
-        // grab our row IDs
1040
-        $row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1041
-            ? explode(',', rtrim($this->_req_data['row_ids'], ','))
1042
-            : array();
1043
-
1044
-        $perpage = ! empty($this->_req_data['perpage'])
1045
-            ? (int) $this->_req_data['perpage']
1046
-            : null;
1047
-        $curpage = ! empty($this->_req_data['curpage'])
1048
-            ? (int) $this->_req_data['curpage']
1049
-            : null;
1050
-
1051
-        if (! empty($row_ids)) {
1052
-            // figure out where we start the row_id count at for the current page.
1053
-            $qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1054
-
1055
-            $row_count = count($row_ids);
1056
-            for ($i = 0; $i < $row_count; $i++) {
1057
-                // Update the questions when re-ordering
1058
-                $updated = EEM_Question_Group::instance()->update(
1059
-                    array('QSG_order' => $qsgcount),
1060
-                    array(array('QSG_ID' => $row_ids[ $i ]))
1061
-                );
1062
-                if ($updated === false) {
1063
-                    $success = false;
1064
-                }
1065
-                $qsgcount++;
1066
-            }
1067
-        } else {
1068
-            $success = false;
1069
-        }
1070
-
1071
-        $errors = ! $success
1072
-            ? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1073
-            : false;
1074
-
1075
-        echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1076
-        die();
1077
-    }
1078
-
1079
-
1080
-
1081
-    /***************************************       REGISTRATION SETTINGS       ***************************************/
1082
-
1083
-
1084
-    /**
1085
-     * @throws DomainException
1086
-     * @throws EE_Error
1087
-     * @throws InvalidArgumentException
1088
-     * @throws InvalidDataTypeException
1089
-     * @throws InvalidInterfaceException
1090
-     */
1091
-    protected function _reg_form_settings()
1092
-    {
1093
-        $this->_template_args['values'] = $this->_yes_no_values;
1094
-        add_action(
1095
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1096
-            array($this, 'email_validation_settings_form'),
1097
-            2
1098
-        );
1099
-        add_action(
1100
-            'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1101
-            array($this, 'copy_attendee_info_settings_form'),
1102
-            4
1103
-        );
1104
-        $this->_template_args = (array) apply_filters(
1105
-            'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1106
-            $this->_template_args
1107
-        );
1108
-        $this->_set_add_edit_form_tags('update_reg_form_settings');
1109
-        $this->_set_publish_post_box_vars(null, false, false, null, false);
1110
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
1111
-            REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1112
-            $this->_template_args,
1113
-            true
1114
-        );
1115
-        $this->display_admin_page_with_sidebar();
1116
-    }
1117
-
1118
-
1119
-    /**
1120
-     * @return void
1121
-     * @throws EE_Error
1122
-     * @throws InvalidArgumentException
1123
-     * @throws ReflectionException
1124
-     * @throws InvalidDataTypeException
1125
-     * @throws InvalidInterfaceException
1126
-     */
1127
-    protected function _update_reg_form_settings()
1128
-    {
1129
-        EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1130
-            EE_Registry::instance()->CFG->registration
1131
-        );
1132
-        EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1133
-            EE_Registry::instance()->CFG->registration
1134
-        );
1135
-        EE_Registry::instance()->CFG->registration = apply_filters(
1136
-            'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1137
-            EE_Registry::instance()->CFG->registration
1138
-        );
1139
-        $success = $this->_update_espresso_configuration(
1140
-            esc_html__('Registration Form Options', 'event_espresso'),
1141
-            EE_Registry::instance()->CFG,
1142
-            __FILE__,
1143
-            __FUNCTION__,
1144
-            __LINE__
1145
-        );
1146
-        $this->_redirect_after_action(
1147
-            $success,
1148
-            esc_html__('Registration Form Options', 'event_espresso'),
1149
-            'updated',
1150
-            array('action' => 'view_reg_form_settings')
1151
-        );
1152
-    }
1153
-
1154
-
1155
-    /**
1156
-     * @return void
1157
-     * @throws EE_Error
1158
-     * @throws InvalidArgumentException
1159
-     * @throws InvalidDataTypeException
1160
-     * @throws InvalidInterfaceException
1161
-     */
1162
-    public function copy_attendee_info_settings_form()
1163
-    {
1164
-        echo wp_kses($this->_copy_attendee_info_settings_form()->get_html(), AllowedTags::getWithFormTags());
1165
-    }
1166
-
1167
-    /**
1168
-     * _copy_attendee_info_settings_form
1169
-     *
1170
-     * @access protected
1171
-     * @return EE_Form_Section_Proper
1172
-     * @throws \EE_Error
1173
-     */
1174
-    protected function _copy_attendee_info_settings_form()
1175
-    {
1176
-        return new EE_Form_Section_Proper(
1177
-            array(
1178
-                'name'            => 'copy_attendee_info_settings',
1179
-                'html_id'         => 'copy_attendee_info_settings',
1180
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1181
-                'subsections'     => apply_filters(
1182
-                    'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1183
-                    array(
1184
-                        'copy_attendee_info_hdr'   => new EE_Form_Section_HTML(
1185
-                            EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1186
-                        ),
1187
-                        'copy_attendee_info' => new EE_Yes_No_Input(
1188
-                            array(
1189
-                                'html_label_text' => esc_html__(
1190
-                                    'Allow copy #1 attendee info to extra attendees?',
1191
-                                    'event_espresso'
1192
-                                ),
1193
-                                'html_help_text'  => esc_html__(
1194
-                                    'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1195
-                                    'event_espresso'
1196
-                                ),
1197
-                                'default'         => EE_Registry::instance()->CFG->registration->copyAttendeeInfo(),
1198
-                                'required'        => false,
1199
-                                'display_html_label_text' => false,
1200
-                            )
1201
-                        ),
1202
-                    )
1203
-                ),
1204
-            )
1205
-        );
1206
-    }
1207
-
1208
-    /**
1209
-     * @param EE_Registration_Config $EE_Registration_Config
1210
-     * @return EE_Registration_Config
1211
-     * @throws EE_Error
1212
-     * @throws InvalidArgumentException
1213
-     * @throws ReflectionException
1214
-     * @throws InvalidDataTypeException
1215
-     * @throws InvalidInterfaceException
1216
-     */
1217
-    public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1218
-    {
1219
-        $prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1220
-        try {
1221
-            $copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1222
-            // if not displaying a form, then check for form submission
1223
-            if ($copy_attendee_info_settings_form->was_submitted()) {
1224
-                // capture form data
1225
-                $copy_attendee_info_settings_form->receive_form_submission();
1226
-                // validate form data
1227
-                if ($copy_attendee_info_settings_form->is_valid()) {
1228
-                    // grab validated data from form
1229
-                    $valid_data = $copy_attendee_info_settings_form->valid_data();
1230
-                    if (isset($valid_data['copy_attendee_info'])) {
1231
-                        $EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1232
-                    } else {
1233
-                        EE_Error::add_error(
1234
-                            esc_html__(
1235
-                                'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1236
-                                'event_espresso'
1237
-                            ),
1238
-                            __FILE__,
1239
-                            __FUNCTION__,
1240
-                            __LINE__
1241
-                        );
1242
-                    }
1243
-                } else {
1244
-                    if ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1245
-                        EE_Error::add_error(
1246
-                            $copy_attendee_info_settings_form->submission_error_message(),
1247
-                            __FILE__,
1248
-                            __FUNCTION__,
1249
-                            __LINE__
1250
-                        );
1251
-                    }
1252
-                }
1253
-            }
1254
-        } catch (EE_Error $e) {
1255
-            $e->get_error();
1256
-        }
1257
-        return $EE_Registration_Config;
1258
-    }
1259
-
1260
-
1261
-    /**
1262
-     * @return void
1263
-     * @throws EE_Error
1264
-     * @throws InvalidArgumentException
1265
-     * @throws InvalidDataTypeException
1266
-     * @throws InvalidInterfaceException
1267
-     */
1268
-    public function email_validation_settings_form()
1269
-    {
1270
-        echo wp_kses($this->_email_validation_settings_form()->get_html(), AllowedTags::getWithFormTags());
1271
-    }
1272
-
1273
-
1274
-    /**
1275
-     * _email_validation_settings_form
1276
-     *
1277
-     * @access protected
1278
-     * @return EE_Form_Section_Proper
1279
-     * @throws \EE_Error
1280
-     */
1281
-    protected function _email_validation_settings_form()
1282
-    {
1283
-        return new EE_Form_Section_Proper(
1284
-            array(
1285
-                'name'            => 'email_validation_settings',
1286
-                'html_id'         => 'email_validation_settings',
1287
-                'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1288
-                'subsections'     => apply_filters(
1289
-                    'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1290
-                    array(
1291
-                        'email_validation_hdr'   => new EE_Form_Section_HTML(
1292
-                            EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1293
-                        ),
1294
-                        'email_validation_level' => new EE_Select_Input(
1295
-                            array(
1296
-                                'basic'      => esc_html__('Basic', 'event_espresso'),
1297
-                                'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1298
-                                'i18n'       => esc_html__('International', 'event_espresso'),
1299
-                                'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1300
-                            ),
1301
-                            array(
1302
-                                'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1303
-                                                     . EEH_Template::get_help_tab_link('email_validation_info'),
1304
-                                'html_help_text'  => esc_html__(
1305
-                                    '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.',
1306
-                                    'event_espresso'
1307
-                                ),
1308
-                                'default'         => isset(
1309
-                                    EE_Registry::instance()->CFG->registration->email_validation_level
1310
-                                )
1311
-                                    ? EE_Registry::instance()->CFG->registration->email_validation_level
1312
-                                    : 'wp_default',
1313
-                                'required'        => false,
1314
-                            )
1315
-                        ),
1316
-                    )
1317
-                ),
1318
-            )
1319
-        );
1320
-    }
1321
-
1322
-
1323
-    /**
1324
-     * @param EE_Registration_Config $EE_Registration_Config
1325
-     * @return EE_Registration_Config
1326
-     * @throws EE_Error
1327
-     * @throws InvalidArgumentException
1328
-     * @throws ReflectionException
1329
-     * @throws InvalidDataTypeException
1330
-     * @throws InvalidInterfaceException
1331
-     */
1332
-    public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1333
-    {
1334
-        $prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1335
-        try {
1336
-            $email_validation_settings_form = $this->_email_validation_settings_form();
1337
-            // if not displaying a form, then check for form submission
1338
-            if ($email_validation_settings_form->was_submitted()) {
1339
-                // capture form data
1340
-                $email_validation_settings_form->receive_form_submission();
1341
-                // validate form data
1342
-                if ($email_validation_settings_form->is_valid()) {
1343
-                    // grab validated data from form
1344
-                    $valid_data = $email_validation_settings_form->valid_data();
1345
-                    if (isset($valid_data['email_validation_level'])) {
1346
-                        $email_validation_level = $valid_data['email_validation_level'];
1347
-                        // now if they want to use international email addresses
1348
-                        if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1349
-                            // in case we need to reset their email validation level,
1350
-                            // make sure that the previous value wasn't already set to one of the i18n options.
1351
-                            if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1352
-                                // if so, then reset it back to "basic" since that is the only other option that,
1353
-                                // despite offering poor validation, supports i18n email addresses
1354
-                                $prev_email_validation_level = 'basic';
1355
-                            }
1356
-                            // confirm our i18n email validation will work on the server
1357
-                            if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1358
-                                // or reset email validation level to previous value
1359
-                                $email_validation_level = $prev_email_validation_level;
1360
-                            }
1361
-                        }
1362
-                        $EE_Registration_Config->email_validation_level = $email_validation_level;
1363
-                    } else {
1364
-                        EE_Error::add_error(
1365
-                            esc_html__(
1366
-                                'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1367
-                                'event_espresso'
1368
-                            ),
1369
-                            __FILE__,
1370
-                            __FUNCTION__,
1371
-                            __LINE__
1372
-                        );
1373
-                    }
1374
-                } else {
1375
-                    if ($email_validation_settings_form->submission_error_message() !== '') {
1376
-                        EE_Error::add_error(
1377
-                            $email_validation_settings_form->submission_error_message(),
1378
-                            __FILE__,
1379
-                            __FUNCTION__,
1380
-                            __LINE__
1381
-                        );
1382
-                    }
1383
-                }
1384
-            }
1385
-        } catch (EE_Error $e) {
1386
-            $e->get_error();
1387
-        }
1388
-        return $EE_Registration_Config;
1389
-    }
1390
-
1391
-
1392
-    /**
1393
-     * confirms that the server's PHP version has the PCRE module enabled,
1394
-     * and that the PCRE version works with our i18n email validation
1395
-     *
1396
-     * @param EE_Registration_Config $EE_Registration_Config
1397
-     * @param string                 $email_validation_level
1398
-     * @return bool
1399
-     */
1400
-    private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1401
-    {
1402
-        // first check that PCRE is enabled
1403
-        if (! defined('PREG_BAD_UTF8_ERROR')) {
1404
-            EE_Error::add_error(
1405
-                sprintf(
1406
-                    esc_html__(
1407
-                        '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.',
1408
-                        'event_espresso'
1409
-                    ),
1410
-                    '<br />'
1411
-                ),
1412
-                __FILE__,
1413
-                __FUNCTION__,
1414
-                __LINE__
1415
-            );
1416
-            return false;
1417
-        } else {
1418
-            // PCRE support is enabled, but let's still
1419
-            // perform a test to see if the server will support it.
1420
-            // but first, save the updated validation level to the config,
1421
-            // so that the validation strategy picks it up.
1422
-            // this will get bumped back down if it doesn't work
1423
-            $EE_Registration_Config->email_validation_level = $email_validation_level;
1424
-            try {
1425
-                $email_validator = new EE_Email_Validation_Strategy();
1426
-                $i18n_email_address = apply_filters(
1427
-                    'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1428
-                    'jägerjü[email protected]'
1429
-                );
1430
-                $email_validator->validate($i18n_email_address);
1431
-            } catch (Exception $e) {
1432
-                EE_Error::add_error(
1433
-                    sprintf(
1434
-                        esc_html__(
1435
-                            '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',
1436
-                            'event_espresso'
1437
-                        ),
1438
-                        '<br />',
1439
-                        '<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1440
-                    ),
1441
-                    __FILE__,
1442
-                    __FUNCTION__,
1443
-                    __LINE__
1444
-                );
1445
-                return false;
1446
-            }
1447
-        }
1448
-        return true;
1449
-    }
18
+	/**
19
+	 * @param bool $routing indicate whether we want to just load the object and handle routing or just load the object.
20
+	 */
21
+	public function __construct($routing = true)
22
+	{
23
+		define('REGISTRATION_FORM_CAF_ADMIN', EE_CORE_CAF_ADMIN_EXTEND . 'registration_form/');
24
+		define('REGISTRATION_FORM_CAF_ASSETS_PATH', REGISTRATION_FORM_CAF_ADMIN . 'assets/');
25
+		define('REGISTRATION_FORM_CAF_ASSETS_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/assets/');
26
+		define('REGISTRATION_FORM_CAF_TEMPLATE_PATH', REGISTRATION_FORM_CAF_ADMIN . 'templates/');
27
+		define('REGISTRATION_FORM_CAF_TEMPLATE_URL', EE_CORE_CAF_ADMIN_EXTEND_URL . 'registration_form/templates/');
28
+		parent::__construct($routing);
29
+	}
30
+
31
+
32
+	/**
33
+	 * @return void
34
+	 */
35
+	protected function _extend_page_config()
36
+	{
37
+		$this->_admin_base_path = REGISTRATION_FORM_CAF_ADMIN;
38
+		$qst_id = ! empty($this->_req_data['QST_ID']) && ! is_array($this->_req_data['QST_ID'])
39
+			? $this->_req_data['QST_ID'] : 0;
40
+		$qsg_id = ! empty($this->_req_data['QSG_ID']) && ! is_array($this->_req_data['QSG_ID'])
41
+			? $this->_req_data['QSG_ID'] : 0;
42
+
43
+		$new_page_routes = array(
44
+			'question_groups'    => array(
45
+				'func'       => '_question_groups_overview_list_table',
46
+				'capability' => 'ee_read_question_groups',
47
+			),
48
+			'add_question'       => array(
49
+				'func'       => '_edit_question',
50
+				'capability' => 'ee_edit_questions',
51
+			),
52
+			'insert_question'    => array(
53
+				'func'       => '_insert_or_update_question',
54
+				'args'       => array('new_question' => true),
55
+				'capability' => 'ee_edit_questions',
56
+				'noheader'   => true,
57
+			),
58
+			'duplicate_question' => array(
59
+				'func'       => '_duplicate_question',
60
+				'capability' => 'ee_edit_questions',
61
+				'noheader'   => true,
62
+			),
63
+			'trash_question'     => array(
64
+				'func'       => '_trash_question',
65
+				'capability' => 'ee_delete_question',
66
+				'obj_id'     => $qst_id,
67
+				'noheader'   => true,
68
+			),
69
+
70
+			'restore_question' => array(
71
+				'func'       => '_trash_or_restore_questions',
72
+				'capability' => 'ee_delete_question',
73
+				'obj_id'     => $qst_id,
74
+				'args'       => array('trash' => false),
75
+				'noheader'   => true,
76
+			),
77
+
78
+			'delete_question' => array(
79
+				'func'       => '_delete_question',
80
+				'capability' => 'ee_delete_question',
81
+				'obj_id'     => $qst_id,
82
+				'noheader'   => true,
83
+			),
84
+
85
+			'trash_questions' => array(
86
+				'func'       => '_trash_or_restore_questions',
87
+				'capability' => 'ee_delete_questions',
88
+				'args'       => array('trash' => true),
89
+				'noheader'   => true,
90
+			),
91
+
92
+			'restore_questions' => array(
93
+				'func'       => '_trash_or_restore_questions',
94
+				'capability' => 'ee_delete_questions',
95
+				'args'       => array('trash' => false),
96
+				'noheader'   => true,
97
+			),
98
+
99
+			'delete_questions' => array(
100
+				'func'       => '_delete_questions',
101
+				'args'       => array(),
102
+				'capability' => 'ee_delete_questions',
103
+				'noheader'   => true,
104
+			),
105
+
106
+			'add_question_group' => array(
107
+				'func'       => '_edit_question_group',
108
+				'capability' => 'ee_edit_question_groups',
109
+			),
110
+
111
+			'edit_question_group' => array(
112
+				'func'       => '_edit_question_group',
113
+				'capability' => 'ee_edit_question_group',
114
+				'obj_id'     => $qsg_id,
115
+				'args'       => array('edit'),
116
+			),
117
+
118
+			'delete_question_groups' => array(
119
+				'func'       => '_delete_question_groups',
120
+				'capability' => 'ee_delete_question_groups',
121
+				'noheader'   => true,
122
+			),
123
+
124
+			'delete_question_group' => array(
125
+				'func'       => '_delete_question_groups',
126
+				'capability' => 'ee_delete_question_group',
127
+				'obj_id'     => $qsg_id,
128
+				'noheader'   => true,
129
+			),
130
+
131
+			'trash_question_group' => array(
132
+				'func'       => '_trash_or_restore_question_groups',
133
+				'args'       => array('trash' => true),
134
+				'capability' => 'ee_delete_question_group',
135
+				'obj_id'     => $qsg_id,
136
+				'noheader'   => true,
137
+			),
138
+
139
+			'restore_question_group' => array(
140
+				'func'       => '_trash_or_restore_question_groups',
141
+				'args'       => array('trash' => false),
142
+				'capability' => 'ee_delete_question_group',
143
+				'obj_id'     => $qsg_id,
144
+				'noheader'   => true,
145
+			),
146
+
147
+			'insert_question_group' => array(
148
+				'func'       => '_insert_or_update_question_group',
149
+				'args'       => array('new_question_group' => true),
150
+				'capability' => 'ee_edit_question_groups',
151
+				'noheader'   => true,
152
+			),
153
+
154
+			'update_question_group' => array(
155
+				'func'       => '_insert_or_update_question_group',
156
+				'args'       => array('new_question_group' => false),
157
+				'capability' => 'ee_edit_question_group',
158
+				'obj_id'     => $qsg_id,
159
+				'noheader'   => true,
160
+			),
161
+
162
+			'trash_question_groups' => array(
163
+				'func'       => '_trash_or_restore_question_groups',
164
+				'args'       => array('trash' => true),
165
+				'capability' => 'ee_delete_question_groups',
166
+				'noheader'   => array('trash' => false),
167
+			),
168
+
169
+			'restore_question_groups' => array(
170
+				'func'       => '_trash_or_restore_question_groups',
171
+				'args'       => array('trash' => false),
172
+				'capability' => 'ee_delete_question_groups',
173
+				'noheader'   => true,
174
+			),
175
+
176
+
177
+			'espresso_update_question_group_order' => array(
178
+				'func'       => 'update_question_group_order',
179
+				'capability' => 'ee_edit_question_groups',
180
+				'noheader'   => true,
181
+			),
182
+
183
+			'view_reg_form_settings' => array(
184
+				'func'       => '_reg_form_settings',
185
+				'capability' => 'manage_options',
186
+			),
187
+
188
+			'update_reg_form_settings' => array(
189
+				'func'       => '_update_reg_form_settings',
190
+				'capability' => 'manage_options',
191
+				'noheader'   => true,
192
+			),
193
+		);
194
+		$this->_page_routes = array_merge($this->_page_routes, $new_page_routes);
195
+
196
+		$new_page_config = array(
197
+
198
+			'question_groups' => array(
199
+				'nav'           => array(
200
+					'label' => esc_html__('Question Groups', 'event_espresso'),
201
+					'order' => 20,
202
+				),
203
+				'list_table'    => 'Registration_Form_Question_Groups_Admin_List_Table',
204
+				'help_tabs'     => array(
205
+					'registration_form_question_groups_help_tab'                           => array(
206
+						'title'    => esc_html__('Question Groups', 'event_espresso'),
207
+						'filename' => 'registration_form_question_groups',
208
+					),
209
+					'registration_form_question_groups_table_column_headings_help_tab'     => array(
210
+						'title'    => esc_html__('Question Groups Table Column Headings', 'event_espresso'),
211
+						'filename' => 'registration_form_question_groups_table_column_headings',
212
+					),
213
+					'registration_form_question_groups_views_bulk_actions_search_help_tab' => array(
214
+						'title'    => esc_html__('Question Groups Views & Bulk Actions & Search', 'event_espresso'),
215
+						'filename' => 'registration_form_question_groups_views_bulk_actions_search',
216
+					),
217
+				),
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
+				'require_nonce' => false,
239
+			),
240
+
241
+			'add_question_group' => array(
242
+				'nav'           => array(
243
+					'label'      => esc_html__('Add Question Group', 'event_espresso'),
244
+					'order'      => 5,
245
+					'persistent' => false,
246
+				),
247
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
248
+				'help_tabs'     => array(
249
+					'registration_form_add_question_group_help_tab' => array(
250
+						'title'    => esc_html__('Add Question Group', 'event_espresso'),
251
+						'filename' => 'registration_form_add_question_group',
252
+					),
253
+				),
254
+				'require_nonce' => false,
255
+			),
256
+
257
+			'edit_question_group' => array(
258
+				'nav'           => array(
259
+					'label'      => esc_html__('Edit Question Group', 'event_espresso'),
260
+					'order'      => 5,
261
+					'persistent' => false,
262
+					'url'        => isset($this->_req_data['question_group_id']) ? add_query_arg(
263
+						array('question_group_id' => $this->_req_data['question_group_id']),
264
+						$this->_current_page_view_url
265
+					) : $this->_admin_base_url,
266
+				),
267
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
268
+				'help_tabs'     => array(
269
+					'registration_form_edit_question_group_help_tab' => array(
270
+						'title'    => esc_html__('Edit Question Group', 'event_espresso'),
271
+						'filename' => 'registration_form_edit_question_group',
272
+					),
273
+				),
274
+				'require_nonce' => false,
275
+			),
276
+
277
+			'view_reg_form_settings' => array(
278
+				'nav'           => array(
279
+					'label' => esc_html__('Reg Form Settings', 'event_espresso'),
280
+					'order' => 40,
281
+				),
282
+				'labels'        => array(
283
+					'publishbox' => esc_html__('Update Settings', 'event_espresso'),
284
+				),
285
+				'metaboxes'     => array_merge($this->_default_espresso_metaboxes, array('_publish_post_box')),
286
+				'help_tabs'     => array(
287
+					'registration_form_reg_form_settings_help_tab' => array(
288
+						'title'    => esc_html__('Registration Form Settings', 'event_espresso'),
289
+						'filename' => 'registration_form_reg_form_settings',
290
+					),
291
+				),
292
+				'require_nonce' => false,
293
+			),
294
+
295
+		);
296
+		$this->_page_config = array_merge($this->_page_config, $new_page_config);
297
+
298
+		// change the list table we're going to use so it's the NEW list table!
299
+		$this->_page_config['default']['list_table'] = 'Extend_Registration_Form_Questions_Admin_List_Table';
300
+
301
+
302
+		// additional labels
303
+		$new_labels = array(
304
+			'add_question'          => esc_html__('Add New Question', 'event_espresso'),
305
+			'delete_question'       => esc_html__('Delete Question', 'event_espresso'),
306
+			'add_question_group'    => esc_html__('Add New Question Group', 'event_espresso'),
307
+			'edit_question_group'   => esc_html__('Edit Question Group', 'event_espresso'),
308
+			'delete_question_group' => esc_html__('Delete Question Group', 'event_espresso'),
309
+		);
310
+		$this->_labels['buttons'] = array_merge($this->_labels['buttons'], $new_labels);
311
+	}
312
+
313
+
314
+	/**
315
+	 * @return void
316
+	 */
317
+	protected function _ajax_hooks()
318
+	{
319
+		add_action('wp_ajax_espresso_update_question_group_order', array($this, 'update_question_group_order'));
320
+	}
321
+
322
+
323
+	/**
324
+	 * @return void
325
+	 */
326
+	public function load_scripts_styles_question_groups()
327
+	{
328
+		wp_enqueue_script('espresso_ajax_table_sorting');
329
+	}
330
+
331
+
332
+	/**
333
+	 * @return void
334
+	 */
335
+	public function load_scripts_styles_add_question_group()
336
+	{
337
+		$this->load_scripts_styles_forms();
338
+		$this->load_sortable_question_script();
339
+	}
340
+
341
+
342
+	/**
343
+	 * @return void
344
+	 */
345
+	public function load_scripts_styles_edit_question_group()
346
+	{
347
+		$this->load_scripts_styles_forms();
348
+		$this->load_sortable_question_script();
349
+	}
350
+
351
+
352
+	/**
353
+	 * registers and enqueues script for questions
354
+	 *
355
+	 * @return void
356
+	 */
357
+	public function load_sortable_question_script()
358
+	{
359
+		wp_register_script(
360
+			'ee-question-sortable',
361
+			REGISTRATION_FORM_CAF_ASSETS_URL . 'ee_question_order.js',
362
+			array('jquery-ui-sortable'),
363
+			EVENT_ESPRESSO_VERSION,
364
+			true
365
+		);
366
+		wp_enqueue_script('ee-question-sortable');
367
+	}
368
+
369
+
370
+	/**
371
+	 * @return void
372
+	 */
373
+	protected function _set_list_table_views_default()
374
+	{
375
+		$this->_views = array(
376
+			'all' => array(
377
+				'slug'        => 'all',
378
+				'label'       => esc_html__('View All Questions', 'event_espresso'),
379
+				'count'       => 0,
380
+				'bulk_action' => array(
381
+					'trash_questions' => esc_html__('Trash', 'event_espresso'),
382
+				),
383
+			),
384
+		);
385
+
386
+		if (
387
+			EE_Registry::instance()->CAP->current_user_can(
388
+				'ee_delete_questions',
389
+				'espresso_registration_form_trash_questions'
390
+			)
391
+		) {
392
+			$this->_views['trash'] = array(
393
+				'slug'        => 'trash',
394
+				'label'       => esc_html__('Trash', 'event_espresso'),
395
+				'count'       => 0,
396
+				'bulk_action' => array(
397
+					'delete_questions'  => esc_html__('Delete Permanently', 'event_espresso'),
398
+					'restore_questions' => esc_html__('Restore', 'event_espresso'),
399
+				),
400
+			);
401
+		}
402
+	}
403
+
404
+
405
+	/**
406
+	 * @return void
407
+	 */
408
+	protected function _set_list_table_views_question_groups()
409
+	{
410
+		$this->_views = array(
411
+			'all' => array(
412
+				'slug'        => 'all',
413
+				'label'       => esc_html__('All', 'event_espresso'),
414
+				'count'       => 0,
415
+				'bulk_action' => array(
416
+					'trash_question_groups' => esc_html__('Trash', 'event_espresso'),
417
+				),
418
+			),
419
+		);
420
+
421
+		if (
422
+			EE_Registry::instance()->CAP->current_user_can(
423
+				'ee_delete_question_groups',
424
+				'espresso_registration_form_trash_question_groups'
425
+			)
426
+		) {
427
+			$this->_views['trash'] = array(
428
+				'slug'        => 'trash',
429
+				'label'       => esc_html__('Trash', 'event_espresso'),
430
+				'count'       => 0,
431
+				'bulk_action' => array(
432
+					'delete_question_groups'  => esc_html__('Delete Permanently', 'event_espresso'),
433
+					'restore_question_groups' => esc_html__('Restore', 'event_espresso'),
434
+				),
435
+			);
436
+		}
437
+	}
438
+
439
+
440
+	/**
441
+	 * @return void
442
+	 * @throws EE_Error
443
+	 * @throws InvalidArgumentException
444
+	 * @throws InvalidDataTypeException
445
+	 * @throws InvalidInterfaceException
446
+	 */
447
+	protected function _questions_overview_list_table()
448
+	{
449
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
450
+			'add_question',
451
+			'add_question',
452
+			array(),
453
+			'add-new-h2'
454
+		);
455
+		parent::_questions_overview_list_table();
456
+	}
457
+
458
+
459
+	/**
460
+	 * @return void
461
+	 * @throws DomainException
462
+	 * @throws EE_Error
463
+	 * @throws InvalidArgumentException
464
+	 * @throws InvalidDataTypeException
465
+	 * @throws InvalidInterfaceException
466
+	 */
467
+	protected function _question_groups_overview_list_table()
468
+	{
469
+		$this->_search_btn_label = esc_html__('Question Groups', 'event_espresso');
470
+		$this->_admin_page_title .= ' ' . $this->get_action_link_or_button(
471
+			'add_question_group',
472
+			'add_question_group',
473
+			array(),
474
+			'add-new-h2'
475
+		);
476
+		$this->display_admin_list_table_page_with_sidebar();
477
+	}
478
+
479
+
480
+	/**
481
+	 * @return void
482
+	 * @throws EE_Error
483
+	 * @throws InvalidArgumentException
484
+	 * @throws InvalidDataTypeException
485
+	 * @throws InvalidInterfaceException
486
+	 */
487
+	protected function _delete_question()
488
+	{
489
+		$success = $this->_delete_items($this->_question_model);
490
+		$this->_redirect_after_action(
491
+			$success,
492
+			$this->_question_model->item_name($success),
493
+			'deleted',
494
+			array('action' => 'default', 'status' => 'all')
495
+		);
496
+	}
497
+
498
+
499
+	/**
500
+	 * @return void
501
+	 * @throws EE_Error
502
+	 * @throws InvalidArgumentException
503
+	 * @throws InvalidDataTypeException
504
+	 * @throws InvalidInterfaceException
505
+	 */
506
+	protected function _delete_questions()
507
+	{
508
+		$success = $this->_delete_items($this->_question_model);
509
+		$this->_redirect_after_action(
510
+			$success,
511
+			$this->_question_model->item_name($success),
512
+			'deleted permanently',
513
+			array('action' => 'default', 'status' => 'trash')
514
+		);
515
+	}
516
+
517
+
518
+	/**
519
+	 * Performs the deletion of a single or multiple questions or question groups.
520
+	 *
521
+	 * @param EEM_Soft_Delete_Base $model
522
+	 * @return int number of items deleted permanently
523
+	 * @throws EE_Error
524
+	 * @throws InvalidArgumentException
525
+	 * @throws InvalidDataTypeException
526
+	 * @throws InvalidInterfaceException
527
+	 */
528
+	private function _delete_items(EEM_Soft_Delete_Base $model)
529
+	{
530
+		$success = 0;
531
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
532
+		if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
533
+			// if array has more than one element than success message should be plural
534
+			$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
535
+			// cycle thru bulk action checkboxes
536
+			while (list($ID, $value) = each($this->_req_data['checkbox'])) {
537
+				if (! $this->_delete_item($ID, $model)) {
538
+					$success = 0;
539
+				}
540
+			}
541
+		} elseif (! empty($this->_req_data['QSG_ID'])) {
542
+			$success = $this->_delete_item($this->_req_data['QSG_ID'], $model);
543
+		} elseif (! empty($this->_req_data['QST_ID'])) {
544
+			$success = $this->_delete_item($this->_req_data['QST_ID'], $model);
545
+		} else {
546
+			EE_Error::add_error(
547
+				sprintf(
548
+					esc_html__(
549
+						"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.",
550
+						"event_espresso"
551
+					)
552
+				),
553
+				__FILE__,
554
+				__FUNCTION__,
555
+				__LINE__
556
+			);
557
+		}
558
+		return $success;
559
+	}
560
+
561
+
562
+	/**
563
+	 * Deletes the specified question (and its associated question options) or question group
564
+	 *
565
+	 * @param int                  $id
566
+	 * @param EEM_Soft_Delete_Base $model
567
+	 * @return boolean
568
+	 * @throws EE_Error
569
+	 * @throws InvalidArgumentException
570
+	 * @throws InvalidDataTypeException
571
+	 * @throws InvalidInterfaceException
572
+	 */
573
+	protected function _delete_item($id, $model)
574
+	{
575
+		if ($model instanceof EEM_Question) {
576
+			EEM_Question_Option::instance()->delete_permanently(array(array('QST_ID' => absint($id))));
577
+		}
578
+		return $model->delete_permanently_by_ID(absint($id));
579
+	}
580
+
581
+
582
+	/******************************    QUESTION GROUPS    ******************************/
583
+
584
+
585
+	/**
586
+	 * @param string $type
587
+	 * @return void
588
+	 * @throws DomainException
589
+	 * @throws EE_Error
590
+	 * @throws InvalidArgumentException
591
+	 * @throws InvalidDataTypeException
592
+	 * @throws InvalidInterfaceException
593
+	 */
594
+	protected function _edit_question_group($type = 'add')
595
+	{
596
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
597
+		$ID = isset($this->_req_data['QSG_ID']) && ! empty($this->_req_data['QSG_ID'])
598
+			? absint($this->_req_data['QSG_ID'])
599
+			: false;
600
+
601
+		switch ($this->_req_action) {
602
+			case 'add_question_group':
603
+				$this->_admin_page_title = esc_html__('Add Question Group', 'event_espresso');
604
+				break;
605
+			case 'edit_question_group':
606
+				$this->_admin_page_title = esc_html__('Edit Question Group', 'event_espresso');
607
+				break;
608
+			default:
609
+				$this->_admin_page_title = ucwords(str_replace('_', ' ', $this->_req_action));
610
+		}
611
+		// add ID to title if editing
612
+		$this->_admin_page_title = $ID ? $this->_admin_page_title . ' # ' . $ID : $this->_admin_page_title;
613
+		if ($ID) {
614
+			/** @var EE_Question_Group $questionGroup */
615
+			$questionGroup = $this->_question_group_model->get_one_by_ID($ID);
616
+			$additional_hidden_fields = array('QSG_ID' => array('type' => 'hidden', 'value' => $ID));
617
+			$this->_set_add_edit_form_tags('update_question_group', $additional_hidden_fields);
618
+		} else {
619
+			/** @var EE_Question_Group $questionGroup */
620
+			$questionGroup = EEM_Question_Group::instance()->create_default_object();
621
+			$questionGroup->set_order_to_latest();
622
+			$this->_set_add_edit_form_tags('insert_question_group');
623
+		}
624
+		$this->_template_args['values'] = $this->_yes_no_values;
625
+		$this->_template_args['all_questions'] = $questionGroup->questions_in_and_not_in_group();
626
+		$this->_template_args['QSG_ID'] = $ID ? $ID : true;
627
+		$this->_template_args['question_group'] = $questionGroup;
628
+
629
+		$redirect_URL = add_query_arg(array('action' => 'question_groups'), $this->_admin_base_url);
630
+		$this->_set_publish_post_box_vars('id', $ID, false, $redirect_URL);
631
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
632
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'question_groups_main_meta_box.template.php',
633
+			$this->_template_args,
634
+			true
635
+		);
636
+
637
+		// the details template wrapper
638
+		$this->display_admin_page_with_sidebar();
639
+	}
640
+
641
+
642
+	/**
643
+	 * @return void
644
+	 * @throws EE_Error
645
+	 * @throws InvalidArgumentException
646
+	 * @throws InvalidDataTypeException
647
+	 * @throws InvalidInterfaceException
648
+	 */
649
+	protected function _delete_question_groups()
650
+	{
651
+		$success = $this->_delete_items($this->_question_group_model);
652
+		$this->_redirect_after_action(
653
+			$success,
654
+			$this->_question_group_model->item_name($success),
655
+			'deleted permanently',
656
+			array('action' => 'question_groups', 'status' => 'trash')
657
+		);
658
+	}
659
+
660
+
661
+	/**
662
+	 * @param bool $new_question_group
663
+	 * @throws EE_Error
664
+	 * @throws InvalidArgumentException
665
+	 * @throws InvalidDataTypeException
666
+	 * @throws InvalidInterfaceException
667
+	 */
668
+	protected function _insert_or_update_question_group($new_question_group = true)
669
+	{
670
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
671
+		$set_column_values = $this->_set_column_values_for($this->_question_group_model);
672
+		if ($new_question_group) {
673
+			// make sure identifier is unique
674
+			$identifier_value = isset($set_column_values['QSG_identifier']) ? $set_column_values['QSG_identifier'] : '';
675
+			$identifier_exists = ! empty($identifier_value)
676
+				? $this->_question_group_model->count([['QSG_identifier' => $set_column_values['QSG_identifier']]]) > 0
677
+				: false;
678
+			if ($identifier_exists) {
679
+				$set_column_values['QSG_identifier'] .= uniqid('id', true);
680
+			}
681
+			$QSG_ID = $this->_question_group_model->insert($set_column_values);
682
+			$success = $QSG_ID ? 1 : 0;
683
+			if ($success === 0) {
684
+				EE_Error::add_error(
685
+					esc_html__('Something went wrong saving the question group.', 'event_espresso'),
686
+					__FILE__,
687
+					__FUNCTION__,
688
+					__LINE__
689
+				);
690
+				$this->_redirect_after_action(
691
+					false,
692
+					'',
693
+					'',
694
+					array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
695
+					true
696
+				);
697
+			}
698
+		} else {
699
+			$QSG_ID = absint($this->_req_data['QSG_ID']);
700
+			unset($set_column_values['QSG_ID']);
701
+			$success = $this->_question_group_model->update($set_column_values, array(array('QSG_ID' => $QSG_ID)));
702
+		}
703
+
704
+		$phone_question_id = EEM_Question::instance()->get_Question_ID_from_system_string(
705
+			EEM_Attendee::system_question_phone
706
+		);
707
+		// update the existing related questions
708
+		// BUT FIRST...  delete the phone question from the Question_Group_Question
709
+		// if it is being added to this question group (therefore removed from the existing group)
710
+		if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $phone_question_id ])) {
711
+			// delete where QST ID = system phone question ID and Question Group ID is NOT this group
712
+			EEM_Question_Group_Question::instance()->delete(
713
+				array(
714
+					array(
715
+						'QST_ID' => $phone_question_id,
716
+						'QSG_ID' => array('!=', $QSG_ID),
717
+					),
718
+				)
719
+			);
720
+		}
721
+		/** @type EE_Question_Group $question_group */
722
+		$question_group = $this->_question_group_model->get_one_by_ID($QSG_ID);
723
+		$questions = $question_group->questions();
724
+		// make sure system phone question is added to list of questions for this group
725
+		if (! isset($questions[ $phone_question_id ])) {
726
+			$questions[ $phone_question_id ] = EEM_Question::instance()->get_one_by_ID($phone_question_id);
727
+		}
728
+
729
+		foreach ($questions as $question_ID => $question) {
730
+			// first we always check for order.
731
+			if (! empty($this->_req_data['question_orders'][ $question_ID ])) {
732
+				// update question order
733
+				$question_group->update_question_order(
734
+					$question_ID,
735
+					$this->_req_data['question_orders'][ $question_ID ]
736
+				);
737
+			}
738
+
739
+			// then we always check if adding or removing.
740
+			if (isset($this->_req_data['questions'], $this->_req_data['questions'][ $question_ID ])) {
741
+				$question_group->add_question($question_ID);
742
+			} else {
743
+				// not found, remove it (but only if not a system question for the personal group
744
+				// with the exception of lname system question - we allow removal of it)
745
+				if (
746
+					in_array(
747
+						$question->system_ID(),
748
+						EEM_Question::instance()->required_system_questions_in_system_question_group(
749
+							$question_group->system_group()
750
+						)
751
+					)
752
+				) {
753
+					continue;
754
+				} else {
755
+					$question_group->remove_question($question_ID);
756
+				}
757
+			}
758
+		}
759
+		// save new related questions
760
+		if (isset($this->_req_data['questions'])) {
761
+			foreach ($this->_req_data['questions'] as $QST_ID) {
762
+				$question_group->add_question($QST_ID);
763
+				if (isset($this->_req_data['question_orders'][ $QST_ID ])) {
764
+					$question_group->update_question_order($QST_ID, $this->_req_data['question_orders'][ $QST_ID ]);
765
+				}
766
+			}
767
+		}
768
+
769
+		if ($success !== false) {
770
+			$msg = $new_question_group
771
+				? sprintf(
772
+					esc_html__('The %s has been created', 'event_espresso'),
773
+					$this->_question_group_model->item_name()
774
+				)
775
+				: sprintf(
776
+					esc_html__(
777
+						'The %s has been updated',
778
+						'event_espresso'
779
+					),
780
+					$this->_question_group_model->item_name()
781
+				);
782
+			EE_Error::add_success($msg);
783
+		}
784
+		$this->_redirect_after_action(
785
+			false,
786
+			'',
787
+			'',
788
+			array('action' => 'edit_question_group', 'QSG_ID' => $QSG_ID),
789
+			true
790
+		);
791
+	}
792
+
793
+
794
+	/**
795
+	 * duplicates a question and all its question options and redirects to the new question.
796
+	 *
797
+	 * @return void
798
+	 * @throws EE_Error
799
+	 * @throws InvalidArgumentException
800
+	 * @throws ReflectionException
801
+	 * @throws InvalidDataTypeException
802
+	 * @throws InvalidInterfaceException
803
+	 */
804
+	public function _duplicate_question()
805
+	{
806
+		$question_ID = (int) $this->_req_data['QST_ID'];
807
+		$question = EEM_Question::instance()->get_one_by_ID($question_ID);
808
+		if ($question instanceof EE_Question) {
809
+			$new_question = $question->duplicate();
810
+			if ($new_question instanceof EE_Question) {
811
+				$this->_redirect_after_action(
812
+					true,
813
+					esc_html__('Question', 'event_espresso'),
814
+					esc_html__('Duplicated', 'event_espresso'),
815
+					array('action' => 'edit_question', 'QST_ID' => $new_question->ID()),
816
+					true
817
+				);
818
+			} else {
819
+				global $wpdb;
820
+				EE_Error::add_error(
821
+					sprintf(
822
+						esc_html__(
823
+							'Could not duplicate question with ID %1$d because: %2$s',
824
+							'event_espresso'
825
+						),
826
+						$question_ID,
827
+						$wpdb->last_error
828
+					),
829
+					__FILE__,
830
+					__FUNCTION__,
831
+					__LINE__
832
+				);
833
+				$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
834
+			}
835
+		} else {
836
+			EE_Error::add_error(
837
+				sprintf(
838
+					esc_html__(
839
+						'Could not duplicate question with ID %d because it didn\'t exist!',
840
+						'event_espresso'
841
+					),
842
+					$question_ID
843
+				),
844
+				__FILE__,
845
+				__FUNCTION__,
846
+				__LINE__
847
+			);
848
+			$this->_redirect_after_action(false, '', '', array('action' => 'default'), false);
849
+		}
850
+	}
851
+
852
+
853
+	/**
854
+	 * @param bool $trash
855
+	 * @throws EE_Error
856
+	 */
857
+	protected function _trash_or_restore_question_groups($trash = true)
858
+	{
859
+		$this->_trash_or_restore_items($this->_question_group_model, $trash);
860
+	}
861
+
862
+
863
+	/**
864
+	 *_trash_question
865
+	 *
866
+	 * @return void
867
+	 * @throws EE_Error
868
+	 */
869
+	protected function _trash_question()
870
+	{
871
+		$success = $this->_question_model->delete_by_ID((int) $this->_req_data['QST_ID']);
872
+		$query_args = array('action' => 'default', 'status' => 'all');
873
+		$this->_redirect_after_action($success, $this->_question_model->item_name($success), 'trashed', $query_args);
874
+	}
875
+
876
+
877
+	/**
878
+	 * @param bool $trash
879
+	 * @throws EE_Error
880
+	 */
881
+	protected function _trash_or_restore_questions($trash = true)
882
+	{
883
+		$this->_trash_or_restore_items($this->_question_model, $trash);
884
+	}
885
+
886
+
887
+	/**
888
+	 * Internally used to delete or restore items, using the request data. Meant to be
889
+	 * flexible between question or question groups
890
+	 *
891
+	 * @param EEM_Soft_Delete_Base $model
892
+	 * @param boolean              $trash whether to trash or restore
893
+	 * @throws EE_Error
894
+	 */
895
+	private function _trash_or_restore_items(EEM_Soft_Delete_Base $model, $trash = true)
896
+	{
897
+
898
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
899
+
900
+		$success = 1;
901
+		// Checkboxes
902
+		// echo "trash $trash";
903
+		// var_dump($this->_req_data['checkbox']);die;
904
+		if (isset($this->_req_data['checkbox'])) {
905
+			if (! empty($this->_req_data['checkbox']) && is_array($this->_req_data['checkbox'])) {
906
+				// if array has more than one element than success message should be plural
907
+				$success = count($this->_req_data['checkbox']) > 1 ? 2 : 1;
908
+				// cycle thru bulk action checkboxes
909
+				while (list($ID, $value) = each($this->_req_data['checkbox'])) {
910
+					if (! $model->delete_or_restore_by_ID($trash, absint($ID))) {
911
+						$success = 0;
912
+					}
913
+				}
914
+			} else {
915
+				// grab single id and delete
916
+				$ID = absint($this->_req_data['checkbox']);
917
+				if (! $model->delete_or_restore_by_ID($trash, $ID)) {
918
+					$success = 0;
919
+				}
920
+			}
921
+		} else {
922
+			// delete via trash link
923
+			// grab single id and delete
924
+			$ID = absint($this->_req_data[ $model->primary_key_name() ]);
925
+			if (! $model->delete_or_restore_by_ID($trash, $ID)) {
926
+				$success = 0;
927
+			}
928
+		}
929
+
930
+
931
+		$action = $model instanceof EEM_Question ? 'default' : 'question_groups';// strtolower( $model->item_name(2) );
932
+		// echo "action :$action";
933
+		// $action = 'questions' ? 'default' : $action;
934
+		if ($trash) {
935
+			$action_desc = 'trashed';
936
+			$status = 'trash';
937
+		} else {
938
+			$action_desc = 'restored';
939
+			$status = 'all';
940
+		}
941
+		$this->_redirect_after_action(
942
+			$success,
943
+			$model->item_name($success),
944
+			$action_desc,
945
+			array('action' => $action, 'status' => $status)
946
+		);
947
+	}
948
+
949
+
950
+	/**
951
+	 * @param            $per_page
952
+	 * @param int        $current_page
953
+	 * @param bool|false $count
954
+	 * @return EE_Soft_Delete_Base_Class[]|int
955
+	 * @throws EE_Error
956
+	 * @throws InvalidArgumentException
957
+	 * @throws InvalidDataTypeException
958
+	 * @throws InvalidInterfaceException
959
+	 */
960
+	public function get_trashed_questions($per_page, $current_page = 1, $count = false)
961
+	{
962
+		$query_params = $this->get_query_params(EEM_Question::instance(), $per_page, $current_page);
963
+
964
+		if ($count) {
965
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
966
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
967
+			$results = $this->_question_model->count_deleted($where);
968
+		} else {
969
+			// note: this a subclass of EEM_Soft_Delete_Base, so this is actually only getting non-trashed items
970
+			$results = $this->_question_model->get_all_deleted($query_params);
971
+		}
972
+		return $results;
973
+	}
974
+
975
+
976
+	/**
977
+	 * @param            $per_page
978
+	 * @param int        $current_page
979
+	 * @param bool|false $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_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
+			$results = $questionGroupModel->count($where);
993
+		} else {
994
+			$results = $questionGroupModel->get_all($query_params);
995
+		}
996
+		return $results;
997
+	}
998
+
999
+
1000
+	/**
1001
+	 * @param      $per_page
1002
+	 * @param int  $current_page
1003
+	 * @param bool $count
1004
+	 * @return EE_Soft_Delete_Base_Class[]|int
1005
+	 * @throws EE_Error
1006
+	 * @throws InvalidArgumentException
1007
+	 * @throws InvalidDataTypeException
1008
+	 * @throws InvalidInterfaceException
1009
+	 */
1010
+	public function get_trashed_question_groups($per_page, $current_page = 1, $count = false)
1011
+	{
1012
+		$questionGroupModel = EEM_Question_Group::instance();
1013
+		$query_params = $this->get_query_params($questionGroupModel, $per_page, $current_page);
1014
+		if ($count) {
1015
+			$where = isset($query_params[0]) ? array($query_params[0]) : array();
1016
+			$query_params['limit'] = null;
1017
+			$results = $questionGroupModel->count_deleted($where);
1018
+		} else {
1019
+			$results = $questionGroupModel->get_all_deleted($query_params);
1020
+		}
1021
+		return $results;
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * method for performing updates to question order
1027
+	 *
1028
+	 * @return void results array
1029
+	 * @throws EE_Error
1030
+	 * @throws InvalidArgumentException
1031
+	 * @throws InvalidDataTypeException
1032
+	 * @throws InvalidInterfaceException
1033
+	 */
1034
+	public function update_question_group_order()
1035
+	{
1036
+
1037
+		$success = esc_html__('Question group order was updated successfully.', 'event_espresso');
1038
+
1039
+		// grab our row IDs
1040
+		$row_ids = isset($this->_req_data['row_ids']) && ! empty($this->_req_data['row_ids'])
1041
+			? explode(',', rtrim($this->_req_data['row_ids'], ','))
1042
+			: array();
1043
+
1044
+		$perpage = ! empty($this->_req_data['perpage'])
1045
+			? (int) $this->_req_data['perpage']
1046
+			: null;
1047
+		$curpage = ! empty($this->_req_data['curpage'])
1048
+			? (int) $this->_req_data['curpage']
1049
+			: null;
1050
+
1051
+		if (! empty($row_ids)) {
1052
+			// figure out where we start the row_id count at for the current page.
1053
+			$qsgcount = empty($curpage) ? 0 : ($curpage - 1) * $perpage;
1054
+
1055
+			$row_count = count($row_ids);
1056
+			for ($i = 0; $i < $row_count; $i++) {
1057
+				// Update the questions when re-ordering
1058
+				$updated = EEM_Question_Group::instance()->update(
1059
+					array('QSG_order' => $qsgcount),
1060
+					array(array('QSG_ID' => $row_ids[ $i ]))
1061
+				);
1062
+				if ($updated === false) {
1063
+					$success = false;
1064
+				}
1065
+				$qsgcount++;
1066
+			}
1067
+		} else {
1068
+			$success = false;
1069
+		}
1070
+
1071
+		$errors = ! $success
1072
+			? esc_html__('An error occurred. The question group order was not updated.', 'event_espresso')
1073
+			: false;
1074
+
1075
+		echo wp_json_encode(array('return_data' => false, 'success' => $success, 'errors' => $errors));
1076
+		die();
1077
+	}
1078
+
1079
+
1080
+
1081
+	/***************************************       REGISTRATION SETTINGS       ***************************************/
1082
+
1083
+
1084
+	/**
1085
+	 * @throws DomainException
1086
+	 * @throws EE_Error
1087
+	 * @throws InvalidArgumentException
1088
+	 * @throws InvalidDataTypeException
1089
+	 * @throws InvalidInterfaceException
1090
+	 */
1091
+	protected function _reg_form_settings()
1092
+	{
1093
+		$this->_template_args['values'] = $this->_yes_no_values;
1094
+		add_action(
1095
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1096
+			array($this, 'email_validation_settings_form'),
1097
+			2
1098
+		);
1099
+		add_action(
1100
+			'AHEE__Extend_Registration_Form_Admin_Page___reg_form_settings_template',
1101
+			array($this, 'copy_attendee_info_settings_form'),
1102
+			4
1103
+		);
1104
+		$this->_template_args = (array) apply_filters(
1105
+			'FHEE__Extend_Registration_Form_Admin_Page___reg_form_settings___template_args',
1106
+			$this->_template_args
1107
+		);
1108
+		$this->_set_add_edit_form_tags('update_reg_form_settings');
1109
+		$this->_set_publish_post_box_vars(null, false, false, null, false);
1110
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
1111
+			REGISTRATION_FORM_CAF_TEMPLATE_PATH . 'reg_form_settings.template.php',
1112
+			$this->_template_args,
1113
+			true
1114
+		);
1115
+		$this->display_admin_page_with_sidebar();
1116
+	}
1117
+
1118
+
1119
+	/**
1120
+	 * @return void
1121
+	 * @throws EE_Error
1122
+	 * @throws InvalidArgumentException
1123
+	 * @throws ReflectionException
1124
+	 * @throws InvalidDataTypeException
1125
+	 * @throws InvalidInterfaceException
1126
+	 */
1127
+	protected function _update_reg_form_settings()
1128
+	{
1129
+		EE_Registry::instance()->CFG->registration = $this->update_email_validation_settings_form(
1130
+			EE_Registry::instance()->CFG->registration
1131
+		);
1132
+		EE_Registry::instance()->CFG->registration = $this->update_copy_attendee_info_settings_form(
1133
+			EE_Registry::instance()->CFG->registration
1134
+		);
1135
+		EE_Registry::instance()->CFG->registration = apply_filters(
1136
+			'FHEE__Extend_Registration_Form_Admin_Page___update_reg_form_settings__CFG_registration',
1137
+			EE_Registry::instance()->CFG->registration
1138
+		);
1139
+		$success = $this->_update_espresso_configuration(
1140
+			esc_html__('Registration Form Options', 'event_espresso'),
1141
+			EE_Registry::instance()->CFG,
1142
+			__FILE__,
1143
+			__FUNCTION__,
1144
+			__LINE__
1145
+		);
1146
+		$this->_redirect_after_action(
1147
+			$success,
1148
+			esc_html__('Registration Form Options', 'event_espresso'),
1149
+			'updated',
1150
+			array('action' => 'view_reg_form_settings')
1151
+		);
1152
+	}
1153
+
1154
+
1155
+	/**
1156
+	 * @return void
1157
+	 * @throws EE_Error
1158
+	 * @throws InvalidArgumentException
1159
+	 * @throws InvalidDataTypeException
1160
+	 * @throws InvalidInterfaceException
1161
+	 */
1162
+	public function copy_attendee_info_settings_form()
1163
+	{
1164
+		echo wp_kses($this->_copy_attendee_info_settings_form()->get_html(), AllowedTags::getWithFormTags());
1165
+	}
1166
+
1167
+	/**
1168
+	 * _copy_attendee_info_settings_form
1169
+	 *
1170
+	 * @access protected
1171
+	 * @return EE_Form_Section_Proper
1172
+	 * @throws \EE_Error
1173
+	 */
1174
+	protected function _copy_attendee_info_settings_form()
1175
+	{
1176
+		return new EE_Form_Section_Proper(
1177
+			array(
1178
+				'name'            => 'copy_attendee_info_settings',
1179
+				'html_id'         => 'copy_attendee_info_settings',
1180
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1181
+				'subsections'     => apply_filters(
1182
+					'FHEE__Extend_Registration_Form_Admin_Page___copy_attendee_info_settings_form__form_subsections',
1183
+					array(
1184
+						'copy_attendee_info_hdr'   => new EE_Form_Section_HTML(
1185
+							EEH_HTML::h2(esc_html__('Copy Attendee Info Settings', 'event_espresso'))
1186
+						),
1187
+						'copy_attendee_info' => new EE_Yes_No_Input(
1188
+							array(
1189
+								'html_label_text' => esc_html__(
1190
+									'Allow copy #1 attendee info to extra attendees?',
1191
+									'event_espresso'
1192
+								),
1193
+								'html_help_text'  => esc_html__(
1194
+									'Set to yes if you want to enable the copy of #1 attendee info to extra attendees at Registration Form.',
1195
+									'event_espresso'
1196
+								),
1197
+								'default'         => EE_Registry::instance()->CFG->registration->copyAttendeeInfo(),
1198
+								'required'        => false,
1199
+								'display_html_label_text' => false,
1200
+							)
1201
+						),
1202
+					)
1203
+				),
1204
+			)
1205
+		);
1206
+	}
1207
+
1208
+	/**
1209
+	 * @param EE_Registration_Config $EE_Registration_Config
1210
+	 * @return EE_Registration_Config
1211
+	 * @throws EE_Error
1212
+	 * @throws InvalidArgumentException
1213
+	 * @throws ReflectionException
1214
+	 * @throws InvalidDataTypeException
1215
+	 * @throws InvalidInterfaceException
1216
+	 */
1217
+	public function update_copy_attendee_info_settings_form(EE_Registration_Config $EE_Registration_Config)
1218
+	{
1219
+		$prev_copy_attendee_info = $EE_Registration_Config->copyAttendeeInfo();
1220
+		try {
1221
+			$copy_attendee_info_settings_form = $this->_copy_attendee_info_settings_form();
1222
+			// if not displaying a form, then check for form submission
1223
+			if ($copy_attendee_info_settings_form->was_submitted()) {
1224
+				// capture form data
1225
+				$copy_attendee_info_settings_form->receive_form_submission();
1226
+				// validate form data
1227
+				if ($copy_attendee_info_settings_form->is_valid()) {
1228
+					// grab validated data from form
1229
+					$valid_data = $copy_attendee_info_settings_form->valid_data();
1230
+					if (isset($valid_data['copy_attendee_info'])) {
1231
+						$EE_Registration_Config->setCopyAttendeeInfo($valid_data['copy_attendee_info']);
1232
+					} else {
1233
+						EE_Error::add_error(
1234
+							esc_html__(
1235
+								'Invalid or missing Copy Attendee Info settings. Please refresh the form and try again.',
1236
+								'event_espresso'
1237
+							),
1238
+							__FILE__,
1239
+							__FUNCTION__,
1240
+							__LINE__
1241
+						);
1242
+					}
1243
+				} else {
1244
+					if ($copy_attendee_info_settings_form->submission_error_message() !== '') {
1245
+						EE_Error::add_error(
1246
+							$copy_attendee_info_settings_form->submission_error_message(),
1247
+							__FILE__,
1248
+							__FUNCTION__,
1249
+							__LINE__
1250
+						);
1251
+					}
1252
+				}
1253
+			}
1254
+		} catch (EE_Error $e) {
1255
+			$e->get_error();
1256
+		}
1257
+		return $EE_Registration_Config;
1258
+	}
1259
+
1260
+
1261
+	/**
1262
+	 * @return void
1263
+	 * @throws EE_Error
1264
+	 * @throws InvalidArgumentException
1265
+	 * @throws InvalidDataTypeException
1266
+	 * @throws InvalidInterfaceException
1267
+	 */
1268
+	public function email_validation_settings_form()
1269
+	{
1270
+		echo wp_kses($this->_email_validation_settings_form()->get_html(), AllowedTags::getWithFormTags());
1271
+	}
1272
+
1273
+
1274
+	/**
1275
+	 * _email_validation_settings_form
1276
+	 *
1277
+	 * @access protected
1278
+	 * @return EE_Form_Section_Proper
1279
+	 * @throws \EE_Error
1280
+	 */
1281
+	protected function _email_validation_settings_form()
1282
+	{
1283
+		return new EE_Form_Section_Proper(
1284
+			array(
1285
+				'name'            => 'email_validation_settings',
1286
+				'html_id'         => 'email_validation_settings',
1287
+				'layout_strategy' => new EE_Admin_Two_Column_Layout(),
1288
+				'subsections'     => apply_filters(
1289
+					'FHEE__Extend_Registration_Form_Admin_Page___email_validation_settings_form__form_subsections',
1290
+					array(
1291
+						'email_validation_hdr'   => new EE_Form_Section_HTML(
1292
+							EEH_HTML::h2(esc_html__('Email Validation Settings', 'event_espresso'))
1293
+						),
1294
+						'email_validation_level' => new EE_Select_Input(
1295
+							array(
1296
+								'basic'      => esc_html__('Basic', 'event_espresso'),
1297
+								'wp_default' => esc_html__('WordPress Default', 'event_espresso'),
1298
+								'i18n'       => esc_html__('International', 'event_espresso'),
1299
+								'i18n_dns'   => esc_html__('International + DNS Check', 'event_espresso'),
1300
+							),
1301
+							array(
1302
+								'html_label_text' => esc_html__('Email Validation Level', 'event_espresso')
1303
+													 . EEH_Template::get_help_tab_link('email_validation_info'),
1304
+								'html_help_text'  => esc_html__(
1305
+									'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.',
1306
+									'event_espresso'
1307
+								),
1308
+								'default'         => isset(
1309
+									EE_Registry::instance()->CFG->registration->email_validation_level
1310
+								)
1311
+									? EE_Registry::instance()->CFG->registration->email_validation_level
1312
+									: 'wp_default',
1313
+								'required'        => false,
1314
+							)
1315
+						),
1316
+					)
1317
+				),
1318
+			)
1319
+		);
1320
+	}
1321
+
1322
+
1323
+	/**
1324
+	 * @param EE_Registration_Config $EE_Registration_Config
1325
+	 * @return EE_Registration_Config
1326
+	 * @throws EE_Error
1327
+	 * @throws InvalidArgumentException
1328
+	 * @throws ReflectionException
1329
+	 * @throws InvalidDataTypeException
1330
+	 * @throws InvalidInterfaceException
1331
+	 */
1332
+	public function update_email_validation_settings_form(EE_Registration_Config $EE_Registration_Config)
1333
+	{
1334
+		$prev_email_validation_level = $EE_Registration_Config->email_validation_level;
1335
+		try {
1336
+			$email_validation_settings_form = $this->_email_validation_settings_form();
1337
+			// if not displaying a form, then check for form submission
1338
+			if ($email_validation_settings_form->was_submitted()) {
1339
+				// capture form data
1340
+				$email_validation_settings_form->receive_form_submission();
1341
+				// validate form data
1342
+				if ($email_validation_settings_form->is_valid()) {
1343
+					// grab validated data from form
1344
+					$valid_data = $email_validation_settings_form->valid_data();
1345
+					if (isset($valid_data['email_validation_level'])) {
1346
+						$email_validation_level = $valid_data['email_validation_level'];
1347
+						// now if they want to use international email addresses
1348
+						if ($email_validation_level === 'i18n' || $email_validation_level === 'i18n_dns') {
1349
+							// in case we need to reset their email validation level,
1350
+							// make sure that the previous value wasn't already set to one of the i18n options.
1351
+							if ($prev_email_validation_level === 'i18n' || $prev_email_validation_level === 'i18n_dns') {
1352
+								// if so, then reset it back to "basic" since that is the only other option that,
1353
+								// despite offering poor validation, supports i18n email addresses
1354
+								$prev_email_validation_level = 'basic';
1355
+							}
1356
+							// confirm our i18n email validation will work on the server
1357
+							if (! $this->_verify_pcre_support($EE_Registration_Config, $email_validation_level)) {
1358
+								// or reset email validation level to previous value
1359
+								$email_validation_level = $prev_email_validation_level;
1360
+							}
1361
+						}
1362
+						$EE_Registration_Config->email_validation_level = $email_validation_level;
1363
+					} else {
1364
+						EE_Error::add_error(
1365
+							esc_html__(
1366
+								'Invalid or missing Email Validation settings. Please refresh the form and try again.',
1367
+								'event_espresso'
1368
+							),
1369
+							__FILE__,
1370
+							__FUNCTION__,
1371
+							__LINE__
1372
+						);
1373
+					}
1374
+				} else {
1375
+					if ($email_validation_settings_form->submission_error_message() !== '') {
1376
+						EE_Error::add_error(
1377
+							$email_validation_settings_form->submission_error_message(),
1378
+							__FILE__,
1379
+							__FUNCTION__,
1380
+							__LINE__
1381
+						);
1382
+					}
1383
+				}
1384
+			}
1385
+		} catch (EE_Error $e) {
1386
+			$e->get_error();
1387
+		}
1388
+		return $EE_Registration_Config;
1389
+	}
1390
+
1391
+
1392
+	/**
1393
+	 * confirms that the server's PHP version has the PCRE module enabled,
1394
+	 * and that the PCRE version works with our i18n email validation
1395
+	 *
1396
+	 * @param EE_Registration_Config $EE_Registration_Config
1397
+	 * @param string                 $email_validation_level
1398
+	 * @return bool
1399
+	 */
1400
+	private function _verify_pcre_support(EE_Registration_Config $EE_Registration_Config, $email_validation_level)
1401
+	{
1402
+		// first check that PCRE is enabled
1403
+		if (! defined('PREG_BAD_UTF8_ERROR')) {
1404
+			EE_Error::add_error(
1405
+				sprintf(
1406
+					esc_html__(
1407
+						'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.',
1408
+						'event_espresso'
1409
+					),
1410
+					'<br />'
1411
+				),
1412
+				__FILE__,
1413
+				__FUNCTION__,
1414
+				__LINE__
1415
+			);
1416
+			return false;
1417
+		} else {
1418
+			// PCRE support is enabled, but let's still
1419
+			// perform a test to see if the server will support it.
1420
+			// but first, save the updated validation level to the config,
1421
+			// so that the validation strategy picks it up.
1422
+			// this will get bumped back down if it doesn't work
1423
+			$EE_Registration_Config->email_validation_level = $email_validation_level;
1424
+			try {
1425
+				$email_validator = new EE_Email_Validation_Strategy();
1426
+				$i18n_email_address = apply_filters(
1427
+					'FHEE__Extend_Registration_Form_Admin_Page__update_email_validation_settings_form__i18n_email_address',
1428
+					'jägerjü[email protected]'
1429
+				);
1430
+				$email_validator->validate($i18n_email_address);
1431
+			} catch (Exception $e) {
1432
+				EE_Error::add_error(
1433
+					sprintf(
1434
+						esc_html__(
1435
+							'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',
1436
+							'event_espresso'
1437
+						),
1438
+						'<br />',
1439
+						'<a href="http://php.net/manual/en/pcre.installation.php" target="_blank" rel="noopener noreferrer">http://php.net/manual/en/pcre.installation.php</a>'
1440
+					),
1441
+					__FILE__,
1442
+					__FUNCTION__,
1443
+					__LINE__
1444
+				);
1445
+				return false;
1446
+			}
1447
+		}
1448
+		return true;
1449
+	}
1450 1450
 }
Please login to merge, or discard this patch.
registration_form/espresso_events_Registration_Form_Hooks_Extend.class.php 1 patch
Indentation   +189 added lines, -189 removed lines patch added patch discarded remove patch
@@ -17,208 +17,208 @@
 block discarded – undo
17 17
 class espresso_events_Registration_Form_Hooks_Extend extends espresso_events_Registration_Form_Hooks
18 18
 {
19 19
 
20
-    /**
21
-     * extending the properties set in espresso_events_Registration_From_Hooks
22
-     *
23
-     * @access protected
24
-     * @return void
25
-     */
26
-    protected function _extend_properties()
27
-    {
28
-        $this->_metaboxes = array_merge(
29
-            $this->_metaboxes,
30
-            array(
31
-                1 => array(
32
-                    'page_route' => array('create_new', 'edit'),
33
-                    'func'       => 'additional_questions',
34
-                    'label'      => esc_html__('Questions for Additional Registrants', 'event_espresso'),
35
-                    'priority'   => 'default',
36
-                    'context'    => 'side',
37
-                ),
38
-            )
39
-        );
40
-        $this->_scripts_styles = array(
41
-            'registers' => array(
42
-                'extended-event-editor' => array(
43
-                    'url'     => EE_CORE_CAF_ADMIN_EXTEND_URL
44
-                                 . 'registration_form/assets/event-editor-question-groups.js',
45
-                    'depends' => array('jquery'),
46
-                ),
47
-            ),
48
-            'enqueues'  => array(
49
-                'extended-event-editor' => array('edit', 'create_new'),
50
-            ),
51
-        );
52
-    }
53
-
54
-
55
-    /**
56
-     * @param Callable[] $callbacks
57
-     * @return array
58
-     */
59
-    public function modify_callbacks($callbacks)
60
-    {
61
-        $callbacks = parent::modify_callbacks($callbacks);
62
-        $callbacks[] = array($this, 'additional_question_group_update');
63
-        return $callbacks;
64
-    }
65
-
66
-
67
-    /**
68
-     * Call back hooked into revision restores.
69
-     *
70
-     * @param $post_id
71
-     * @param $revision_id
72
-     * @return EE_Base_Class|void
73
-     * @throws EE_Error
74
-     * @throws InvalidArgumentException
75
-     * @throws InvalidDataTypeException
76
-     * @throws InvalidInterfaceException
77
-     * @throws ReflectionException
78
-     */
79
-    public function restore_revision($post_id, $revision_id)
80
-    {
81
-        $post_evt = parent::restore_revision($post_id, $revision_id);
82
-
83
-        // restore revision for additional questions
84
-        $post_evt->restore_revision(
85
-            $revision_id,
86
-            ['Question_Group'],
87
-            [
88
-                'Question_Group' => ['Event_Question_Group.EQG_additional' => true],
89
-            ]
90
-        );
91
-    }
92
-
93
-
94
-    /**
95
-     * @param $post_id
96
-     * @param $post
97
-     * @throws EE_Error
98
-     * @throws InvalidArgumentException
99
-     * @throws InvalidDataTypeException
100
-     * @throws InvalidInterfaceException
101
-     */
102
-    public function additional_questions($post_id, $post)
103
-    {
104
-        $this->_event = $this->_adminpage_obj->get_event_object();
105
-        $event_id = $this->_event->ID();
106
-        ?>
20
+	/**
21
+	 * extending the properties set in espresso_events_Registration_From_Hooks
22
+	 *
23
+	 * @access protected
24
+	 * @return void
25
+	 */
26
+	protected function _extend_properties()
27
+	{
28
+		$this->_metaboxes = array_merge(
29
+			$this->_metaboxes,
30
+			array(
31
+				1 => array(
32
+					'page_route' => array('create_new', 'edit'),
33
+					'func'       => 'additional_questions',
34
+					'label'      => esc_html__('Questions for Additional Registrants', 'event_espresso'),
35
+					'priority'   => 'default',
36
+					'context'    => 'side',
37
+				),
38
+			)
39
+		);
40
+		$this->_scripts_styles = array(
41
+			'registers' => array(
42
+				'extended-event-editor' => array(
43
+					'url'     => EE_CORE_CAF_ADMIN_EXTEND_URL
44
+								 . 'registration_form/assets/event-editor-question-groups.js',
45
+					'depends' => array('jquery'),
46
+				),
47
+			),
48
+			'enqueues'  => array(
49
+				'extended-event-editor' => array('edit', 'create_new'),
50
+			),
51
+		);
52
+	}
53
+
54
+
55
+	/**
56
+	 * @param Callable[] $callbacks
57
+	 * @return array
58
+	 */
59
+	public function modify_callbacks($callbacks)
60
+	{
61
+		$callbacks = parent::modify_callbacks($callbacks);
62
+		$callbacks[] = array($this, 'additional_question_group_update');
63
+		return $callbacks;
64
+	}
65
+
66
+
67
+	/**
68
+	 * Call back hooked into revision restores.
69
+	 *
70
+	 * @param $post_id
71
+	 * @param $revision_id
72
+	 * @return EE_Base_Class|void
73
+	 * @throws EE_Error
74
+	 * @throws InvalidArgumentException
75
+	 * @throws InvalidDataTypeException
76
+	 * @throws InvalidInterfaceException
77
+	 * @throws ReflectionException
78
+	 */
79
+	public function restore_revision($post_id, $revision_id)
80
+	{
81
+		$post_evt = parent::restore_revision($post_id, $revision_id);
82
+
83
+		// restore revision for additional questions
84
+		$post_evt->restore_revision(
85
+			$revision_id,
86
+			['Question_Group'],
87
+			[
88
+				'Question_Group' => ['Event_Question_Group.EQG_additional' => true],
89
+			]
90
+		);
91
+	}
92
+
93
+
94
+	/**
95
+	 * @param $post_id
96
+	 * @param $post
97
+	 * @throws EE_Error
98
+	 * @throws InvalidArgumentException
99
+	 * @throws InvalidDataTypeException
100
+	 * @throws InvalidInterfaceException
101
+	 */
102
+	public function additional_questions($post_id, $post)
103
+	{
104
+		$this->_event = $this->_adminpage_obj->get_event_object();
105
+		$event_id = $this->_event->ID();
106
+		?>
107 107
         <div class="inside">
108 108
             <p><strong>
109 109
                     <?php esc_html_e('Question Groups', 'event_espresso'); ?>
110 110
                 </strong><br/>
111 111
                 <?php
112
-                printf(
113
-                    esc_html__(
114
-                        'Add a pre-populated %1$sgroup of questions%2$s to your event.',
115
-                        'event_espresso'
116
-                    ),
117
-                    '<a href="admin.php?page=espresso_registration_form" target="_blank">',
118
-                    '</a>'
119
-                );
120
-                ?>
112
+				printf(
113
+					esc_html__(
114
+						'Add a pre-populated %1$sgroup of questions%2$s to your event.',
115
+						'event_espresso'
116
+					),
117
+					'<a href="admin.php?page=espresso_registration_form" target="_blank">',
118
+					'</a>'
119
+				);
120
+				?>
121 121
             </p>
122 122
             <?php
123 123
 
124
-            $qsg_where['QSG_deleted'] = false;
125
-            $query_params = apply_filters(
126
-                'FHEE__espresso_events_Registration_Form_Hooks_Extend__additional_questions__question_group_query_parameters',
127
-                array($qsg_where, 'order_by' => array('QSG_order' => 'ASC'))
128
-            );
129
-            $QSGs = EEM_Question_Group::instance()->get_all($query_params);
130
-            $EQGs = ! empty($event_id)
131
-                ? $this->_event->get_many_related(
132
-                    'Question_Group',
133
-                    [['Event_Question_Group.EQG_additional' => true]]
134
-                )
135
-                : [];
136
-            $EQGids = array_keys($EQGs);
137
-
138
-            if (! empty($QSGs)) {
139
-                $html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
140
-                foreach ($QSGs as $QSG) {
141
-                    $checked = in_array($QSG->ID(), $EQGids, true) ? ' checked="checked" ' : '';
142
-                    $edit_link = EE_Admin_Page::add_query_args_and_nonce(
143
-                        array(
144
-                            'action' => 'edit_question_group',
145
-                            'QSG_ID' => $QSG->ID(),
146
-                        ),
147
-                        EE_FORMS_ADMIN_URL
148
-                    );
149
-
150
-                    $html .= '
124
+			$qsg_where['QSG_deleted'] = false;
125
+			$query_params = apply_filters(
126
+				'FHEE__espresso_events_Registration_Form_Hooks_Extend__additional_questions__question_group_query_parameters',
127
+				array($qsg_where, 'order_by' => array('QSG_order' => 'ASC'))
128
+			);
129
+			$QSGs = EEM_Question_Group::instance()->get_all($query_params);
130
+			$EQGs = ! empty($event_id)
131
+				? $this->_event->get_many_related(
132
+					'Question_Group',
133
+					[['Event_Question_Group.EQG_additional' => true]]
134
+				)
135
+				: [];
136
+			$EQGids = array_keys($EQGs);
137
+
138
+			if (! empty($QSGs)) {
139
+				$html = count($QSGs) > 10 ? '<div style="height:250px;overflow:auto;">' : '';
140
+				foreach ($QSGs as $QSG) {
141
+					$checked = in_array($QSG->ID(), $EQGids, true) ? ' checked="checked" ' : '';
142
+					$edit_link = EE_Admin_Page::add_query_args_and_nonce(
143
+						array(
144
+							'action' => 'edit_question_group',
145
+							'QSG_ID' => $QSG->ID(),
146
+						),
147
+						EE_FORMS_ADMIN_URL
148
+					);
149
+
150
+					$html .= '
151 151
 					<p id="event-question-group-' . $QSG->ID() . '">
152 152
 						<input value="' . $QSG->ID() . '"'
153
-                             . ' type="checkbox" name="add_attendee_question_groups[' . $QSG->ID() . ']"' . $checked . ' />
153
+							 . ' type="checkbox" name="add_attendee_question_groups[' . $QSG->ID() . ']"' . $checked . ' />
154 154
 						<a href="' . $edit_link . '" title="'
155
-                             . sprintf(
156
-                                 esc_attr__('Edit %s Group', 'event_espresso'),
157
-                                 $QSG->get('QSG_name')
158
-                             )
159
-                             . '" target="_blank">' . $QSG->get('QSG_name') . '</a>
155
+							 . sprintf(
156
+								 esc_attr__('Edit %s Group', 'event_espresso'),
157
+								 $QSG->get('QSG_name')
158
+							 )
159
+							 . '" target="_blank">' . $QSG->get('QSG_name') . '</a>
160 160
 					</p>';
161
-                    if ($QSG->ID() === 2) {
162
-                        $html .= '
161
+					if ($QSG->ID() === 2) {
162
+						$html .= '
163 163
 					<p id="question-group-requirements-notice-pg" class="important-notice small-text" style="display: none;">'
164
-                                 . esc_html__(
165
-                                     'The Personal Information question group is required whenever the Address Information question group is activated.',
166
-                                     'event_espresso'
167
-                                 )
168
-                                 . '</p>';
169
-                    }
170
-                }
171
-                $html .= count($QSGs) > 10 ? '</div>' : '';
172
-
173
-                echo wp_kses($html, AllowedTags::getWithFormTags());
174
-            } else {
175
-                esc_html_e(
176
-                    'There seems to be a problem with your questions. Please contact [email protected]',
177
-                    'event_espresso'
178
-                );
179
-            }
180
-            do_action('AHEE__espresso_events_Registration_Form_Hooks__additional_questions__after_content');
181
-            ?>
164
+								 . esc_html__(
165
+									 'The Personal Information question group is required whenever the Address Information question group is activated.',
166
+									 'event_espresso'
167
+								 )
168
+								 . '</p>';
169
+					}
170
+				}
171
+				$html .= count($QSGs) > 10 ? '</div>' : '';
172
+
173
+				echo wp_kses($html, AllowedTags::getWithFormTags());
174
+			} else {
175
+				esc_html_e(
176
+					'There seems to be a problem with your questions. Please contact [email protected]',
177
+					'event_espresso'
178
+				);
179
+			}
180
+			do_action('AHEE__espresso_events_Registration_Form_Hooks__additional_questions__after_content');
181
+			?>
182 182
         </div>
183 183
         <?php
184
-    }
185
-
186
-
187
-    public function additional_question_group_update($evtobj, $data)
188
-    {
189
-        $question_groups = ! empty($data['add_attendee_question_groups'])
190
-            ? (array) $data['add_attendee_question_groups']
191
-            : [];
192
-        $added_qgs = array_keys($question_groups);
193
-        $success = [];
194
-
195
-        // let's get all current question groups associated with this event.
196
-        $current_qgs = $evtobj->get_many_related(
197
-            'Question_Group',
198
-            [['Event_Question_Group.EQG_additional' => true]]
199
-        );
200
-        $current_qgs = array_keys($current_qgs); // we just want the ids
201
-
202
-        // now let's get the groups selected in the editor and update (IF we have data)
203
-        if (! empty($question_groups)) {
204
-            foreach ($question_groups as $qgid) {
205
-                // add to event
206
-                if ($qgid) {
207
-                    $qg = $evtobj->add_question_group($qgid, false);
208
-                }
209
-                $success[] = ! empty($qg) ? 1 : 0;
210
-            }
211
-        }
212
-
213
-        // wait a minute... are there question groups missing in the saved groups that ARE with the current event?
214
-        $removed_qgs = array_diff($current_qgs, $added_qgs);
215
-
216
-        foreach ($removed_qgs as $qgid) {
217
-            $qg = $evtobj->remove_question_group($qgid, false);
218
-            $success[] = ! empty($qg) ? 1 : 0;
219
-        }
220
-
221
-
222
-        return in_array(0, $success, true) ? false : true;
223
-    }
184
+	}
185
+
186
+
187
+	public function additional_question_group_update($evtobj, $data)
188
+	{
189
+		$question_groups = ! empty($data['add_attendee_question_groups'])
190
+			? (array) $data['add_attendee_question_groups']
191
+			: [];
192
+		$added_qgs = array_keys($question_groups);
193
+		$success = [];
194
+
195
+		// let's get all current question groups associated with this event.
196
+		$current_qgs = $evtobj->get_many_related(
197
+			'Question_Group',
198
+			[['Event_Question_Group.EQG_additional' => true]]
199
+		);
200
+		$current_qgs = array_keys($current_qgs); // we just want the ids
201
+
202
+		// now let's get the groups selected in the editor and update (IF we have data)
203
+		if (! empty($question_groups)) {
204
+			foreach ($question_groups as $qgid) {
205
+				// add to event
206
+				if ($qgid) {
207
+					$qg = $evtobj->add_question_group($qgid, false);
208
+				}
209
+				$success[] = ! empty($qg) ? 1 : 0;
210
+			}
211
+		}
212
+
213
+		// wait a minute... are there question groups missing in the saved groups that ARE with the current event?
214
+		$removed_qgs = array_diff($current_qgs, $added_qgs);
215
+
216
+		foreach ($removed_qgs as $qgid) {
217
+			$qg = $evtobj->remove_question_group($qgid, false);
218
+			$success[] = ! empty($qg) ? 1 : 0;
219
+		}
220
+
221
+
222
+		return in_array(0, $success, true) ? false : true;
223
+	}
224 224
 }
Please login to merge, or discard this patch.
extend/registration_form/templates/questions_in_group_meta_box.template.php 1 patch
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -4,7 +4,7 @@
 block discarded – undo
4 4
 use EventEspresso\core\services\request\sanitizers\AllowedTags;
5 5
 
6 6
 assert($question_group instanceof EE_Question_Group);
7
-assert(isset($all_questions) && (empty($all_questions) || is_array($all_questions)));// list of unused questions
7
+assert(isset($all_questions) && (empty($all_questions) || is_array($all_questions))); // list of unused questions
8 8
 foreach ($all_questions as $question_option) {
9 9
     assert($question_option);
10 10
     assert($question_option instanceof EE_Question);
Please login to merge, or discard this patch.
core/EE_System.core.php 2 patches
Indentation   +1345 added lines, -1345 removed lines patch added patch discarded remove patch
@@ -27,1349 +27,1349 @@
 block discarded – undo
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29 29
 
30
-    /**
31
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
-     */
34
-    const req_type_normal = 0;
35
-
36
-    /**
37
-     * Indicates this is a brand new installation of EE so we should install
38
-     * tables and default data etc
39
-     */
40
-    const req_type_new_activation = 1;
41
-
42
-    /**
43
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
-     * and we just exited maintenance mode). We MUST check the database is setup properly
45
-     * and that default data is setup too
46
-     */
47
-    const req_type_reactivation = 2;
48
-
49
-    /**
50
-     * indicates that EE has been upgraded since its previous request.
51
-     * We may have data migration scripts to call and will want to trigger maintenance mode
52
-     */
53
-    const req_type_upgrade = 3;
54
-
55
-    /**
56
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
-     */
58
-    const req_type_downgrade = 4;
59
-
60
-    /**
61
-     * @deprecated since version 4.6.0.dev.006
62
-     * Now whenever a new_activation is detected the request type is still just
63
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
-     * (Specifically, when the migration manager indicates migrations are finished
67
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
-     */
69
-    const req_type_activation_but_not_installed = 5;
70
-
71
-    /**
72
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
-     */
74
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
-
76
-    /**
77
-     * @var EE_System $_instance
78
-     */
79
-    private static $_instance;
80
-
81
-    /**
82
-     * @var EE_Registry $registry
83
-     */
84
-    private $registry;
85
-
86
-    /**
87
-     * @var LoaderInterface $loader
88
-     */
89
-    private $loader;
90
-
91
-    /**
92
-     * @var EE_Capabilities $capabilities
93
-     */
94
-    private $capabilities;
95
-
96
-    /**
97
-     * @var RequestInterface $request
98
-     */
99
-    private $request;
100
-
101
-    /**
102
-     * @var EE_Maintenance_Mode $maintenance_mode
103
-     */
104
-    private $maintenance_mode;
105
-
106
-    /**
107
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
-     *
110
-     * @var int $_req_type
111
-     */
112
-    private $_req_type;
113
-
114
-    /**
115
-     * Whether or not there was a non-micro version change in EE core version during this request
116
-     *
117
-     * @var boolean $_major_version_change
118
-     */
119
-    private $_major_version_change = false;
120
-
121
-    /**
122
-     * A Context DTO dedicated solely to identifying the current request type.
123
-     *
124
-     * @var RequestTypeContextCheckerInterface $request_type
125
-     */
126
-    private $request_type;
127
-
128
-    /**
129
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
130
-     */
131
-    private $register_custom_post_types;
132
-
133
-    /**
134
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
135
-     */
136
-    private $register_custom_taxonomies;
137
-
138
-    /**
139
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
140
-     */
141
-    private $register_custom_taxonomy_terms;
142
-
143
-    /**
144
-     * @singleton method used to instantiate class object
145
-     * @param EE_Registry|null         $registry
146
-     * @param LoaderInterface|null     $loader
147
-     * @param RequestInterface|null    $request
148
-     * @param EE_Maintenance_Mode|null $maintenance_mode
149
-     * @return EE_System
150
-     */
151
-    public static function instance(
152
-        EE_Registry $registry = null,
153
-        LoaderInterface $loader = null,
154
-        RequestInterface $request = null,
155
-        EE_Maintenance_Mode $maintenance_mode = null
156
-    ) {
157
-        // check if class object is instantiated
158
-        if (! self::$_instance instanceof EE_System) {
159
-            self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160
-        }
161
-        return self::$_instance;
162
-    }
163
-
164
-
165
-    /**
166
-     * resets the instance and returns it
167
-     *
168
-     * @return EE_System
169
-     */
170
-    public static function reset()
171
-    {
172
-        self::$_instance->_req_type = null;
173
-        // make sure none of the old hooks are left hanging around
174
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
175
-        // we need to reset the migration manager in order for it to detect DMSs properly
176
-        EE_Data_Migration_Manager::reset();
177
-        self::instance()->detect_activations_or_upgrades();
178
-        self::instance()->perform_activations_upgrades_and_migrations();
179
-        return self::instance();
180
-    }
181
-
182
-
183
-    /**
184
-     * sets hooks for running rest of system
185
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
186
-     * starting EE Addons from any other point may lead to problems
187
-     *
188
-     * @param EE_Registry         $registry
189
-     * @param LoaderInterface     $loader
190
-     * @param RequestInterface    $request
191
-     * @param EE_Maintenance_Mode $maintenance_mode
192
-     */
193
-    private function __construct(
194
-        EE_Registry $registry,
195
-        LoaderInterface $loader,
196
-        RequestInterface $request,
197
-        EE_Maintenance_Mode $maintenance_mode
198
-    ) {
199
-        $this->registry = $registry;
200
-        $this->loader = $loader;
201
-        $this->request = $request;
202
-        $this->maintenance_mode = $maintenance_mode;
203
-        do_action('AHEE__EE_System__construct__begin', $this);
204
-        add_action(
205
-            'AHEE__EE_Bootstrap__load_espresso_addons',
206
-            array($this, 'loadCapabilities'),
207
-            5
208
-        );
209
-        add_action(
210
-            'AHEE__EE_Bootstrap__load_espresso_addons',
211
-            array($this, 'loadCommandBus'),
212
-            7
213
-        );
214
-        add_action(
215
-            'AHEE__EE_Bootstrap__load_espresso_addons',
216
-            array($this, 'loadPluginApi'),
217
-            9
218
-        );
219
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
220
-        add_action(
221
-            'AHEE__EE_Bootstrap__load_espresso_addons',
222
-            array($this, 'load_espresso_addons')
223
-        );
224
-        // when an ee addon is activated, we want to call the core hook(s) again
225
-        // because the newly-activated addon didn't get a chance to run at all
226
-        add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
227
-        // detect whether install or upgrade
228
-        add_action(
229
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
230
-            array($this, 'detect_activations_or_upgrades'),
231
-            3
232
-        );
233
-        // load EE_Config, EE_Textdomain, etc
234
-        add_action(
235
-            'AHEE__EE_Bootstrap__load_core_configuration',
236
-            array($this, 'load_core_configuration'),
237
-            5
238
-        );
239
-        // load specifications for matching routes to current request
240
-        add_action(
241
-            'AHEE__EE_Bootstrap__load_core_configuration',
242
-            array($this, 'loadRouteMatchSpecifications')
243
-        );
244
-        // load specifications for custom post types
245
-        add_action(
246
-            'AHEE__EE_Bootstrap__load_core_configuration',
247
-            array($this, 'loadCustomPostTypes')
248
-        );
249
-        // load EE_Config, EE_Textdomain, etc
250
-        add_action(
251
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
252
-            array($this, 'register_shortcodes_modules_and_widgets'),
253
-            7
254
-        );
255
-        // you wanna get going? I wanna get going... let's get going!
256
-        add_action(
257
-            'AHEE__EE_Bootstrap__brew_espresso',
258
-            array($this, 'brew_espresso'),
259
-            9
260
-        );
261
-        // other housekeeping
262
-        // exclude EE critical pages from wp_list_pages
263
-        add_filter(
264
-            'wp_list_pages_excludes',
265
-            array($this, 'remove_pages_from_wp_list_pages'),
266
-            10
267
-        );
268
-        // ALL EE Addons should use the following hook point to attach their initial setup too
269
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
270
-        do_action('AHEE__EE_System__construct__complete', $this);
271
-    }
272
-
273
-
274
-    /**
275
-     * load and setup EE_Capabilities
276
-     *
277
-     * @return void
278
-     * @throws EE_Error
279
-     */
280
-    public function loadCapabilities()
281
-    {
282
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
283
-        add_action(
284
-            'AHEE__EE_Capabilities__init_caps__before_initialization',
285
-            function () {
286
-                LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287
-            }
288
-        );
289
-    }
290
-
291
-
292
-    /**
293
-     * create and cache the CommandBus, and also add middleware
294
-     * The CapChecker middleware requires the use of EE_Capabilities
295
-     * which is why we need to load the CommandBus after Caps are set up
296
-     *
297
-     * @return void
298
-     * @throws EE_Error
299
-     */
300
-    public function loadCommandBus()
301
-    {
302
-        $this->loader->getShared(
303
-            'CommandBusInterface',
304
-            array(
305
-                null,
306
-                apply_filters(
307
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
308
-                    array(
309
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
310
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
311
-                    )
312
-                ),
313
-            )
314
-        );
315
-    }
316
-
317
-
318
-    /**
319
-     * @return void
320
-     * @throws EE_Error
321
-     */
322
-    public function loadPluginApi()
323
-    {
324
-        // set autoloaders for all of the classes implementing EEI_Plugin_API
325
-        // which provide helpers for EE plugin authors to more easily register certain components with EE.
326
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
327
-    }
328
-
329
-
330
-    /**
331
-     * @param string $addon_name
332
-     * @param string $version_constant
333
-     * @param string $min_version_required
334
-     * @param string $load_callback
335
-     * @param string $plugin_file_constant
336
-     * @return void
337
-     */
338
-    private function deactivateIncompatibleAddon(
339
-        $addon_name,
340
-        $version_constant,
341
-        $min_version_required,
342
-        $load_callback,
343
-        $plugin_file_constant
344
-    ) {
345
-        if (! defined($version_constant)) {
346
-            return;
347
-        }
348
-        $addon_version = constant($version_constant);
349
-        if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350
-            remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
-            if (! function_exists('deactivate_plugins')) {
352
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
353
-            }
354
-            deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355
-            $this->request->unSetRequestParams(['activate', 'activate-multi'], true);
356
-            EE_Error::add_error(
357
-                sprintf(
358
-                    esc_html__(
359
-                        'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
360
-                        'event_espresso'
361
-                    ),
362
-                    $addon_name,
363
-                    $min_version_required
364
-                ),
365
-                __FILE__,
366
-                __FUNCTION__ . "({$addon_name})",
367
-                __LINE__
368
-            );
369
-            EE_Error::get_notices(false, true);
370
-        }
371
-    }
372
-
373
-
374
-    /**
375
-     * load_espresso_addons
376
-     * allow addons to load first so that they can set hooks for running DMS's, etc
377
-     * this is hooked into both:
378
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
379
-     *        which runs during the WP 'plugins_loaded' action at priority 5
380
-     *    and the WP 'activate_plugin' hook point
381
-     *
382
-     * @access public
383
-     * @return void
384
-     */
385
-    public function load_espresso_addons()
386
-    {
387
-        $this->deactivateIncompatibleAddon(
388
-            'Wait Lists',
389
-            'EE_WAIT_LISTS_VERSION',
390
-            '1.0.0.beta.074',
391
-            'load_espresso_wait_lists',
392
-            'EE_WAIT_LISTS_PLUGIN_FILE'
393
-        );
394
-        $this->deactivateIncompatibleAddon(
395
-            'Automated Upcoming Event Notifications',
396
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
397
-            '1.0.0.beta.091',
398
-            'load_espresso_automated_upcoming_event_notification',
399
-            'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
400
-        );
401
-        do_action('AHEE__EE_System__load_espresso_addons');
402
-        // if the WP API basic auth plugin isn't already loaded, load it now.
403
-        // We want it for mobile apps. Just include the entire plugin
404
-        // also, don't load the basic auth when a plugin is getting activated, because
405
-        // it could be the basic auth plugin, and it doesn't check if its methods are already defined
406
-        // and causes a fatal error
407
-        if (
408
-            ($this->request->isWordPressApi() || $this->request->isApi())
409
-            && $this->request->getRequestParam('activate') !== 'true'
410
-            && ! function_exists('json_basic_auth_handler')
411
-            && ! function_exists('json_basic_auth_error')
412
-            && ! in_array(
413
-                $this->request->getRequestParam('action'),
414
-                array('activate', 'activate-selected'),
415
-                true
416
-            )
417
-        ) {
418
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
419
-        }
420
-        do_action('AHEE__EE_System__load_espresso_addons__complete');
421
-    }
422
-
423
-
424
-    /**
425
-     * detect_activations_or_upgrades
426
-     * Checks for activation or upgrade of core first;
427
-     * then also checks if any registered addons have been activated or upgraded
428
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
429
-     * which runs during the WP 'plugins_loaded' action at priority 3
430
-     *
431
-     * @access public
432
-     * @return void
433
-     */
434
-    public function detect_activations_or_upgrades()
435
-    {
436
-        // first off: let's make sure to handle core
437
-        $this->detect_if_activation_or_upgrade();
438
-        foreach ($this->registry->addons as $addon) {
439
-            if ($addon instanceof EE_Addon) {
440
-                // detect teh request type for that addon
441
-                $addon->detect_req_type();
442
-            }
443
-        }
444
-    }
445
-
446
-
447
-    /**
448
-     * detect_if_activation_or_upgrade
449
-     * Takes care of detecting whether this is a brand new install or code upgrade,
450
-     * and either setting up the DB or setting up maintenance mode etc.
451
-     *
452
-     * @access public
453
-     * @return void
454
-     */
455
-    public function detect_if_activation_or_upgrade()
456
-    {
457
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
458
-        // check if db has been updated, or if its a brand-new installation
459
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
460
-        $request_type = $this->detect_req_type($espresso_db_update);
461
-        // EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
462
-        switch ($request_type) {
463
-            case EE_System::req_type_new_activation:
464
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
465
-                $this->_handle_core_version_change($espresso_db_update);
466
-                break;
467
-            case EE_System::req_type_reactivation:
468
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
469
-                $this->_handle_core_version_change($espresso_db_update);
470
-                break;
471
-            case EE_System::req_type_upgrade:
472
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
473
-                // migrations may be required now that we've upgraded
474
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
475
-                $this->_handle_core_version_change($espresso_db_update);
476
-                break;
477
-            case EE_System::req_type_downgrade:
478
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
479
-                // its possible migrations are no longer required
480
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
481
-                $this->_handle_core_version_change($espresso_db_update);
482
-                break;
483
-            case EE_System::req_type_normal:
484
-            default:
485
-                break;
486
-        }
487
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
488
-    }
489
-
490
-
491
-    /**
492
-     * Updates the list of installed versions and sets hooks for
493
-     * initializing the database later during the request
494
-     *
495
-     * @param array $espresso_db_update
496
-     */
497
-    private function _handle_core_version_change($espresso_db_update)
498
-    {
499
-        $this->update_list_of_installed_versions($espresso_db_update);
500
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
501
-        add_action(
502
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
503
-            array($this, 'initialize_db_if_no_migrations_required')
504
-        );
505
-    }
506
-
507
-
508
-    /**
509
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
510
-     * information about what versions of EE have been installed and activated,
511
-     * NOT necessarily the state of the database
512
-     *
513
-     * @param mixed $espresso_db_update           the value of the WordPress option.
514
-     *                                            If not supplied, fetches it from the options table
515
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
516
-     */
517
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518
-    {
519
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
-        if (! $espresso_db_update) {
521
-            $espresso_db_update = get_option('espresso_db_update');
522
-        }
523
-        // check that option is an array
524
-        if (! is_array($espresso_db_update)) {
525
-            // if option is FALSE, then it never existed
526
-            if ($espresso_db_update === false) {
527
-                // make $espresso_db_update an array and save option with autoload OFF
528
-                $espresso_db_update = array();
529
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
530
-            } else {
531
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
532
-                $espresso_db_update = array($espresso_db_update => array());
533
-                update_option('espresso_db_update', $espresso_db_update);
534
-            }
535
-        } else {
536
-            $corrected_db_update = array();
537
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
538
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
539
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
540
-                    // the key is an int, and the value IS NOT an array
541
-                    // so it must be numerically-indexed, where values are versions installed...
542
-                    // fix it!
543
-                    $version_string = $should_be_array;
544
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
545
-                } else {
546
-                    // ok it checks out
547
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
548
-                }
549
-            }
550
-            $espresso_db_update = $corrected_db_update;
551
-            update_option('espresso_db_update', $espresso_db_update);
552
-        }
553
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
554
-        return $espresso_db_update;
555
-    }
556
-
557
-
558
-    /**
559
-     * Does the traditional work of setting up the plugin's database and adding default data.
560
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
561
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
562
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
563
-     * so that it will be done when migrations are finished
564
-     *
565
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
566
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
567
-     *                                       This is a resource-intensive job
568
-     *                                       so we prefer to only do it when necessary
569
-     * @return void
570
-     * @throws EE_Error
571
-     */
572
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
573
-    {
574
-        $request_type = $this->detect_req_type();
575
-        // only initialize system if we're not in maintenance mode.
576
-        if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
577
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
578
-            $rewrite_rules = $this->loader->getShared(
579
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
580
-            );
581
-            $rewrite_rules->flush();
582
-            if ($verify_schema) {
583
-                EEH_Activation::initialize_db_and_folders();
584
-            }
585
-            EEH_Activation::initialize_db_content();
586
-            EEH_Activation::system_initialization();
587
-            if ($initialize_addons_too) {
588
-                $this->initialize_addons();
589
-            }
590
-        } else {
591
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
592
-        }
593
-        if (
594
-            $request_type === EE_System::req_type_new_activation
595
-            || $request_type === EE_System::req_type_reactivation
596
-            || (
597
-                $request_type === EE_System::req_type_upgrade
598
-                && $this->is_major_version_change()
599
-            )
600
-        ) {
601
-            add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
602
-        }
603
-    }
604
-
605
-
606
-    /**
607
-     * Initializes the db for all registered addons
608
-     *
609
-     * @throws EE_Error
610
-     */
611
-    public function initialize_addons()
612
-    {
613
-        // foreach registered addon, make sure its db is up-to-date too
614
-        foreach ($this->registry->addons as $addon) {
615
-            if ($addon instanceof EE_Addon) {
616
-                $addon->initialize_db_if_no_migrations_required();
617
-            }
618
-        }
619
-    }
620
-
621
-
622
-    /**
623
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
624
-     *
625
-     * @param    array  $version_history
626
-     * @param    string $current_version_to_add version to be added to the version history
627
-     * @return    boolean success as to whether or not this option was changed
628
-     */
629
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630
-    {
631
-        if (! $version_history) {
632
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
633
-        }
634
-        if ($current_version_to_add === null) {
635
-            $current_version_to_add = espresso_version();
636
-        }
637
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
638
-        // re-save
639
-        return update_option('espresso_db_update', $version_history);
640
-    }
641
-
642
-
643
-    /**
644
-     * Detects if the current version indicated in the has existed in the list of
645
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
646
-     *
647
-     * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
648
-     *                                  If not supplied, fetches it from the options table.
649
-     *                                  Also, caches its result so later parts of the code can also know whether
650
-     *                                  there's been an update or not. This way we can add the current version to
651
-     *                                  espresso_db_update, but still know if this is a new install or not
652
-     * @return int one of the constants on EE_System::req_type_
653
-     */
654
-    public function detect_req_type($espresso_db_update = null)
655
-    {
656
-        if ($this->_req_type === null) {
657
-            $espresso_db_update = ! empty($espresso_db_update)
658
-                ? $espresso_db_update
659
-                : $this->fix_espresso_db_upgrade_option();
660
-            $this->_req_type = EE_System::detect_req_type_given_activation_history(
661
-                $espresso_db_update,
662
-                'ee_espresso_activation',
663
-                espresso_version()
664
-            );
665
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
666
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
667
-        }
668
-        return $this->_req_type;
669
-    }
670
-
671
-
672
-    /**
673
-     * Returns whether or not there was a non-micro version change (ie, change in either
674
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
675
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
676
-     *
677
-     * @param $activation_history
678
-     * @return bool
679
-     */
680
-    private function _detect_major_version_change($activation_history)
681
-    {
682
-        $previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
683
-        $previous_version_parts = explode('.', $previous_version);
684
-        $current_version_parts = explode('.', espresso_version());
685
-        return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
686
-               && ($previous_version_parts[0] !== $current_version_parts[0]
687
-                   || $previous_version_parts[1] !== $current_version_parts[1]
688
-               );
689
-    }
690
-
691
-
692
-    /**
693
-     * Returns true if either the major or minor version of EE changed during this request.
694
-     * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
695
-     *
696
-     * @return bool
697
-     */
698
-    public function is_major_version_change()
699
-    {
700
-        return $this->_major_version_change;
701
-    }
702
-
703
-
704
-    /**
705
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
706
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
707
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
708
-     * just activated to (for core that will always be espresso_version())
709
-     *
710
-     * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
711
-     *                                                 ee plugin. for core that's 'espresso_db_update'
712
-     * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
713
-     *                                                 indicate that this plugin was just activated
714
-     * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
715
-     *                                                 espresso_version())
716
-     * @return int one of the constants on EE_System::req_type_*
717
-     */
718
-    public static function detect_req_type_given_activation_history(
719
-        $activation_history_for_addon,
720
-        $activation_indicator_option_name,
721
-        $version_to_upgrade_to
722
-    ) {
723
-        $version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
724
-        if ($activation_history_for_addon) {
725
-            // it exists, so this isn't a completely new install
726
-            // check if this version already in that list of previously installed versions
727
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
728
-                // it a version we haven't seen before
729
-                if ($version_is_higher === 1) {
730
-                    $req_type = EE_System::req_type_upgrade;
731
-                } else {
732
-                    $req_type = EE_System::req_type_downgrade;
733
-                }
734
-                delete_option($activation_indicator_option_name);
735
-            } else {
736
-                // its not an update. maybe a reactivation?
737
-                if (get_option($activation_indicator_option_name, false)) {
738
-                    if ($version_is_higher === -1) {
739
-                        $req_type = EE_System::req_type_downgrade;
740
-                    } elseif ($version_is_higher === 0) {
741
-                        // we've seen this version before, but it's an activation. must be a reactivation
742
-                        $req_type = EE_System::req_type_reactivation;
743
-                    } else {// $version_is_higher === 1
744
-                        $req_type = EE_System::req_type_upgrade;
745
-                    }
746
-                    delete_option($activation_indicator_option_name);
747
-                } else {
748
-                    // we've seen this version before and the activation indicate doesn't show it was just activated
749
-                    if ($version_is_higher === -1) {
750
-                        $req_type = EE_System::req_type_downgrade;
751
-                    } elseif ($version_is_higher === 0) {
752
-                        // we've seen this version before and it's not an activation. its normal request
753
-                        $req_type = EE_System::req_type_normal;
754
-                    } else {// $version_is_higher === 1
755
-                        $req_type = EE_System::req_type_upgrade;
756
-                    }
757
-                }
758
-            }
759
-        } else {
760
-            // brand new install
761
-            $req_type = EE_System::req_type_new_activation;
762
-            delete_option($activation_indicator_option_name);
763
-        }
764
-        return $req_type;
765
-    }
766
-
767
-
768
-    /**
769
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
770
-     * the $activation_history_for_addon
771
-     *
772
-     * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
773
-     *                                             sometimes containing 'unknown-date'
774
-     * @param string $version_to_upgrade_to        (current version)
775
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
776
-     *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
777
-     *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
778
-     *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
779
-     */
780
-    private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
781
-    {
782
-        // find the most recently-activated version
783
-        $most_recently_active_version =
784
-            EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
785
-        return version_compare($version_to_upgrade_to, $most_recently_active_version);
786
-    }
787
-
788
-
789
-    /**
790
-     * Gets the most recently active version listed in the activation history,
791
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
792
-     *
793
-     * @param array $activation_history  (keys are versions, values are arrays of times activated,
794
-     *                                   sometimes containing 'unknown-date'
795
-     * @return string
796
-     */
797
-    private static function _get_most_recently_active_version_from_activation_history($activation_history)
798
-    {
799
-        $most_recently_active_version_activation = '1970-01-01 00:00:00';
800
-        $most_recently_active_version = '0.0.0.dev.000';
801
-        if (is_array($activation_history)) {
802
-            foreach ($activation_history as $version => $times_activated) {
803
-                // check there is a record of when this version was activated. Otherwise,
804
-                // mark it as unknown
805
-                if (! $times_activated) {
806
-                    $times_activated = array('unknown-date');
807
-                }
808
-                if (is_string($times_activated)) {
809
-                    $times_activated = array($times_activated);
810
-                }
811
-                foreach ($times_activated as $an_activation) {
812
-                    if (
813
-                        $an_activation !== 'unknown-date'
814
-                        && $an_activation
815
-                           > $most_recently_active_version_activation
816
-                    ) {
817
-                        $most_recently_active_version = $version;
818
-                        $most_recently_active_version_activation = $an_activation === 'unknown-date'
819
-                            ? '1970-01-01 00:00:00'
820
-                            : $an_activation;
821
-                    }
822
-                }
823
-            }
824
-        }
825
-        return $most_recently_active_version;
826
-    }
827
-
828
-
829
-    /**
830
-     * This redirects to the about EE page after activation
831
-     *
832
-     * @return void
833
-     */
834
-    public function redirect_to_about_ee()
835
-    {
836
-        $notices = EE_Error::get_notices(false);
837
-        // if current user is an admin and it's not an ajax or rest request
838
-        if (
839
-            ! isset($notices['errors'])
840
-            && $this->request->isAdmin()
841
-            && apply_filters(
842
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
843
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
844
-            )
845
-        ) {
846
-            $query_params = array('page' => 'espresso_about');
847
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
848
-                $query_params['new_activation'] = true;
849
-            }
850
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
851
-                $query_params['reactivation'] = true;
852
-            }
853
-            $url = add_query_arg($query_params, admin_url('admin.php'));
854
-            wp_safe_redirect($url);
855
-            exit();
856
-        }
857
-    }
858
-
859
-
860
-    /**
861
-     * load_core_configuration
862
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
863
-     * which runs during the WP 'plugins_loaded' action at priority 5
864
-     *
865
-     * @return void
866
-     * @throws ReflectionException
867
-     * @throws Exception
868
-     */
869
-    public function load_core_configuration()
870
-    {
871
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
872
-        $this->loader->getShared('EE_Load_Textdomain');
873
-        // load textdomain
874
-        EE_Load_Textdomain::load_textdomain();
875
-        // load caf stuff a chance to play during the activation process too.
876
-        $this->_maybe_brew_regular();
877
-        // load and setup EE_Config and EE_Network_Config
878
-        $config = $this->loader->getShared('EE_Config');
879
-        $this->loader->getShared('EE_Network_Config');
880
-        // setup autoloaders
881
-        // enable logging?
882
-        if ($config->admin->use_remote_logging) {
883
-            $this->loader->getShared('EE_Log');
884
-        }
885
-        // check for activation errors
886
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
887
-        if ($activation_errors) {
888
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
889
-            update_option('ee_plugin_activation_errors', false);
890
-        }
891
-        // get model names
892
-        $this->_parse_model_names();
893
-        // configure custom post type definitions
894
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
895
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
896
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
897
-    }
898
-
899
-
900
-    /**
901
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
902
-     *
903
-     * @return void
904
-     * @throws ReflectionException
905
-     */
906
-    private function _parse_model_names()
907
-    {
908
-        // get all the files in the EE_MODELS folder that end in .model.php
909
-        $models = glob(EE_MODELS . '*.model.php');
910
-        $model_names = array();
911
-        $non_abstract_db_models = array();
912
-        foreach ($models as $model) {
913
-            // get model classname
914
-            $classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
915
-            $short_name = str_replace('EEM_', '', $classname);
916
-            $reflectionClass = new ReflectionClass($classname);
917
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
-                $non_abstract_db_models[ $short_name ] = $classname;
919
-            }
920
-            $model_names[ $short_name ] = $classname;
921
-        }
922
-        $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923
-        $this->registry->non_abstract_db_models = apply_filters(
924
-            'FHEE__EE_System__parse_implemented_model_names',
925
-            $non_abstract_db_models
926
-        );
927
-    }
928
-
929
-
930
-    /**
931
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
932
-     * that need to be setup before our EE_System launches.
933
-     *
934
-     * @return void
935
-     * @throws DomainException
936
-     * @throws InvalidArgumentException
937
-     * @throws InvalidDataTypeException
938
-     * @throws InvalidInterfaceException
939
-     * @throws InvalidClassException
940
-     * @throws InvalidFilePathException
941
-     */
942
-    private function _maybe_brew_regular()
943
-    {
944
-        /** @var Domain $domain */
945
-        $domain = DomainFactory::getShared(
946
-            new FullyQualifiedName(
947
-                'EventEspresso\core\domain\Domain'
948
-            ),
949
-            array(
950
-                new FilePath(EVENT_ESPRESSO_MAIN_FILE),
951
-                Version::fromString(espresso_version()),
952
-            )
953
-        );
954
-        if ($domain->isCaffeinated()) {
955
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
956
-        }
957
-    }
958
-
959
-
960
-    /**
961
-     * @since 4.9.71.p
962
-     * @throws Exception
963
-     */
964
-    public function loadRouteMatchSpecifications()
965
-    {
966
-        try {
967
-            $this->loader->getShared(
968
-                'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
969
-            );
970
-        } catch (Exception $exception) {
971
-            new ExceptionStackTraceDisplay($exception);
972
-        }
973
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
974
-    }
975
-
976
-
977
-    /**
978
-     * loading CPT related classes earlier so that their definitions are available
979
-     * but not performing any actual registration with WP core until load_CPTs_and_session() is called
980
-     *
981
-     * @since   4.10.21.p
982
-     */
983
-    public function loadCustomPostTypes()
984
-    {
985
-        $this->register_custom_taxonomies = $this->loader->getShared(
986
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
987
-        );
988
-        $this->register_custom_post_types = $this->loader->getShared(
989
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
990
-        );
991
-        $this->register_custom_taxonomy_terms = $this->loader->getShared(
992
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
993
-        );
994
-        // integrate WP_Query with the EE models
995
-        $this->loader->getShared('EE_CPT_Strategy');
996
-        // load legacy EE_Request_Handler in case add-ons still need it
997
-        $this->loader->getShared('EE_Request_Handler');
998
-    }
999
-
1000
-
1001
-    /**
1002
-     * register_shortcodes_modules_and_widgets
1003
-     * generate lists of shortcodes and modules, then verify paths and classes
1004
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
1005
-     * which runs during the WP 'plugins_loaded' action at priority 7
1006
-     *
1007
-     * @access public
1008
-     * @return void
1009
-     * @throws Exception
1010
-     */
1011
-    public function register_shortcodes_modules_and_widgets()
1012
-    {
1013
-        if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
1014
-            // load, register, and add shortcodes the new way
1015
-            $this->loader->getShared('EventEspresso\core\services\shortcodes\ShortcodesManager');
1016
-        }
1017
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
1018
-        // check for addons using old hook point
1019
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1020
-            $this->_incompatible_addon_error();
1021
-        }
1022
-    }
1023
-
1024
-
1025
-    /**
1026
-     * _incompatible_addon_error
1027
-     *
1028
-     * @access public
1029
-     * @return void
1030
-     */
1031
-    private function _incompatible_addon_error()
1032
-    {
1033
-        // get array of classes hooking into here
1034
-        $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036
-        );
1037
-        if (! empty($class_names)) {
1038
-            $msg = esc_html__(
1039
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040
-                'event_espresso'
1041
-            );
1042
-            $msg .= '<ul>';
1043
-            foreach ($class_names as $class_name) {
1044
-                $msg .= '<li><b>Event Espresso - '
1045
-                        . str_replace(
1046
-                            array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047
-                            '',
1048
-                            $class_name
1049
-                        ) . '</b></li>';
1050
-            }
1051
-            $msg .= '</ul>';
1052
-            $msg .= esc_html__(
1053
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1054
-                'event_espresso'
1055
-            );
1056
-            // save list of incompatible addons to wp-options for later use
1057
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1058
-            if (is_admin()) {
1059
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1060
-            }
1061
-        }
1062
-    }
1063
-
1064
-
1065
-    /**
1066
-     * brew_espresso
1067
-     * begins the process of setting hooks for initializing EE in the correct order
1068
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1069
-     * which runs during the WP 'plugins_loaded' action at priority 9
1070
-     *
1071
-     * @return void
1072
-     */
1073
-    public function brew_espresso()
1074
-    {
1075
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1076
-        // load some final core systems
1077
-        add_action('init', array($this, 'set_hooks_for_core'), 1);
1078
-        add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1079
-        add_action('init', array($this, 'load_CPTs_and_session'), 5);
1080
-        add_action('init', array($this, 'load_controllers'), 7);
1081
-        add_action('init', array($this, 'core_loaded_and_ready'), 9);
1082
-        add_action('init', array($this, 'initialize'), 10);
1083
-        add_action('init', array($this, 'initialize_last'), 100);
1084
-        if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1085
-            // pew pew pew
1086
-            $this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1087
-            do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1088
-        }
1089
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1090
-    }
1091
-
1092
-
1093
-    /**
1094
-     *    set_hooks_for_core
1095
-     *
1096
-     * @access public
1097
-     * @return    void
1098
-     * @throws EE_Error
1099
-     */
1100
-    public function set_hooks_for_core()
1101
-    {
1102
-        $this->_deactivate_incompatible_addons();
1103
-        do_action('AHEE__EE_System__set_hooks_for_core');
1104
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1105
-        // caps need to be initialized on every request so that capability maps are set.
1106
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1107
-        $this->registry->CAP->init_caps();
1108
-    }
1109
-
1110
-
1111
-    /**
1112
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1113
-     * deactivates any addons considered incompatible with the current version of EE
1114
-     */
1115
-    private function _deactivate_incompatible_addons()
1116
-    {
1117
-        $incompatible_addons = get_option('ee_incompatible_addons', array());
1118
-        if (! empty($incompatible_addons)) {
1119
-            $active_plugins = get_option('active_plugins', array());
1120
-            foreach ($active_plugins as $active_plugin) {
1121
-                foreach ($incompatible_addons as $incompatible_addon) {
1122
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1123
-                        $this->request->unSetRequestParams(['activate'], true);
1124
-                        espresso_deactivate_plugin($active_plugin);
1125
-                    }
1126
-                }
1127
-            }
1128
-        }
1129
-    }
1130
-
1131
-
1132
-    /**
1133
-     *    perform_activations_upgrades_and_migrations
1134
-     *
1135
-     * @access public
1136
-     * @return    void
1137
-     */
1138
-    public function perform_activations_upgrades_and_migrations()
1139
-    {
1140
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1141
-    }
1142
-
1143
-
1144
-    /**
1145
-     * @return void
1146
-     * @throws DomainException
1147
-     */
1148
-    public function load_CPTs_and_session()
1149
-    {
1150
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1151
-        $this->register_custom_taxonomies->registerCustomTaxonomies();
1152
-        $this->register_custom_post_types->registerCustomPostTypes();
1153
-        $this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1154
-        // load legacy Custom Post Types and Taxonomies
1155
-        $this->loader->getShared('EE_Register_CPTs');
1156
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1157
-    }
1158
-
1159
-
1160
-    /**
1161
-     * load_controllers
1162
-     * this is the best place to load any additional controllers that needs access to EE core.
1163
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1164
-     * time
1165
-     *
1166
-     * @access public
1167
-     * @return void
1168
-     */
1169
-    public function load_controllers()
1170
-    {
1171
-        do_action('AHEE__EE_System__load_controllers__start');
1172
-        // let's get it started
1173
-        if (
1174
-            ! $this->maintenance_mode->level()
1175
-            && ($this->request->isFrontend() || $this->request->isFrontAjax())
1176
-        ) {
1177
-            do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1178
-            $this->loader->getShared('EE_Front_Controller');
1179
-        } elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1180
-            do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1181
-            $this->loader->getShared('EE_Admin');
1182
-        } elseif ($this->request->isWordPressHeartbeat()) {
1183
-            $this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1184
-        }
1185
-        do_action('AHEE__EE_System__load_controllers__complete');
1186
-    }
1187
-
1188
-
1189
-    /**
1190
-     * core_loaded_and_ready
1191
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1192
-     *
1193
-     * @access public
1194
-     * @return void
1195
-     * @throws Exception
1196
-     */
1197
-    public function core_loaded_and_ready()
1198
-    {
1199
-        if (
1200
-            $this->request->isAdmin()
1201
-            || $this->request->isFrontend()
1202
-            || $this->request->isIframe()
1203
-            || $this->request->isWordPressApi()
1204
-        ) {
1205
-            try {
1206
-                $this->loader->getShared('EventEspresso\core\services\assets\Registry');
1207
-                $this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1208
-                if ($this->canLoadBlocks()) {
1209
-                    $this->loader->getShared(
1210
-                        'EventEspresso\core\services\editor\BlockRegistrationManager'
1211
-                    );
1212
-                }
1213
-            } catch (Exception $exception) {
1214
-                new ExceptionStackTraceDisplay($exception);
1215
-            }
1216
-        }
1217
-        if (
1218
-            $this->request->isAdmin()
1219
-            || $this->request->isEeAjax()
1220
-            || $this->request->isFrontend()
1221
-        ) {
1222
-            $this->loader->getShared('EE_Session');
1223
-        }
1224
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1225
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1226
-        // builders require these even on the front-end
1227
-        require_once EE_PUBLIC . 'template_tags.php';
1228
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229
-    }
1230
-
1231
-
1232
-    /**
1233
-     * initialize
1234
-     * this is the best place to begin initializing client code
1235
-     *
1236
-     * @access public
1237
-     * @return void
1238
-     */
1239
-    public function initialize()
1240
-    {
1241
-        do_action('AHEE__EE_System__initialize');
1242
-        add_filter(
1243
-            'safe_style_css',
1244
-            function ($styles) {
1245
-                $styles[] = 'display';
1246
-                $styles[] = 'visibility';
1247
-                return $styles;
1248
-            }
1249
-        );
1250
-    }
1251
-
1252
-
1253
-    /**
1254
-     * initialize_last
1255
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1256
-     * initialize has done so
1257
-     *
1258
-     * @access public
1259
-     * @return void
1260
-     */
1261
-    public function initialize_last()
1262
-    {
1263
-        do_action('AHEE__EE_System__initialize_last');
1264
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1265
-        $rewrite_rules = $this->loader->getShared(
1266
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1267
-        );
1268
-        $rewrite_rules->flushRewriteRules();
1269
-        add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1270
-        if (
1271
-            ($this->request->isAjax() || $this->request->isAdmin())
1272
-            && $this->maintenance_mode->models_can_query()
1273
-        ) {
1274
-            $this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1275
-            $this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1276
-        }
1277
-    }
1278
-
1279
-
1280
-    /**
1281
-     * @return void
1282
-     * @throws EE_Error
1283
-     */
1284
-    public function addEspressoToolbar()
1285
-    {
1286
-        $this->loader->getShared(
1287
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1288
-            array($this->registry->CAP)
1289
-        );
1290
-    }
1291
-
1292
-
1293
-    /**
1294
-     * do_not_cache
1295
-     * sets no cache headers and defines no cache constants for WP plugins
1296
-     *
1297
-     * @access public
1298
-     * @return void
1299
-     */
1300
-    public static function do_not_cache()
1301
-    {
1302
-        // set no cache constants
1303
-        if (! defined('DONOTCACHEPAGE')) {
1304
-            define('DONOTCACHEPAGE', true);
1305
-        }
1306
-        if (! defined('DONOTCACHCEOBJECT')) {
1307
-            define('DONOTCACHCEOBJECT', true);
1308
-        }
1309
-        if (! defined('DONOTCACHEDB')) {
1310
-            define('DONOTCACHEDB', true);
1311
-        }
1312
-        // add no cache headers
1313
-        add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1314
-        // plus a little extra for nginx and Google Chrome
1315
-        add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1316
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1317
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1318
-    }
1319
-
1320
-
1321
-    /**
1322
-     *    extra_nocache_headers
1323
-     *
1324
-     * @access    public
1325
-     * @param $headers
1326
-     * @return    array
1327
-     */
1328
-    public static function extra_nocache_headers($headers)
1329
-    {
1330
-        // for NGINX
1331
-        $headers['X-Accel-Expires'] = 0;
1332
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1333
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1334
-        return $headers;
1335
-    }
1336
-
1337
-
1338
-    /**
1339
-     *    nocache_headers
1340
-     *
1341
-     * @access    public
1342
-     * @return    void
1343
-     */
1344
-    public static function nocache_headers()
1345
-    {
1346
-        nocache_headers();
1347
-    }
1348
-
1349
-
1350
-    /**
1351
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1352
-     * never returned with the function.
1353
-     *
1354
-     * @param  array $exclude_array any existing pages being excluded are in this array.
1355
-     * @return array
1356
-     */
1357
-    public function remove_pages_from_wp_list_pages($exclude_array)
1358
-    {
1359
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1360
-    }
1361
-
1362
-
1363
-    /**
1364
-     * Return whether blocks can be registered/loaded or not.
1365
-     * @return bool
1366
-     */
1367
-    private function canLoadBlocks()
1368
-    {
1369
-        return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1370
-               && function_exists('register_block_type')
1371
-               // don't load blocks if in the Divi page builder editor context
1372
-               // @see https://github.com/eventespresso/event-espresso-core/issues/814
1373
-               && ! $this->request->getRequestParam('et_fb', false);
1374
-    }
30
+	/**
31
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
32
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
33
+	 */
34
+	const req_type_normal = 0;
35
+
36
+	/**
37
+	 * Indicates this is a brand new installation of EE so we should install
38
+	 * tables and default data etc
39
+	 */
40
+	const req_type_new_activation = 1;
41
+
42
+	/**
43
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
44
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
45
+	 * and that default data is setup too
46
+	 */
47
+	const req_type_reactivation = 2;
48
+
49
+	/**
50
+	 * indicates that EE has been upgraded since its previous request.
51
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
52
+	 */
53
+	const req_type_upgrade = 3;
54
+
55
+	/**
56
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
57
+	 */
58
+	const req_type_downgrade = 4;
59
+
60
+	/**
61
+	 * @deprecated since version 4.6.0.dev.006
62
+	 * Now whenever a new_activation is detected the request type is still just
63
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we'r ein maintenance mode
64
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
65
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
66
+	 * (Specifically, when the migration manager indicates migrations are finished
67
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
68
+	 */
69
+	const req_type_activation_but_not_installed = 5;
70
+
71
+	/**
72
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
73
+	 */
74
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
75
+
76
+	/**
77
+	 * @var EE_System $_instance
78
+	 */
79
+	private static $_instance;
80
+
81
+	/**
82
+	 * @var EE_Registry $registry
83
+	 */
84
+	private $registry;
85
+
86
+	/**
87
+	 * @var LoaderInterface $loader
88
+	 */
89
+	private $loader;
90
+
91
+	/**
92
+	 * @var EE_Capabilities $capabilities
93
+	 */
94
+	private $capabilities;
95
+
96
+	/**
97
+	 * @var RequestInterface $request
98
+	 */
99
+	private $request;
100
+
101
+	/**
102
+	 * @var EE_Maintenance_Mode $maintenance_mode
103
+	 */
104
+	private $maintenance_mode;
105
+
106
+	/**
107
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
108
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
109
+	 *
110
+	 * @var int $_req_type
111
+	 */
112
+	private $_req_type;
113
+
114
+	/**
115
+	 * Whether or not there was a non-micro version change in EE core version during this request
116
+	 *
117
+	 * @var boolean $_major_version_change
118
+	 */
119
+	private $_major_version_change = false;
120
+
121
+	/**
122
+	 * A Context DTO dedicated solely to identifying the current request type.
123
+	 *
124
+	 * @var RequestTypeContextCheckerInterface $request_type
125
+	 */
126
+	private $request_type;
127
+
128
+	/**
129
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
130
+	 */
131
+	private $register_custom_post_types;
132
+
133
+	/**
134
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
135
+	 */
136
+	private $register_custom_taxonomies;
137
+
138
+	/**
139
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
140
+	 */
141
+	private $register_custom_taxonomy_terms;
142
+
143
+	/**
144
+	 * @singleton method used to instantiate class object
145
+	 * @param EE_Registry|null         $registry
146
+	 * @param LoaderInterface|null     $loader
147
+	 * @param RequestInterface|null    $request
148
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
149
+	 * @return EE_System
150
+	 */
151
+	public static function instance(
152
+		EE_Registry $registry = null,
153
+		LoaderInterface $loader = null,
154
+		RequestInterface $request = null,
155
+		EE_Maintenance_Mode $maintenance_mode = null
156
+	) {
157
+		// check if class object is instantiated
158
+		if (! self::$_instance instanceof EE_System) {
159
+			self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160
+		}
161
+		return self::$_instance;
162
+	}
163
+
164
+
165
+	/**
166
+	 * resets the instance and returns it
167
+	 *
168
+	 * @return EE_System
169
+	 */
170
+	public static function reset()
171
+	{
172
+		self::$_instance->_req_type = null;
173
+		// make sure none of the old hooks are left hanging around
174
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
175
+		// we need to reset the migration manager in order for it to detect DMSs properly
176
+		EE_Data_Migration_Manager::reset();
177
+		self::instance()->detect_activations_or_upgrades();
178
+		self::instance()->perform_activations_upgrades_and_migrations();
179
+		return self::instance();
180
+	}
181
+
182
+
183
+	/**
184
+	 * sets hooks for running rest of system
185
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
186
+	 * starting EE Addons from any other point may lead to problems
187
+	 *
188
+	 * @param EE_Registry         $registry
189
+	 * @param LoaderInterface     $loader
190
+	 * @param RequestInterface    $request
191
+	 * @param EE_Maintenance_Mode $maintenance_mode
192
+	 */
193
+	private function __construct(
194
+		EE_Registry $registry,
195
+		LoaderInterface $loader,
196
+		RequestInterface $request,
197
+		EE_Maintenance_Mode $maintenance_mode
198
+	) {
199
+		$this->registry = $registry;
200
+		$this->loader = $loader;
201
+		$this->request = $request;
202
+		$this->maintenance_mode = $maintenance_mode;
203
+		do_action('AHEE__EE_System__construct__begin', $this);
204
+		add_action(
205
+			'AHEE__EE_Bootstrap__load_espresso_addons',
206
+			array($this, 'loadCapabilities'),
207
+			5
208
+		);
209
+		add_action(
210
+			'AHEE__EE_Bootstrap__load_espresso_addons',
211
+			array($this, 'loadCommandBus'),
212
+			7
213
+		);
214
+		add_action(
215
+			'AHEE__EE_Bootstrap__load_espresso_addons',
216
+			array($this, 'loadPluginApi'),
217
+			9
218
+		);
219
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
220
+		add_action(
221
+			'AHEE__EE_Bootstrap__load_espresso_addons',
222
+			array($this, 'load_espresso_addons')
223
+		);
224
+		// when an ee addon is activated, we want to call the core hook(s) again
225
+		// because the newly-activated addon didn't get a chance to run at all
226
+		add_action('activate_plugin', array($this, 'load_espresso_addons'), 1);
227
+		// detect whether install or upgrade
228
+		add_action(
229
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
230
+			array($this, 'detect_activations_or_upgrades'),
231
+			3
232
+		);
233
+		// load EE_Config, EE_Textdomain, etc
234
+		add_action(
235
+			'AHEE__EE_Bootstrap__load_core_configuration',
236
+			array($this, 'load_core_configuration'),
237
+			5
238
+		);
239
+		// load specifications for matching routes to current request
240
+		add_action(
241
+			'AHEE__EE_Bootstrap__load_core_configuration',
242
+			array($this, 'loadRouteMatchSpecifications')
243
+		);
244
+		// load specifications for custom post types
245
+		add_action(
246
+			'AHEE__EE_Bootstrap__load_core_configuration',
247
+			array($this, 'loadCustomPostTypes')
248
+		);
249
+		// load EE_Config, EE_Textdomain, etc
250
+		add_action(
251
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
252
+			array($this, 'register_shortcodes_modules_and_widgets'),
253
+			7
254
+		);
255
+		// you wanna get going? I wanna get going... let's get going!
256
+		add_action(
257
+			'AHEE__EE_Bootstrap__brew_espresso',
258
+			array($this, 'brew_espresso'),
259
+			9
260
+		);
261
+		// other housekeeping
262
+		// exclude EE critical pages from wp_list_pages
263
+		add_filter(
264
+			'wp_list_pages_excludes',
265
+			array($this, 'remove_pages_from_wp_list_pages'),
266
+			10
267
+		);
268
+		// ALL EE Addons should use the following hook point to attach their initial setup too
269
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
270
+		do_action('AHEE__EE_System__construct__complete', $this);
271
+	}
272
+
273
+
274
+	/**
275
+	 * load and setup EE_Capabilities
276
+	 *
277
+	 * @return void
278
+	 * @throws EE_Error
279
+	 */
280
+	public function loadCapabilities()
281
+	{
282
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
283
+		add_action(
284
+			'AHEE__EE_Capabilities__init_caps__before_initialization',
285
+			function () {
286
+				LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287
+			}
288
+		);
289
+	}
290
+
291
+
292
+	/**
293
+	 * create and cache the CommandBus, and also add middleware
294
+	 * The CapChecker middleware requires the use of EE_Capabilities
295
+	 * which is why we need to load the CommandBus after Caps are set up
296
+	 *
297
+	 * @return void
298
+	 * @throws EE_Error
299
+	 */
300
+	public function loadCommandBus()
301
+	{
302
+		$this->loader->getShared(
303
+			'CommandBusInterface',
304
+			array(
305
+				null,
306
+				apply_filters(
307
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
308
+					array(
309
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
310
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
311
+					)
312
+				),
313
+			)
314
+		);
315
+	}
316
+
317
+
318
+	/**
319
+	 * @return void
320
+	 * @throws EE_Error
321
+	 */
322
+	public function loadPluginApi()
323
+	{
324
+		// set autoloaders for all of the classes implementing EEI_Plugin_API
325
+		// which provide helpers for EE plugin authors to more easily register certain components with EE.
326
+		EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
327
+	}
328
+
329
+
330
+	/**
331
+	 * @param string $addon_name
332
+	 * @param string $version_constant
333
+	 * @param string $min_version_required
334
+	 * @param string $load_callback
335
+	 * @param string $plugin_file_constant
336
+	 * @return void
337
+	 */
338
+	private function deactivateIncompatibleAddon(
339
+		$addon_name,
340
+		$version_constant,
341
+		$min_version_required,
342
+		$load_callback,
343
+		$plugin_file_constant
344
+	) {
345
+		if (! defined($version_constant)) {
346
+			return;
347
+		}
348
+		$addon_version = constant($version_constant);
349
+		if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350
+			remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
+			if (! function_exists('deactivate_plugins')) {
352
+				require_once ABSPATH . 'wp-admin/includes/plugin.php';
353
+			}
354
+			deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355
+			$this->request->unSetRequestParams(['activate', 'activate-multi'], true);
356
+			EE_Error::add_error(
357
+				sprintf(
358
+					esc_html__(
359
+						'We\'re sorry, but the Event Espresso %1$s addon was deactivated because version %2$s or higher is required with this version of Event Espresso core.',
360
+						'event_espresso'
361
+					),
362
+					$addon_name,
363
+					$min_version_required
364
+				),
365
+				__FILE__,
366
+				__FUNCTION__ . "({$addon_name})",
367
+				__LINE__
368
+			);
369
+			EE_Error::get_notices(false, true);
370
+		}
371
+	}
372
+
373
+
374
+	/**
375
+	 * load_espresso_addons
376
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
377
+	 * this is hooked into both:
378
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
379
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
380
+	 *    and the WP 'activate_plugin' hook point
381
+	 *
382
+	 * @access public
383
+	 * @return void
384
+	 */
385
+	public function load_espresso_addons()
386
+	{
387
+		$this->deactivateIncompatibleAddon(
388
+			'Wait Lists',
389
+			'EE_WAIT_LISTS_VERSION',
390
+			'1.0.0.beta.074',
391
+			'load_espresso_wait_lists',
392
+			'EE_WAIT_LISTS_PLUGIN_FILE'
393
+		);
394
+		$this->deactivateIncompatibleAddon(
395
+			'Automated Upcoming Event Notifications',
396
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_VERSION',
397
+			'1.0.0.beta.091',
398
+			'load_espresso_automated_upcoming_event_notification',
399
+			'EE_AUTOMATED_UPCOMING_EVENT_NOTIFICATION_PLUGIN_FILE'
400
+		);
401
+		do_action('AHEE__EE_System__load_espresso_addons');
402
+		// if the WP API basic auth plugin isn't already loaded, load it now.
403
+		// We want it for mobile apps. Just include the entire plugin
404
+		// also, don't load the basic auth when a plugin is getting activated, because
405
+		// it could be the basic auth plugin, and it doesn't check if its methods are already defined
406
+		// and causes a fatal error
407
+		if (
408
+			($this->request->isWordPressApi() || $this->request->isApi())
409
+			&& $this->request->getRequestParam('activate') !== 'true'
410
+			&& ! function_exists('json_basic_auth_handler')
411
+			&& ! function_exists('json_basic_auth_error')
412
+			&& ! in_array(
413
+				$this->request->getRequestParam('action'),
414
+				array('activate', 'activate-selected'),
415
+				true
416
+			)
417
+		) {
418
+			include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
419
+		}
420
+		do_action('AHEE__EE_System__load_espresso_addons__complete');
421
+	}
422
+
423
+
424
+	/**
425
+	 * detect_activations_or_upgrades
426
+	 * Checks for activation or upgrade of core first;
427
+	 * then also checks if any registered addons have been activated or upgraded
428
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
429
+	 * which runs during the WP 'plugins_loaded' action at priority 3
430
+	 *
431
+	 * @access public
432
+	 * @return void
433
+	 */
434
+	public function detect_activations_or_upgrades()
435
+	{
436
+		// first off: let's make sure to handle core
437
+		$this->detect_if_activation_or_upgrade();
438
+		foreach ($this->registry->addons as $addon) {
439
+			if ($addon instanceof EE_Addon) {
440
+				// detect teh request type for that addon
441
+				$addon->detect_req_type();
442
+			}
443
+		}
444
+	}
445
+
446
+
447
+	/**
448
+	 * detect_if_activation_or_upgrade
449
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
450
+	 * and either setting up the DB or setting up maintenance mode etc.
451
+	 *
452
+	 * @access public
453
+	 * @return void
454
+	 */
455
+	public function detect_if_activation_or_upgrade()
456
+	{
457
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
458
+		// check if db has been updated, or if its a brand-new installation
459
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
460
+		$request_type = $this->detect_req_type($espresso_db_update);
461
+		// EEH_Debug_Tools::printr( $request_type, '$request_type', __FILE__, __LINE__ );
462
+		switch ($request_type) {
463
+			case EE_System::req_type_new_activation:
464
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
465
+				$this->_handle_core_version_change($espresso_db_update);
466
+				break;
467
+			case EE_System::req_type_reactivation:
468
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
469
+				$this->_handle_core_version_change($espresso_db_update);
470
+				break;
471
+			case EE_System::req_type_upgrade:
472
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
473
+				// migrations may be required now that we've upgraded
474
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
475
+				$this->_handle_core_version_change($espresso_db_update);
476
+				break;
477
+			case EE_System::req_type_downgrade:
478
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
479
+				// its possible migrations are no longer required
480
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
481
+				$this->_handle_core_version_change($espresso_db_update);
482
+				break;
483
+			case EE_System::req_type_normal:
484
+			default:
485
+				break;
486
+		}
487
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
488
+	}
489
+
490
+
491
+	/**
492
+	 * Updates the list of installed versions and sets hooks for
493
+	 * initializing the database later during the request
494
+	 *
495
+	 * @param array $espresso_db_update
496
+	 */
497
+	private function _handle_core_version_change($espresso_db_update)
498
+	{
499
+		$this->update_list_of_installed_versions($espresso_db_update);
500
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
501
+		add_action(
502
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
503
+			array($this, 'initialize_db_if_no_migrations_required')
504
+		);
505
+	}
506
+
507
+
508
+	/**
509
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
510
+	 * information about what versions of EE have been installed and activated,
511
+	 * NOT necessarily the state of the database
512
+	 *
513
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
514
+	 *                                            If not supplied, fetches it from the options table
515
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
516
+	 */
517
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518
+	{
519
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
+		if (! $espresso_db_update) {
521
+			$espresso_db_update = get_option('espresso_db_update');
522
+		}
523
+		// check that option is an array
524
+		if (! is_array($espresso_db_update)) {
525
+			// if option is FALSE, then it never existed
526
+			if ($espresso_db_update === false) {
527
+				// make $espresso_db_update an array and save option with autoload OFF
528
+				$espresso_db_update = array();
529
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
530
+			} else {
531
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
532
+				$espresso_db_update = array($espresso_db_update => array());
533
+				update_option('espresso_db_update', $espresso_db_update);
534
+			}
535
+		} else {
536
+			$corrected_db_update = array();
537
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
538
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
539
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
540
+					// the key is an int, and the value IS NOT an array
541
+					// so it must be numerically-indexed, where values are versions installed...
542
+					// fix it!
543
+					$version_string = $should_be_array;
544
+					$corrected_db_update[ $version_string ] = array('unknown-date');
545
+				} else {
546
+					// ok it checks out
547
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
548
+				}
549
+			}
550
+			$espresso_db_update = $corrected_db_update;
551
+			update_option('espresso_db_update', $espresso_db_update);
552
+		}
553
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
554
+		return $espresso_db_update;
555
+	}
556
+
557
+
558
+	/**
559
+	 * Does the traditional work of setting up the plugin's database and adding default data.
560
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
561
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
562
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
563
+	 * so that it will be done when migrations are finished
564
+	 *
565
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
566
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
567
+	 *                                       This is a resource-intensive job
568
+	 *                                       so we prefer to only do it when necessary
569
+	 * @return void
570
+	 * @throws EE_Error
571
+	 */
572
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
573
+	{
574
+		$request_type = $this->detect_req_type();
575
+		// only initialize system if we're not in maintenance mode.
576
+		if ($this->maintenance_mode->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
577
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
578
+			$rewrite_rules = $this->loader->getShared(
579
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
580
+			);
581
+			$rewrite_rules->flush();
582
+			if ($verify_schema) {
583
+				EEH_Activation::initialize_db_and_folders();
584
+			}
585
+			EEH_Activation::initialize_db_content();
586
+			EEH_Activation::system_initialization();
587
+			if ($initialize_addons_too) {
588
+				$this->initialize_addons();
589
+			}
590
+		} else {
591
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
592
+		}
593
+		if (
594
+			$request_type === EE_System::req_type_new_activation
595
+			|| $request_type === EE_System::req_type_reactivation
596
+			|| (
597
+				$request_type === EE_System::req_type_upgrade
598
+				&& $this->is_major_version_change()
599
+			)
600
+		) {
601
+			add_action('AHEE__EE_System__initialize_last', array($this, 'redirect_to_about_ee'), 9);
602
+		}
603
+	}
604
+
605
+
606
+	/**
607
+	 * Initializes the db for all registered addons
608
+	 *
609
+	 * @throws EE_Error
610
+	 */
611
+	public function initialize_addons()
612
+	{
613
+		// foreach registered addon, make sure its db is up-to-date too
614
+		foreach ($this->registry->addons as $addon) {
615
+			if ($addon instanceof EE_Addon) {
616
+				$addon->initialize_db_if_no_migrations_required();
617
+			}
618
+		}
619
+	}
620
+
621
+
622
+	/**
623
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
624
+	 *
625
+	 * @param    array  $version_history
626
+	 * @param    string $current_version_to_add version to be added to the version history
627
+	 * @return    boolean success as to whether or not this option was changed
628
+	 */
629
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630
+	{
631
+		if (! $version_history) {
632
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
633
+		}
634
+		if ($current_version_to_add === null) {
635
+			$current_version_to_add = espresso_version();
636
+		}
637
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
638
+		// re-save
639
+		return update_option('espresso_db_update', $version_history);
640
+	}
641
+
642
+
643
+	/**
644
+	 * Detects if the current version indicated in the has existed in the list of
645
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
646
+	 *
647
+	 * @param array $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
648
+	 *                                  If not supplied, fetches it from the options table.
649
+	 *                                  Also, caches its result so later parts of the code can also know whether
650
+	 *                                  there's been an update or not. This way we can add the current version to
651
+	 *                                  espresso_db_update, but still know if this is a new install or not
652
+	 * @return int one of the constants on EE_System::req_type_
653
+	 */
654
+	public function detect_req_type($espresso_db_update = null)
655
+	{
656
+		if ($this->_req_type === null) {
657
+			$espresso_db_update = ! empty($espresso_db_update)
658
+				? $espresso_db_update
659
+				: $this->fix_espresso_db_upgrade_option();
660
+			$this->_req_type = EE_System::detect_req_type_given_activation_history(
661
+				$espresso_db_update,
662
+				'ee_espresso_activation',
663
+				espresso_version()
664
+			);
665
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
666
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
667
+		}
668
+		return $this->_req_type;
669
+	}
670
+
671
+
672
+	/**
673
+	 * Returns whether or not there was a non-micro version change (ie, change in either
674
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
675
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
676
+	 *
677
+	 * @param $activation_history
678
+	 * @return bool
679
+	 */
680
+	private function _detect_major_version_change($activation_history)
681
+	{
682
+		$previous_version = EE_System::_get_most_recently_active_version_from_activation_history($activation_history);
683
+		$previous_version_parts = explode('.', $previous_version);
684
+		$current_version_parts = explode('.', espresso_version());
685
+		return isset($previous_version_parts[0], $previous_version_parts[1], $current_version_parts[0], $current_version_parts[1])
686
+			   && ($previous_version_parts[0] !== $current_version_parts[0]
687
+				   || $previous_version_parts[1] !== $current_version_parts[1]
688
+			   );
689
+	}
690
+
691
+
692
+	/**
693
+	 * Returns true if either the major or minor version of EE changed during this request.
694
+	 * Eg 4.9.0.rc.001 to 4.10.0.rc.000, but not 4.9.0.rc.0001 to 4.9.1.rc.0001
695
+	 *
696
+	 * @return bool
697
+	 */
698
+	public function is_major_version_change()
699
+	{
700
+		return $this->_major_version_change;
701
+	}
702
+
703
+
704
+	/**
705
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
706
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
707
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
708
+	 * just activated to (for core that will always be espresso_version())
709
+	 *
710
+	 * @param array  $activation_history_for_addon     the option's value which stores the activation history for this
711
+	 *                                                 ee plugin. for core that's 'espresso_db_update'
712
+	 * @param string $activation_indicator_option_name the name of the WordPress option that is temporarily set to
713
+	 *                                                 indicate that this plugin was just activated
714
+	 * @param string $version_to_upgrade_to            the version that was just upgraded to (for core that will be
715
+	 *                                                 espresso_version())
716
+	 * @return int one of the constants on EE_System::req_type_*
717
+	 */
718
+	public static function detect_req_type_given_activation_history(
719
+		$activation_history_for_addon,
720
+		$activation_indicator_option_name,
721
+		$version_to_upgrade_to
722
+	) {
723
+		$version_is_higher = self::_new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to);
724
+		if ($activation_history_for_addon) {
725
+			// it exists, so this isn't a completely new install
726
+			// check if this version already in that list of previously installed versions
727
+			if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
728
+				// it a version we haven't seen before
729
+				if ($version_is_higher === 1) {
730
+					$req_type = EE_System::req_type_upgrade;
731
+				} else {
732
+					$req_type = EE_System::req_type_downgrade;
733
+				}
734
+				delete_option($activation_indicator_option_name);
735
+			} else {
736
+				// its not an update. maybe a reactivation?
737
+				if (get_option($activation_indicator_option_name, false)) {
738
+					if ($version_is_higher === -1) {
739
+						$req_type = EE_System::req_type_downgrade;
740
+					} elseif ($version_is_higher === 0) {
741
+						// we've seen this version before, but it's an activation. must be a reactivation
742
+						$req_type = EE_System::req_type_reactivation;
743
+					} else {// $version_is_higher === 1
744
+						$req_type = EE_System::req_type_upgrade;
745
+					}
746
+					delete_option($activation_indicator_option_name);
747
+				} else {
748
+					// we've seen this version before and the activation indicate doesn't show it was just activated
749
+					if ($version_is_higher === -1) {
750
+						$req_type = EE_System::req_type_downgrade;
751
+					} elseif ($version_is_higher === 0) {
752
+						// we've seen this version before and it's not an activation. its normal request
753
+						$req_type = EE_System::req_type_normal;
754
+					} else {// $version_is_higher === 1
755
+						$req_type = EE_System::req_type_upgrade;
756
+					}
757
+				}
758
+			}
759
+		} else {
760
+			// brand new install
761
+			$req_type = EE_System::req_type_new_activation;
762
+			delete_option($activation_indicator_option_name);
763
+		}
764
+		return $req_type;
765
+	}
766
+
767
+
768
+	/**
769
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
770
+	 * the $activation_history_for_addon
771
+	 *
772
+	 * @param array  $activation_history_for_addon (keys are versions, values are arrays of times activated,
773
+	 *                                             sometimes containing 'unknown-date'
774
+	 * @param string $version_to_upgrade_to        (current version)
775
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
776
+	 *                                             ie, -1 if $version_to_upgrade_to is LOWER (downgrade);
777
+	 *                                             0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
778
+	 *                                             1 if $version_to_upgrade_to is HIGHER (upgrade) ;
779
+	 */
780
+	private static function _new_version_is_higher($activation_history_for_addon, $version_to_upgrade_to)
781
+	{
782
+		// find the most recently-activated version
783
+		$most_recently_active_version =
784
+			EE_System::_get_most_recently_active_version_from_activation_history($activation_history_for_addon);
785
+		return version_compare($version_to_upgrade_to, $most_recently_active_version);
786
+	}
787
+
788
+
789
+	/**
790
+	 * Gets the most recently active version listed in the activation history,
791
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
792
+	 *
793
+	 * @param array $activation_history  (keys are versions, values are arrays of times activated,
794
+	 *                                   sometimes containing 'unknown-date'
795
+	 * @return string
796
+	 */
797
+	private static function _get_most_recently_active_version_from_activation_history($activation_history)
798
+	{
799
+		$most_recently_active_version_activation = '1970-01-01 00:00:00';
800
+		$most_recently_active_version = '0.0.0.dev.000';
801
+		if (is_array($activation_history)) {
802
+			foreach ($activation_history as $version => $times_activated) {
803
+				// check there is a record of when this version was activated. Otherwise,
804
+				// mark it as unknown
805
+				if (! $times_activated) {
806
+					$times_activated = array('unknown-date');
807
+				}
808
+				if (is_string($times_activated)) {
809
+					$times_activated = array($times_activated);
810
+				}
811
+				foreach ($times_activated as $an_activation) {
812
+					if (
813
+						$an_activation !== 'unknown-date'
814
+						&& $an_activation
815
+						   > $most_recently_active_version_activation
816
+					) {
817
+						$most_recently_active_version = $version;
818
+						$most_recently_active_version_activation = $an_activation === 'unknown-date'
819
+							? '1970-01-01 00:00:00'
820
+							: $an_activation;
821
+					}
822
+				}
823
+			}
824
+		}
825
+		return $most_recently_active_version;
826
+	}
827
+
828
+
829
+	/**
830
+	 * This redirects to the about EE page after activation
831
+	 *
832
+	 * @return void
833
+	 */
834
+	public function redirect_to_about_ee()
835
+	{
836
+		$notices = EE_Error::get_notices(false);
837
+		// if current user is an admin and it's not an ajax or rest request
838
+		if (
839
+			! isset($notices['errors'])
840
+			&& $this->request->isAdmin()
841
+			&& apply_filters(
842
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
843
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
844
+			)
845
+		) {
846
+			$query_params = array('page' => 'espresso_about');
847
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
848
+				$query_params['new_activation'] = true;
849
+			}
850
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
851
+				$query_params['reactivation'] = true;
852
+			}
853
+			$url = add_query_arg($query_params, admin_url('admin.php'));
854
+			wp_safe_redirect($url);
855
+			exit();
856
+		}
857
+	}
858
+
859
+
860
+	/**
861
+	 * load_core_configuration
862
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
863
+	 * which runs during the WP 'plugins_loaded' action at priority 5
864
+	 *
865
+	 * @return void
866
+	 * @throws ReflectionException
867
+	 * @throws Exception
868
+	 */
869
+	public function load_core_configuration()
870
+	{
871
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
872
+		$this->loader->getShared('EE_Load_Textdomain');
873
+		// load textdomain
874
+		EE_Load_Textdomain::load_textdomain();
875
+		// load caf stuff a chance to play during the activation process too.
876
+		$this->_maybe_brew_regular();
877
+		// load and setup EE_Config and EE_Network_Config
878
+		$config = $this->loader->getShared('EE_Config');
879
+		$this->loader->getShared('EE_Network_Config');
880
+		// setup autoloaders
881
+		// enable logging?
882
+		if ($config->admin->use_remote_logging) {
883
+			$this->loader->getShared('EE_Log');
884
+		}
885
+		// check for activation errors
886
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
887
+		if ($activation_errors) {
888
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
889
+			update_option('ee_plugin_activation_errors', false);
890
+		}
891
+		// get model names
892
+		$this->_parse_model_names();
893
+		// configure custom post type definitions
894
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
895
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
896
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
897
+	}
898
+
899
+
900
+	/**
901
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
902
+	 *
903
+	 * @return void
904
+	 * @throws ReflectionException
905
+	 */
906
+	private function _parse_model_names()
907
+	{
908
+		// get all the files in the EE_MODELS folder that end in .model.php
909
+		$models = glob(EE_MODELS . '*.model.php');
910
+		$model_names = array();
911
+		$non_abstract_db_models = array();
912
+		foreach ($models as $model) {
913
+			// get model classname
914
+			$classname = EEH_File::get_classname_from_filepath_with_standard_filename($model);
915
+			$short_name = str_replace('EEM_', '', $classname);
916
+			$reflectionClass = new ReflectionClass($classname);
917
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
+				$non_abstract_db_models[ $short_name ] = $classname;
919
+			}
920
+			$model_names[ $short_name ] = $classname;
921
+		}
922
+		$this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923
+		$this->registry->non_abstract_db_models = apply_filters(
924
+			'FHEE__EE_System__parse_implemented_model_names',
925
+			$non_abstract_db_models
926
+		);
927
+	}
928
+
929
+
930
+	/**
931
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
932
+	 * that need to be setup before our EE_System launches.
933
+	 *
934
+	 * @return void
935
+	 * @throws DomainException
936
+	 * @throws InvalidArgumentException
937
+	 * @throws InvalidDataTypeException
938
+	 * @throws InvalidInterfaceException
939
+	 * @throws InvalidClassException
940
+	 * @throws InvalidFilePathException
941
+	 */
942
+	private function _maybe_brew_regular()
943
+	{
944
+		/** @var Domain $domain */
945
+		$domain = DomainFactory::getShared(
946
+			new FullyQualifiedName(
947
+				'EventEspresso\core\domain\Domain'
948
+			),
949
+			array(
950
+				new FilePath(EVENT_ESPRESSO_MAIN_FILE),
951
+				Version::fromString(espresso_version()),
952
+			)
953
+		);
954
+		if ($domain->isCaffeinated()) {
955
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
956
+		}
957
+	}
958
+
959
+
960
+	/**
961
+	 * @since 4.9.71.p
962
+	 * @throws Exception
963
+	 */
964
+	public function loadRouteMatchSpecifications()
965
+	{
966
+		try {
967
+			$this->loader->getShared(
968
+				'EventEspresso\core\services\route_match\RouteMatchSpecificationManager'
969
+			);
970
+		} catch (Exception $exception) {
971
+			new ExceptionStackTraceDisplay($exception);
972
+		}
973
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
974
+	}
975
+
976
+
977
+	/**
978
+	 * loading CPT related classes earlier so that their definitions are available
979
+	 * but not performing any actual registration with WP core until load_CPTs_and_session() is called
980
+	 *
981
+	 * @since   4.10.21.p
982
+	 */
983
+	public function loadCustomPostTypes()
984
+	{
985
+		$this->register_custom_taxonomies = $this->loader->getShared(
986
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
987
+		);
988
+		$this->register_custom_post_types = $this->loader->getShared(
989
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
990
+		);
991
+		$this->register_custom_taxonomy_terms = $this->loader->getShared(
992
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
993
+		);
994
+		// integrate WP_Query with the EE models
995
+		$this->loader->getShared('EE_CPT_Strategy');
996
+		// load legacy EE_Request_Handler in case add-ons still need it
997
+		$this->loader->getShared('EE_Request_Handler');
998
+	}
999
+
1000
+
1001
+	/**
1002
+	 * register_shortcodes_modules_and_widgets
1003
+	 * generate lists of shortcodes and modules, then verify paths and classes
1004
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
1005
+	 * which runs during the WP 'plugins_loaded' action at priority 7
1006
+	 *
1007
+	 * @access public
1008
+	 * @return void
1009
+	 * @throws Exception
1010
+	 */
1011
+	public function register_shortcodes_modules_and_widgets()
1012
+	{
1013
+		if ($this->request->isFrontend() || $this->request->isIframe() || $this->request->isAjax()) {
1014
+			// load, register, and add shortcodes the new way
1015
+			$this->loader->getShared('EventEspresso\core\services\shortcodes\ShortcodesManager');
1016
+		}
1017
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
1018
+		// check for addons using old hook point
1019
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
1020
+			$this->_incompatible_addon_error();
1021
+		}
1022
+	}
1023
+
1024
+
1025
+	/**
1026
+	 * _incompatible_addon_error
1027
+	 *
1028
+	 * @access public
1029
+	 * @return void
1030
+	 */
1031
+	private function _incompatible_addon_error()
1032
+	{
1033
+		// get array of classes hooking into here
1034
+		$class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036
+		);
1037
+		if (! empty($class_names)) {
1038
+			$msg = esc_html__(
1039
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040
+				'event_espresso'
1041
+			);
1042
+			$msg .= '<ul>';
1043
+			foreach ($class_names as $class_name) {
1044
+				$msg .= '<li><b>Event Espresso - '
1045
+						. str_replace(
1046
+							array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047
+							'',
1048
+							$class_name
1049
+						) . '</b></li>';
1050
+			}
1051
+			$msg .= '</ul>';
1052
+			$msg .= esc_html__(
1053
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1054
+				'event_espresso'
1055
+			);
1056
+			// save list of incompatible addons to wp-options for later use
1057
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1058
+			if (is_admin()) {
1059
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1060
+			}
1061
+		}
1062
+	}
1063
+
1064
+
1065
+	/**
1066
+	 * brew_espresso
1067
+	 * begins the process of setting hooks for initializing EE in the correct order
1068
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1069
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1070
+	 *
1071
+	 * @return void
1072
+	 */
1073
+	public function brew_espresso()
1074
+	{
1075
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1076
+		// load some final core systems
1077
+		add_action('init', array($this, 'set_hooks_for_core'), 1);
1078
+		add_action('init', array($this, 'perform_activations_upgrades_and_migrations'), 3);
1079
+		add_action('init', array($this, 'load_CPTs_and_session'), 5);
1080
+		add_action('init', array($this, 'load_controllers'), 7);
1081
+		add_action('init', array($this, 'core_loaded_and_ready'), 9);
1082
+		add_action('init', array($this, 'initialize'), 10);
1083
+		add_action('init', array($this, 'initialize_last'), 100);
1084
+		if (is_admin() && apply_filters('FHEE__EE_System__brew_espresso__load_pue', true)) {
1085
+			// pew pew pew
1086
+			$this->loader->getShared('EventEspresso\core\services\licensing\LicenseService');
1087
+			do_action('AHEE__EE_System__brew_espresso__after_pue_init');
1088
+		}
1089
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1090
+	}
1091
+
1092
+
1093
+	/**
1094
+	 *    set_hooks_for_core
1095
+	 *
1096
+	 * @access public
1097
+	 * @return    void
1098
+	 * @throws EE_Error
1099
+	 */
1100
+	public function set_hooks_for_core()
1101
+	{
1102
+		$this->_deactivate_incompatible_addons();
1103
+		do_action('AHEE__EE_System__set_hooks_for_core');
1104
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1105
+		// caps need to be initialized on every request so that capability maps are set.
1106
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1107
+		$this->registry->CAP->init_caps();
1108
+	}
1109
+
1110
+
1111
+	/**
1112
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1113
+	 * deactivates any addons considered incompatible with the current version of EE
1114
+	 */
1115
+	private function _deactivate_incompatible_addons()
1116
+	{
1117
+		$incompatible_addons = get_option('ee_incompatible_addons', array());
1118
+		if (! empty($incompatible_addons)) {
1119
+			$active_plugins = get_option('active_plugins', array());
1120
+			foreach ($active_plugins as $active_plugin) {
1121
+				foreach ($incompatible_addons as $incompatible_addon) {
1122
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1123
+						$this->request->unSetRequestParams(['activate'], true);
1124
+						espresso_deactivate_plugin($active_plugin);
1125
+					}
1126
+				}
1127
+			}
1128
+		}
1129
+	}
1130
+
1131
+
1132
+	/**
1133
+	 *    perform_activations_upgrades_and_migrations
1134
+	 *
1135
+	 * @access public
1136
+	 * @return    void
1137
+	 */
1138
+	public function perform_activations_upgrades_and_migrations()
1139
+	{
1140
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1141
+	}
1142
+
1143
+
1144
+	/**
1145
+	 * @return void
1146
+	 * @throws DomainException
1147
+	 */
1148
+	public function load_CPTs_and_session()
1149
+	{
1150
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1151
+		$this->register_custom_taxonomies->registerCustomTaxonomies();
1152
+		$this->register_custom_post_types->registerCustomPostTypes();
1153
+		$this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1154
+		// load legacy Custom Post Types and Taxonomies
1155
+		$this->loader->getShared('EE_Register_CPTs');
1156
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1157
+	}
1158
+
1159
+
1160
+	/**
1161
+	 * load_controllers
1162
+	 * this is the best place to load any additional controllers that needs access to EE core.
1163
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1164
+	 * time
1165
+	 *
1166
+	 * @access public
1167
+	 * @return void
1168
+	 */
1169
+	public function load_controllers()
1170
+	{
1171
+		do_action('AHEE__EE_System__load_controllers__start');
1172
+		// let's get it started
1173
+		if (
1174
+			! $this->maintenance_mode->level()
1175
+			&& ($this->request->isFrontend() || $this->request->isFrontAjax())
1176
+		) {
1177
+			do_action('AHEE__EE_System__load_controllers__load_front_controllers');
1178
+			$this->loader->getShared('EE_Front_Controller');
1179
+		} elseif ($this->request->isAdmin() || $this->request->isAdminAjax()) {
1180
+			do_action('AHEE__EE_System__load_controllers__load_admin_controllers');
1181
+			$this->loader->getShared('EE_Admin');
1182
+		} elseif ($this->request->isWordPressHeartbeat()) {
1183
+			$this->loader->getShared('EventEspresso\core\domain\services\admin\ajax\WordpressHeartbeat');
1184
+		}
1185
+		do_action('AHEE__EE_System__load_controllers__complete');
1186
+	}
1187
+
1188
+
1189
+	/**
1190
+	 * core_loaded_and_ready
1191
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1192
+	 *
1193
+	 * @access public
1194
+	 * @return void
1195
+	 * @throws Exception
1196
+	 */
1197
+	public function core_loaded_and_ready()
1198
+	{
1199
+		if (
1200
+			$this->request->isAdmin()
1201
+			|| $this->request->isFrontend()
1202
+			|| $this->request->isIframe()
1203
+			|| $this->request->isWordPressApi()
1204
+		) {
1205
+			try {
1206
+				$this->loader->getShared('EventEspresso\core\services\assets\Registry');
1207
+				$this->loader->getShared('EventEspresso\core\domain\services\assets\CoreAssetManager');
1208
+				if ($this->canLoadBlocks()) {
1209
+					$this->loader->getShared(
1210
+						'EventEspresso\core\services\editor\BlockRegistrationManager'
1211
+					);
1212
+				}
1213
+			} catch (Exception $exception) {
1214
+				new ExceptionStackTraceDisplay($exception);
1215
+			}
1216
+		}
1217
+		if (
1218
+			$this->request->isAdmin()
1219
+			|| $this->request->isEeAjax()
1220
+			|| $this->request->isFrontend()
1221
+		) {
1222
+			$this->loader->getShared('EE_Session');
1223
+		}
1224
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1225
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1226
+		// builders require these even on the front-end
1227
+		require_once EE_PUBLIC . 'template_tags.php';
1228
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229
+	}
1230
+
1231
+
1232
+	/**
1233
+	 * initialize
1234
+	 * this is the best place to begin initializing client code
1235
+	 *
1236
+	 * @access public
1237
+	 * @return void
1238
+	 */
1239
+	public function initialize()
1240
+	{
1241
+		do_action('AHEE__EE_System__initialize');
1242
+		add_filter(
1243
+			'safe_style_css',
1244
+			function ($styles) {
1245
+				$styles[] = 'display';
1246
+				$styles[] = 'visibility';
1247
+				return $styles;
1248
+			}
1249
+		);
1250
+	}
1251
+
1252
+
1253
+	/**
1254
+	 * initialize_last
1255
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1256
+	 * initialize has done so
1257
+	 *
1258
+	 * @access public
1259
+	 * @return void
1260
+	 */
1261
+	public function initialize_last()
1262
+	{
1263
+		do_action('AHEE__EE_System__initialize_last');
1264
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1265
+		$rewrite_rules = $this->loader->getShared(
1266
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1267
+		);
1268
+		$rewrite_rules->flushRewriteRules();
1269
+		add_action('admin_bar_init', array($this, 'addEspressoToolbar'));
1270
+		if (
1271
+			($this->request->isAjax() || $this->request->isAdmin())
1272
+			&& $this->maintenance_mode->models_can_query()
1273
+		) {
1274
+			$this->loader->getShared('EventEspresso\core\services\privacy\export\PersonalDataExporterManager');
1275
+			$this->loader->getShared('EventEspresso\core\services\privacy\erasure\PersonalDataEraserManager');
1276
+		}
1277
+	}
1278
+
1279
+
1280
+	/**
1281
+	 * @return void
1282
+	 * @throws EE_Error
1283
+	 */
1284
+	public function addEspressoToolbar()
1285
+	{
1286
+		$this->loader->getShared(
1287
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1288
+			array($this->registry->CAP)
1289
+		);
1290
+	}
1291
+
1292
+
1293
+	/**
1294
+	 * do_not_cache
1295
+	 * sets no cache headers and defines no cache constants for WP plugins
1296
+	 *
1297
+	 * @access public
1298
+	 * @return void
1299
+	 */
1300
+	public static function do_not_cache()
1301
+	{
1302
+		// set no cache constants
1303
+		if (! defined('DONOTCACHEPAGE')) {
1304
+			define('DONOTCACHEPAGE', true);
1305
+		}
1306
+		if (! defined('DONOTCACHCEOBJECT')) {
1307
+			define('DONOTCACHCEOBJECT', true);
1308
+		}
1309
+		if (! defined('DONOTCACHEDB')) {
1310
+			define('DONOTCACHEDB', true);
1311
+		}
1312
+		// add no cache headers
1313
+		add_action('send_headers', array('EE_System', 'nocache_headers'), 10);
1314
+		// plus a little extra for nginx and Google Chrome
1315
+		add_filter('nocache_headers', array('EE_System', 'extra_nocache_headers'), 10, 1);
1316
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1317
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1318
+	}
1319
+
1320
+
1321
+	/**
1322
+	 *    extra_nocache_headers
1323
+	 *
1324
+	 * @access    public
1325
+	 * @param $headers
1326
+	 * @return    array
1327
+	 */
1328
+	public static function extra_nocache_headers($headers)
1329
+	{
1330
+		// for NGINX
1331
+		$headers['X-Accel-Expires'] = 0;
1332
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1333
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1334
+		return $headers;
1335
+	}
1336
+
1337
+
1338
+	/**
1339
+	 *    nocache_headers
1340
+	 *
1341
+	 * @access    public
1342
+	 * @return    void
1343
+	 */
1344
+	public static function nocache_headers()
1345
+	{
1346
+		nocache_headers();
1347
+	}
1348
+
1349
+
1350
+	/**
1351
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1352
+	 * never returned with the function.
1353
+	 *
1354
+	 * @param  array $exclude_array any existing pages being excluded are in this array.
1355
+	 * @return array
1356
+	 */
1357
+	public function remove_pages_from_wp_list_pages($exclude_array)
1358
+	{
1359
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1360
+	}
1361
+
1362
+
1363
+	/**
1364
+	 * Return whether blocks can be registered/loaded or not.
1365
+	 * @return bool
1366
+	 */
1367
+	private function canLoadBlocks()
1368
+	{
1369
+		return apply_filters('FHEE__EE_System__canLoadBlocks', true)
1370
+			   && function_exists('register_block_type')
1371
+			   // don't load blocks if in the Divi page builder editor context
1372
+			   // @see https://github.com/eventespresso/event-espresso-core/issues/814
1373
+			   && ! $this->request->getRequestParam('et_fb', false);
1374
+	}
1375 1375
 }
Please login to merge, or discard this patch.
Spacing   +28 added lines, -28 removed lines patch added patch discarded remove patch
@@ -155,7 +155,7 @@  discard block
 block discarded – undo
155 155
         EE_Maintenance_Mode $maintenance_mode = null
156 156
     ) {
157 157
         // check if class object is instantiated
158
-        if (! self::$_instance instanceof EE_System) {
158
+        if ( ! self::$_instance instanceof EE_System) {
159 159
             self::$_instance = new self($registry, $loader, $request, $maintenance_mode);
160 160
         }
161 161
         return self::$_instance;
@@ -282,7 +282,7 @@  discard block
 block discarded – undo
282 282
         $this->capabilities = $this->loader->getShared('EE_Capabilities');
283 283
         add_action(
284 284
             'AHEE__EE_Capabilities__init_caps__before_initialization',
285
-            function () {
285
+            function() {
286 286
                 LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
287 287
             }
288 288
         );
@@ -323,7 +323,7 @@  discard block
 block discarded – undo
323 323
     {
324 324
         // set autoloaders for all of the classes implementing EEI_Plugin_API
325 325
         // which provide helpers for EE plugin authors to more easily register certain components with EE.
326
-        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES . 'plugin_api');
326
+        EEH_Autoloader::instance()->register_autoloaders_for_each_file_in_folder(EE_LIBRARIES.'plugin_api');
327 327
     }
328 328
 
329 329
 
@@ -342,14 +342,14 @@  discard block
 block discarded – undo
342 342
         $load_callback,
343 343
         $plugin_file_constant
344 344
     ) {
345
-        if (! defined($version_constant)) {
345
+        if ( ! defined($version_constant)) {
346 346
             return;
347 347
         }
348 348
         $addon_version = constant($version_constant);
349 349
         if ($addon_version && version_compare($addon_version, $min_version_required, '<')) {
350 350
             remove_action('AHEE__EE_System__load_espresso_addons', $load_callback);
351
-            if (! function_exists('deactivate_plugins')) {
352
-                require_once ABSPATH . 'wp-admin/includes/plugin.php';
351
+            if ( ! function_exists('deactivate_plugins')) {
352
+                require_once ABSPATH.'wp-admin/includes/plugin.php';
353 353
             }
354 354
             deactivate_plugins(plugin_basename(constant($plugin_file_constant)));
355 355
             $this->request->unSetRequestParams(['activate', 'activate-multi'], true);
@@ -363,7 +363,7 @@  discard block
 block discarded – undo
363 363
                     $min_version_required
364 364
                 ),
365 365
                 __FILE__,
366
-                __FUNCTION__ . "({$addon_name})",
366
+                __FUNCTION__."({$addon_name})",
367 367
                 __LINE__
368 368
             );
369 369
             EE_Error::get_notices(false, true);
@@ -415,7 +415,7 @@  discard block
 block discarded – undo
415 415
                 true
416 416
             )
417 417
         ) {
418
-            include_once EE_THIRD_PARTY . 'wp-api-basic-auth/basic-auth.php';
418
+            include_once EE_THIRD_PARTY.'wp-api-basic-auth/basic-auth.php';
419 419
         }
420 420
         do_action('AHEE__EE_System__load_espresso_addons__complete');
421 421
     }
@@ -517,11 +517,11 @@  discard block
 block discarded – undo
517 517
     private function fix_espresso_db_upgrade_option($espresso_db_update = null)
518 518
     {
519 519
         do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
520
-        if (! $espresso_db_update) {
520
+        if ( ! $espresso_db_update) {
521 521
             $espresso_db_update = get_option('espresso_db_update');
522 522
         }
523 523
         // check that option is an array
524
-        if (! is_array($espresso_db_update)) {
524
+        if ( ! is_array($espresso_db_update)) {
525 525
             // if option is FALSE, then it never existed
526 526
             if ($espresso_db_update === false) {
527 527
                 // make $espresso_db_update an array and save option with autoload OFF
@@ -541,10 +541,10 @@  discard block
 block discarded – undo
541 541
                     // so it must be numerically-indexed, where values are versions installed...
542 542
                     // fix it!
543 543
                     $version_string = $should_be_array;
544
-                    $corrected_db_update[ $version_string ] = array('unknown-date');
544
+                    $corrected_db_update[$version_string] = array('unknown-date');
545 545
                 } else {
546 546
                     // ok it checks out
547
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
547
+                    $corrected_db_update[$should_be_version_string] = $should_be_array;
548 548
                 }
549 549
             }
550 550
             $espresso_db_update = $corrected_db_update;
@@ -628,13 +628,13 @@  discard block
 block discarded – undo
628 628
      */
629 629
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
630 630
     {
631
-        if (! $version_history) {
631
+        if ( ! $version_history) {
632 632
             $version_history = $this->fix_espresso_db_upgrade_option($version_history);
633 633
         }
634 634
         if ($current_version_to_add === null) {
635 635
             $current_version_to_add = espresso_version();
636 636
         }
637
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
637
+        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
638 638
         // re-save
639 639
         return update_option('espresso_db_update', $version_history);
640 640
     }
@@ -724,7 +724,7 @@  discard block
 block discarded – undo
724 724
         if ($activation_history_for_addon) {
725 725
             // it exists, so this isn't a completely new install
726 726
             // check if this version already in that list of previously installed versions
727
-            if (! isset($activation_history_for_addon[ $version_to_upgrade_to ])) {
727
+            if ( ! isset($activation_history_for_addon[$version_to_upgrade_to])) {
728 728
                 // it a version we haven't seen before
729 729
                 if ($version_is_higher === 1) {
730 730
                     $req_type = EE_System::req_type_upgrade;
@@ -802,7 +802,7 @@  discard block
 block discarded – undo
802 802
             foreach ($activation_history as $version => $times_activated) {
803 803
                 // check there is a record of when this version was activated. Otherwise,
804 804
                 // mark it as unknown
805
-                if (! $times_activated) {
805
+                if ( ! $times_activated) {
806 806
                     $times_activated = array('unknown-date');
807 807
                 }
808 808
                 if (is_string($times_activated)) {
@@ -906,7 +906,7 @@  discard block
 block discarded – undo
906 906
     private function _parse_model_names()
907 907
     {
908 908
         // get all the files in the EE_MODELS folder that end in .model.php
909
-        $models = glob(EE_MODELS . '*.model.php');
909
+        $models = glob(EE_MODELS.'*.model.php');
910 910
         $model_names = array();
911 911
         $non_abstract_db_models = array();
912 912
         foreach ($models as $model) {
@@ -915,9 +915,9 @@  discard block
 block discarded – undo
915 915
             $short_name = str_replace('EEM_', '', $classname);
916 916
             $reflectionClass = new ReflectionClass($classname);
917 917
             if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
918
-                $non_abstract_db_models[ $short_name ] = $classname;
918
+                $non_abstract_db_models[$short_name] = $classname;
919 919
             }
920
-            $model_names[ $short_name ] = $classname;
920
+            $model_names[$short_name] = $classname;
921 921
         }
922 922
         $this->registry->models = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
923 923
         $this->registry->non_abstract_db_models = apply_filters(
@@ -952,7 +952,7 @@  discard block
 block discarded – undo
952 952
             )
953 953
         );
954 954
         if ($domain->isCaffeinated()) {
955
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
955
+            require_once EE_CAFF_PATH.'brewing_regular.php';
956 956
         }
957 957
     }
958 958
 
@@ -1034,7 +1034,7 @@  discard block
 block discarded – undo
1034 1034
         $class_names = EEH_Class_Tools::get_class_names_for_all_callbacks_on_hook(
1035 1035
             'AHEE__EE_System__register_shortcodes_modules_and_addons'
1036 1036
         );
1037
-        if (! empty($class_names)) {
1037
+        if ( ! empty($class_names)) {
1038 1038
             $msg = esc_html__(
1039 1039
                 'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
1040 1040
                 'event_espresso'
@@ -1046,7 +1046,7 @@  discard block
 block discarded – undo
1046 1046
                             array('EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'),
1047 1047
                             '',
1048 1048
                             $class_name
1049
-                        ) . '</b></li>';
1049
+                        ).'</b></li>';
1050 1050
             }
1051 1051
             $msg .= '</ul>';
1052 1052
             $msg .= esc_html__(
@@ -1115,7 +1115,7 @@  discard block
 block discarded – undo
1115 1115
     private function _deactivate_incompatible_addons()
1116 1116
     {
1117 1117
         $incompatible_addons = get_option('ee_incompatible_addons', array());
1118
-        if (! empty($incompatible_addons)) {
1118
+        if ( ! empty($incompatible_addons)) {
1119 1119
             $active_plugins = get_option('active_plugins', array());
1120 1120
             foreach ($active_plugins as $active_plugin) {
1121 1121
                 foreach ($incompatible_addons as $incompatible_addon) {
@@ -1224,7 +1224,7 @@  discard block
 block discarded – undo
1224 1224
         do_action('AHEE__EE_System__core_loaded_and_ready');
1225 1225
         // always load template tags, because it's faster than checking if it's a front-end request, and many page
1226 1226
         // builders require these even on the front-end
1227
-        require_once EE_PUBLIC . 'template_tags.php';
1227
+        require_once EE_PUBLIC.'template_tags.php';
1228 1228
         do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1229 1229
     }
1230 1230
 
@@ -1241,7 +1241,7 @@  discard block
 block discarded – undo
1241 1241
         do_action('AHEE__EE_System__initialize');
1242 1242
         add_filter(
1243 1243
             'safe_style_css',
1244
-            function ($styles) {
1244
+            function($styles) {
1245 1245
                 $styles[] = 'display';
1246 1246
                 $styles[] = 'visibility';
1247 1247
                 return $styles;
@@ -1300,13 +1300,13 @@  discard block
 block discarded – undo
1300 1300
     public static function do_not_cache()
1301 1301
     {
1302 1302
         // set no cache constants
1303
-        if (! defined('DONOTCACHEPAGE')) {
1303
+        if ( ! defined('DONOTCACHEPAGE')) {
1304 1304
             define('DONOTCACHEPAGE', true);
1305 1305
         }
1306
-        if (! defined('DONOTCACHCEOBJECT')) {
1306
+        if ( ! defined('DONOTCACHCEOBJECT')) {
1307 1307
             define('DONOTCACHCEOBJECT', true);
1308 1308
         }
1309
-        if (! defined('DONOTCACHEDB')) {
1309
+        if ( ! defined('DONOTCACHEDB')) {
1310 1310
             define('DONOTCACHEDB', true);
1311 1311
         }
1312 1312
         // add no cache headers
Please login to merge, or discard this patch.
espresso.php 1 patch
Indentation   +80 added lines, -80 removed lines patch added patch discarded remove patch
@@ -38,103 +38,103 @@
 block discarded – undo
38 38
  * @since           4.0
39 39
  */
40 40
 if (function_exists('espresso_version')) {
41
-    if (! function_exists('espresso_duplicate_plugin_error')) {
42
-        /**
43
-         *    espresso_duplicate_plugin_error
44
-         *    displays if more than one version of EE is activated at the same time
45
-         */
46
-        function espresso_duplicate_plugin_error()
47
-        {
48
-            ?>
41
+	if (! function_exists('espresso_duplicate_plugin_error')) {
42
+		/**
43
+		 *    espresso_duplicate_plugin_error
44
+		 *    displays if more than one version of EE is activated at the same time
45
+		 */
46
+		function espresso_duplicate_plugin_error()
47
+		{
48
+			?>
49 49
             <div class="error">
50 50
                 <p>
51 51
                     <?php
52
-                    echo esc_html__(
53
-                        'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
-                        'event_espresso'
55
-                    ); ?>
52
+					echo esc_html__(
53
+						'Can not run multiple versions of Event Espresso! One version has been automatically deactivated. Please verify that you have the correct version you want still active.',
54
+						'event_espresso'
55
+					); ?>
56 56
                 </p>
57 57
             </div>
58 58
             <?php
59
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
60
-        }
61
-    }
62
-    add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
59
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
60
+		}
61
+	}
62
+	add_action('admin_notices', 'espresso_duplicate_plugin_error', 1);
63 63
 } else {
64
-    define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
-    if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
-        /**
67
-         * espresso_minimum_php_version_error
68
-         *
69
-         * @return void
70
-         */
71
-        function espresso_minimum_php_version_error()
72
-        {
73
-            ?>
64
+	define('EE_MIN_PHP_VER_REQUIRED', '5.6.2');
65
+	if (! version_compare(PHP_VERSION, EE_MIN_PHP_VER_REQUIRED, '>=')) {
66
+		/**
67
+		 * espresso_minimum_php_version_error
68
+		 *
69
+		 * @return void
70
+		 */
71
+		function espresso_minimum_php_version_error()
72
+		{
73
+			?>
74 74
             <div class="error">
75 75
                 <p>
76 76
                     <?php
77
-                    printf(
78
-                        esc_html__(
79
-                            'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
-                            'event_espresso'
81
-                        ),
82
-                        EE_MIN_PHP_VER_REQUIRED,
83
-                        PHP_VERSION,
84
-                        '<br/>',
85
-                        '<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
-                    );
87
-                    ?>
77
+					printf(
78
+						esc_html__(
79
+							'We\'re sorry, but Event Espresso requires PHP version %1$s or greater in order to operate. You are currently running version %2$s.%3$sIn order to update your version of PHP, you will need to contact your current hosting provider.%3$sFor information on stable PHP versions, please go to %4$s.',
80
+							'event_espresso'
81
+						),
82
+						EE_MIN_PHP_VER_REQUIRED,
83
+						PHP_VERSION,
84
+						'<br/>',
85
+						'<a href="http://php.net/downloads.php">http://php.net/downloads.php</a>'
86
+					);
87
+					?>
88 88
                 </p>
89 89
             </div>
90 90
             <?php
91
-            espresso_deactivate_plugin(plugin_basename(__FILE__));
92
-        }
91
+			espresso_deactivate_plugin(plugin_basename(__FILE__));
92
+		}
93 93
 
94
-        add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
-    } else {
96
-        define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
-        /**
98
-         * espresso_version
99
-         * Returns the plugin version
100
-         *
101
-         * @return string
102
-         */
103
-        function espresso_version()
104
-        {
105
-            return apply_filters('FHEE__espresso__espresso_version', '4.10.30.rc.011');
106
-        }
94
+		add_action('admin_notices', 'espresso_minimum_php_version_error', 1);
95
+	} else {
96
+		define('EVENT_ESPRESSO_MAIN_FILE', __FILE__);
97
+		/**
98
+		 * espresso_version
99
+		 * Returns the plugin version
100
+		 *
101
+		 * @return string
102
+		 */
103
+		function espresso_version()
104
+		{
105
+			return apply_filters('FHEE__espresso__espresso_version', '4.10.30.rc.011');
106
+		}
107 107
 
108
-        /**
109
-         * espresso_plugin_activation
110
-         * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
-         */
112
-        function espresso_plugin_activation()
113
-        {
114
-            update_option('ee_espresso_activation', true);
115
-        }
108
+		/**
109
+		 * espresso_plugin_activation
110
+		 * adds a wp-option to indicate that EE has been activated via the WP admin plugins page
111
+		 */
112
+		function espresso_plugin_activation()
113
+		{
114
+			update_option('ee_espresso_activation', true);
115
+		}
116 116
 
117
-        register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
117
+		register_activation_hook(EVENT_ESPRESSO_MAIN_FILE, 'espresso_plugin_activation');
118 118
 
119
-        require_once __DIR__ . '/core/bootstrap_espresso.php';
120
-        bootstrap_espresso();
121
-    }
119
+		require_once __DIR__ . '/core/bootstrap_espresso.php';
120
+		bootstrap_espresso();
121
+	}
122 122
 }
123 123
 if (! function_exists('espresso_deactivate_plugin')) {
124
-    /**
125
-     *    deactivate_plugin
126
-     * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
-     *
128
-     * @access public
129
-     * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
-     * @return    void
131
-     */
132
-    function espresso_deactivate_plugin($plugin_basename = '')
133
-    {
134
-        if (! function_exists('deactivate_plugins')) {
135
-            require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
-        }
137
-        unset($_GET['activate'], $_REQUEST['activate']);
138
-        deactivate_plugins($plugin_basename);
139
-    }
124
+	/**
125
+	 *    deactivate_plugin
126
+	 * usage:  espresso_deactivate_plugin( plugin_basename( __FILE__ ));
127
+	 *
128
+	 * @access public
129
+	 * @param string $plugin_basename - the results of plugin_basename( __FILE__ ) for the plugin's main file
130
+	 * @return    void
131
+	 */
132
+	function espresso_deactivate_plugin($plugin_basename = '')
133
+	{
134
+		if (! function_exists('deactivate_plugins')) {
135
+			require_once ABSPATH . 'wp-admin/includes/plugin.php';
136
+		}
137
+		unset($_GET['activate'], $_REQUEST['activate']);
138
+		deactivate_plugins($plugin_basename);
139
+	}
140 140
 }
141 141
\ No newline at end of file
Please login to merge, or discard this patch.