Completed
Branch master (6bdc59)
by
unknown
25:30 queued 20:54
created
core/CPTs/EE_CPT_Event_Strategy.core.php 2 patches
Indentation   +219 added lines, -219 removed lines patch added patch discarded remove patch
@@ -11,251 +11,251 @@
 block discarded – undo
11 11
  */
12 12
 class EE_CPT_Event_Strategy
13 13
 {
14
-    /**
15
-     * CPT details from CustomPostTypeDefinitions for specific post type
16
-     */
17
-    protected array $CPT;
14
+	/**
15
+	 * CPT details from CustomPostTypeDefinitions for specific post type
16
+	 */
17
+	protected array $CPT;
18 18
 
19
-    private string $current_time;
19
+	private string $current_time;
20 20
 
21
-    private string $datetime_table;
21
+	private string $datetime_table;
22 22
 
23
-    private string $event_table;
23
+	private string $event_table;
24 24
 
25
-    private string $event_table_pk;
25
+	private string $event_table_pk;
26 26
 
27
-    public EE_Template_Config $template_settings;
27
+	public EE_Template_Config $template_settings;
28 28
 
29 29
 
30
-    /**
31
-     * @param WP_Query           $wp_query
32
-     * @param array              $CPT
33
-     * @param EE_Template_Config $template_settings
34
-     * @throws EE_Error
35
-     * @throws ReflectionException
36
-     */
37
-    public function __construct(WP_Query $wp_query, array $CPT, EE_Template_Config $template_settings)
38
-    {
39
-        $this->CPT = $CPT;
40
-        $this->current_time      = current_time('mysql', true);
41
-        $this->datetime_table    = EEM_Datetime::instance()->table();
42
-        $this->event_table       = EEM_Event::instance()->table();
43
-        $this->event_table_pk    = EEM_Event::instance()->primary_key_name();
44
-        $this->template_settings = $template_settings;
30
+	/**
31
+	 * @param WP_Query           $wp_query
32
+	 * @param array              $CPT
33
+	 * @param EE_Template_Config $template_settings
34
+	 * @throws EE_Error
35
+	 * @throws ReflectionException
36
+	 */
37
+	public function __construct(WP_Query $wp_query, array $CPT, EE_Template_Config $template_settings)
38
+	{
39
+		$this->CPT = $CPT;
40
+		$this->current_time      = current_time('mysql', true);
41
+		$this->datetime_table    = EEM_Datetime::instance()->table();
42
+		$this->event_table       = EEM_Event::instance()->table();
43
+		$this->event_table_pk    = EEM_Event::instance()->primary_key_name();
44
+		$this->template_settings = $template_settings;
45 45
 
46
-        // !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
47
-        // here's the list of available filters in the WP_Query object
48
-        // 'posts_where'
49
-        // 'posts_where_paged'
50
-        // 'posts_groupby'
51
-        // 'posts_join_paged'
52
-        // 'posts_orderby'
53
-        // 'posts_distinct'
54
-        // 'post_limits'
55
-        // 'posts_fields'
56
-        // 'posts_join'
57
-        $this->_add_filters();
58
-        $wp_query->is_espresso_event_single   = is_singular()
59
-            && (
60
-                (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::EVENTS)
61
-                || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::EVENTS)
62
-            );
63
-        $wp_query->is_espresso_event_archive  = is_post_type_archive(EspressoPostType::EVENTS);
64
-        $wp_query->is_espresso_event_taxonomy = is_tax('espresso_event_categories');
65
-    }
46
+		// !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
47
+		// here's the list of available filters in the WP_Query object
48
+		// 'posts_where'
49
+		// 'posts_where_paged'
50
+		// 'posts_groupby'
51
+		// 'posts_join_paged'
52
+		// 'posts_orderby'
53
+		// 'posts_distinct'
54
+		// 'post_limits'
55
+		// 'posts_fields'
56
+		// 'posts_join'
57
+		$this->_add_filters();
58
+		$wp_query->is_espresso_event_single   = is_singular()
59
+			&& (
60
+				(isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::EVENTS)
61
+				|| (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::EVENTS)
62
+			);
63
+		$wp_query->is_espresso_event_archive  = is_post_type_archive(EspressoPostType::EVENTS);
64
+		$wp_query->is_espresso_event_taxonomy = is_tax('espresso_event_categories');
65
+	}
66 66
 
67 67
 
68
-    /**
69
-     * When an instance of this class is created, we add our filters
70
-     * (which will get removed in case the next call to get_posts ISN'T
71
-     * for event CPTs)
72
-     */
73
-    protected function _add_filters()
74
-    {
75
-        add_filter('posts_fields', [$this, 'posts_fields'], 1, 2);
76
-        add_filter('posts_join', [$this, 'posts_join'], 1, 2);
77
-        add_filter('posts_where', [$this, 'posts_where'], 10, 2);
78
-        // add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 );
79
-        add_filter('posts_orderby', [$this, 'posts_orderby'], 1, 2);
80
-        add_filter('posts_groupby', [$this, 'posts_groupby'], 1, 2);
81
-        add_action('the_post', [$this, 'the_post'], 1);
82
-    }
68
+	/**
69
+	 * When an instance of this class is created, we add our filters
70
+	 * (which will get removed in case the next call to get_posts ISN'T
71
+	 * for event CPTs)
72
+	 */
73
+	protected function _add_filters()
74
+	{
75
+		add_filter('posts_fields', [$this, 'posts_fields'], 1, 2);
76
+		add_filter('posts_join', [$this, 'posts_join'], 1, 2);
77
+		add_filter('posts_where', [$this, 'posts_where'], 10, 2);
78
+		// add_filter( 'the_posts', array( $this, 'the_posts' ), 1, 2 );
79
+		add_filter('posts_orderby', [$this, 'posts_orderby'], 1, 2);
80
+		add_filter('posts_groupby', [$this, 'posts_groupby'], 1, 2);
81
+		add_action('the_post', [$this, 'the_post'], 1);
82
+	}
83 83
 
84 84
 
85
-    /**
86
-     * public access to _remove_filters()
87
-     *
88
-     * @since 4.9.63.p
89
-     */
90
-    public function remove_filters()
91
-    {
92
-    }
85
+	/**
86
+	 * public access to _remove_filters()
87
+	 *
88
+	 * @since 4.9.63.p
89
+	 */
90
+	public function remove_filters()
91
+	{
92
+	}
93 93
 
94 94
 
95
-    /**
96
-     * @param string   $SQL
97
-     * @param WP_Query $wp_query
98
-     * @return    string
99
-     * @noinspection PhpUndefinedFieldInspection
100
-     */
101
-    public function posts_fields(string $SQL, WP_Query $wp_query): string
102
-    {
103
-        if (
104
-            (
105
-                $wp_query->is_espresso_event_single
106
-                || $wp_query->is_espresso_event_archive
107
-                || $wp_query->is_espresso_event_taxonomy
108
-            )
109
-            && $this->isEspressoEvent($wp_query)
110
-            && strpos($SQL, $this->datetime_table) === false
111
-        ) {
112
-            // adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
113
-            $SQL .= ", $this->datetime_table.* ";
114
-            if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) {
115
-                // because we only want to retrieve the next upcoming datetime for each event:
116
-                // add something like:
117
-                // ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date "
118
-                // to WP Query SELECT statement
119
-                $SQL .= ", MIN( $this->datetime_table.DTT_EVT_start ) as event_start_date ";
120
-            }
121
-        }
122
-        return $SQL;
123
-    }
95
+	/**
96
+	 * @param string   $SQL
97
+	 * @param WP_Query $wp_query
98
+	 * @return    string
99
+	 * @noinspection PhpUndefinedFieldInspection
100
+	 */
101
+	public function posts_fields(string $SQL, WP_Query $wp_query): string
102
+	{
103
+		if (
104
+			(
105
+				$wp_query->is_espresso_event_single
106
+				|| $wp_query->is_espresso_event_archive
107
+				|| $wp_query->is_espresso_event_taxonomy
108
+			)
109
+			&& $this->isEspressoEvent($wp_query)
110
+			&& strpos($SQL, $this->datetime_table) === false
111
+		) {
112
+			// adds something like ", wp_esp_datetime.* " to WP Query SELECT statement
113
+			$SQL .= ", $this->datetime_table.* ";
114
+			if ($wp_query->is_espresso_event_archive || $wp_query->is_espresso_event_taxonomy) {
115
+				// because we only want to retrieve the next upcoming datetime for each event:
116
+				// add something like:
117
+				// ", MIN( wp_esp_datetime.DTT_EVT_start ) as event_start_date "
118
+				// to WP Query SELECT statement
119
+				$SQL .= ", MIN( $this->datetime_table.DTT_EVT_start ) as event_start_date ";
120
+			}
121
+		}
122
+		return $SQL;
123
+	}
124 124
 
125 125
 
126
-    /**
127
-     * @param string   $SQL
128
-     * @param WP_Query $wp_query
129
-     * @return string
130
-     * @noinspection PhpUndefinedFieldInspection
131
-     */
132
-    public function posts_join(string $SQL, WP_Query $wp_query): string
133
-    {
134
-        if (
135
-            (
136
-                $wp_query->is_espresso_event_single
137
-                || $wp_query->is_espresso_event_archive
138
-                || $wp_query->is_espresso_event_taxonomy
139
-            )
140
-            && $this->isEspressoEvent($wp_query)
141
-            && strpos($SQL, $this->datetime_table) === false
142
-        ) {
143
-            // adds something like:
144
-            // " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) "
145
-            // to WP Query JOIN statement
146
-            $SQL .= " INNER JOIN $this->datetime_table";
147
-            $SQL .= " ON ( $this->event_table.ID = $this->datetime_table.$this->event_table_pk ) ";
148
-        }
149
-        return $SQL;
150
-    }
126
+	/**
127
+	 * @param string   $SQL
128
+	 * @param WP_Query $wp_query
129
+	 * @return string
130
+	 * @noinspection PhpUndefinedFieldInspection
131
+	 */
132
+	public function posts_join(string $SQL, WP_Query $wp_query): string
133
+	{
134
+		if (
135
+			(
136
+				$wp_query->is_espresso_event_single
137
+				|| $wp_query->is_espresso_event_archive
138
+				|| $wp_query->is_espresso_event_taxonomy
139
+			)
140
+			&& $this->isEspressoEvent($wp_query)
141
+			&& strpos($SQL, $this->datetime_table) === false
142
+		) {
143
+			// adds something like:
144
+			// " LEFT JOIN wp_esp_datetime ON ( wp_esp_datetime.EVT_ID = wp_posts.ID ) "
145
+			// to WP Query JOIN statement
146
+			$SQL .= " INNER JOIN $this->datetime_table";
147
+			$SQL .= " ON ( $this->event_table.ID = $this->datetime_table.$this->event_table_pk ) ";
148
+		}
149
+		return $SQL;
150
+	}
151 151
 
152 152
 
153
-    /**
154
-     * @param string   $SQL
155
-     * @param WP_Query $wp_query
156
-     * @return string
157
-     * @noinspection PhpUndefinedFieldInspection
158
-     */
159
-    public function posts_where(string $SQL, WP_Query $wp_query): string
160
-    {
161
-        if (
162
-            (
163
-                $wp_query->is_espresso_event_archive
164
-                || $wp_query->is_espresso_event_taxonomy
165
-            )
166
-            && $this->isEspressoEvent($wp_query)
167
-            && strpos($SQL, $this->datetime_table) === false
168
-        ) {
169
-            if (
170
-                ! isset($this->template_settings->EED_Events_Archive)
171
-                || ! isset($this->template_settings->EED_Events_Archive->display_expired_events)
172
-                || ! $this->template_settings->EED_Events_Archive->display_expired_events
173
-            ) {
174
-                $SQL .= " AND $this->datetime_table.DTT_EVT_end > '$this->current_time' ";
175
-            }
176
-            // exclude trashed datetimes
177
-            $SQL .= " AND $this->datetime_table.DTT_deleted = 0";
178
-        }
179
-        return $SQL;
180
-    }
153
+	/**
154
+	 * @param string   $SQL
155
+	 * @param WP_Query $wp_query
156
+	 * @return string
157
+	 * @noinspection PhpUndefinedFieldInspection
158
+	 */
159
+	public function posts_where(string $SQL, WP_Query $wp_query): string
160
+	{
161
+		if (
162
+			(
163
+				$wp_query->is_espresso_event_archive
164
+				|| $wp_query->is_espresso_event_taxonomy
165
+			)
166
+			&& $this->isEspressoEvent($wp_query)
167
+			&& strpos($SQL, $this->datetime_table) === false
168
+		) {
169
+			if (
170
+				! isset($this->template_settings->EED_Events_Archive)
171
+				|| ! isset($this->template_settings->EED_Events_Archive->display_expired_events)
172
+				|| ! $this->template_settings->EED_Events_Archive->display_expired_events
173
+			) {
174
+				$SQL .= " AND $this->datetime_table.DTT_EVT_end > '$this->current_time' ";
175
+			}
176
+			// exclude trashed datetimes
177
+			$SQL .= " AND $this->datetime_table.DTT_deleted = 0";
178
+		}
179
+		return $SQL;
180
+	}
181 181
 
182 182
 
183
-    /**
184
-     * @param string   $SQL
185
-     * @param WP_Query $wp_query
186
-     * @return string
187
-     * @noinspection PhpUndefinedFieldInspection
188
-     */
189
-    public function posts_orderby(string $SQL, WP_Query $wp_query): string
190
-    {
191
-        if (
192
-            (
193
-                $wp_query->is_espresso_event_archive
194
-                || $wp_query->is_espresso_event_taxonomy
195
-            )
196
-            && $this->isEspressoEvent($wp_query)
197
-            && strpos($SQL, 'event_start_date') === false
198
-        ) {
199
-            $SQL = ' event_start_date ASC ';
200
-        }
201
-        return $SQL;
202
-    }
183
+	/**
184
+	 * @param string   $SQL
185
+	 * @param WP_Query $wp_query
186
+	 * @return string
187
+	 * @noinspection PhpUndefinedFieldInspection
188
+	 */
189
+	public function posts_orderby(string $SQL, WP_Query $wp_query): string
190
+	{
191
+		if (
192
+			(
193
+				$wp_query->is_espresso_event_archive
194
+				|| $wp_query->is_espresso_event_taxonomy
195
+			)
196
+			&& $this->isEspressoEvent($wp_query)
197
+			&& strpos($SQL, 'event_start_date') === false
198
+		) {
199
+			$SQL = ' event_start_date ASC ';
200
+		}
201
+		return $SQL;
202
+	}
203 203
 
204 204
 
205
-    /**
206
-     * @param string   $SQL
207
-     * @param WP_Query $wp_query
208
-     * @return string
209
-     * @noinspection PhpUndefinedFieldInspection
210
-     */
211
-    public function posts_groupby(string $SQL, WP_Query $wp_query): string
212
-    {
213
-        global $wpdb;
214
-        if (
215
-            (
216
-                $wp_query->is_espresso_event_single
217
-                || $wp_query->is_espresso_event_archive
218
-                || $wp_query->is_espresso_event_taxonomy
219
-            )
220
-            && $this->isEspressoEvent($wp_query)
221
-            && strpos($SQL, "$wpdb->posts.ID") === false
222
-        ) {
223
-            // TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default)
224
-            // we're joining to the datetimes table, where there can be MANY datetimes for a single event,
225
-            // but we want to only show each event only once
226
-            // (whereas if we didn't group them by the post's ID, then we would end up with many repeats)
227
-            $SQL = "$wpdb->posts.ID ";
228
-        }
229
-        return $SQL;
230
-    }
205
+	/**
206
+	 * @param string   $SQL
207
+	 * @param WP_Query $wp_query
208
+	 * @return string
209
+	 * @noinspection PhpUndefinedFieldInspection
210
+	 */
211
+	public function posts_groupby(string $SQL, WP_Query $wp_query): string
212
+	{
213
+		global $wpdb;
214
+		if (
215
+			(
216
+				$wp_query->is_espresso_event_single
217
+				|| $wp_query->is_espresso_event_archive
218
+				|| $wp_query->is_espresso_event_taxonomy
219
+			)
220
+			&& $this->isEspressoEvent($wp_query)
221
+			&& strpos($SQL, "$wpdb->posts.ID") === false
222
+		) {
223
+			// TODO: add event list option for displaying ALL datetimes in event list or only primary datetime (default)
224
+			// we're joining to the datetimes table, where there can be MANY datetimes for a single event,
225
+			// but we want to only show each event only once
226
+			// (whereas if we didn't group them by the post's ID, then we would end up with many repeats)
227
+			$SQL = "$wpdb->posts.ID ";
228
+		}
229
+		return $SQL;
230
+	}
231 231
 
232 232
 
233
-    /**
234
-     * @param array    $posts
235
-     * @param WP_Query $wp_query
236
-     * @return array
237
-     */
238
-    public function the_posts(array $posts, WP_Query $wp_query): array
239
-    {
240
-        return $posts;
241
-    }
233
+	/**
234
+	 * @param array    $posts
235
+	 * @param WP_Query $wp_query
236
+	 * @return array
237
+	 */
238
+	public function the_posts(array $posts, WP_Query $wp_query): array
239
+	{
240
+		return $posts;
241
+	}
242 242
 
243 243
 
244
-    /**
245
-     * @param WP_Post $post The Post object (passed by reference).
246
-     * @throws EE_Error
247
-     * @throws ReflectionException
248
-     */
249
-    public function the_post(WP_Post &$post)
250
-    {
251
-        if ($post->post_type === EspressoPostType::EVENTS && ! isset($post->EE_Event)) {
252
-            $post->EE_Event = EEM_Event::instance()->get_one_by_ID($post->ID);
253
-        }
254
-    }
244
+	/**
245
+	 * @param WP_Post $post The Post object (passed by reference).
246
+	 * @throws EE_Error
247
+	 * @throws ReflectionException
248
+	 */
249
+	public function the_post(WP_Post &$post)
250
+	{
251
+		if ($post->post_type === EspressoPostType::EVENTS && ! isset($post->EE_Event)) {
252
+			$post->EE_Event = EEM_Event::instance()->get_one_by_ID($post->ID);
253
+		}
254
+	}
255 255
 
256 256
 
257
-    private function isEspressoEvent(WP_Query $wp_query): bool
258
-    {
259
-        return EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) === EspressoPostType::EVENTS;
260
-    }
257
+	private function isEspressoEvent(WP_Query $wp_query): bool
258
+	{
259
+		return EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) === EspressoPostType::EVENTS;
260
+	}
261 261
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -55,7 +55,7 @@  discard block
 block discarded – undo
55 55
         // 'posts_fields'
56 56
         // 'posts_join'
57 57
         $this->_add_filters();
58
-        $wp_query->is_espresso_event_single   = is_singular()
58
+        $wp_query->is_espresso_event_single = is_singular()
59 59
             && (
60 60
                 (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::EVENTS)
61 61
                 || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::EVENTS)
@@ -246,7 +246,7 @@  discard block
 block discarded – undo
246 246
      * @throws EE_Error
247 247
      * @throws ReflectionException
248 248
      */
249
-    public function the_post(WP_Post &$post)
249
+    public function the_post(WP_Post & $post)
250 250
     {
251 251
         if ($post->post_type === EspressoPostType::EVENTS && ! isset($post->EE_Event)) {
252 252
             $post->EE_Event = EEM_Event::instance()->get_one_by_ID($post->ID);
Please login to merge, or discard this patch.
core/CPTs/EE_CPT_Venue_Strategy.core.php 2 patches
Indentation   +42 added lines, -42 removed lines patch added patch discarded remove patch
@@ -11,50 +11,50 @@
 block discarded – undo
11 11
  */
12 12
 class EE_CPT_Venue_Strategy
13 13
 {
14
-    /**
15
-     * CPT details from CustomPostTypeDefinitions for specific post type
16
-     */
17
-    protected array $CPT;
14
+	/**
15
+	 * CPT details from CustomPostTypeDefinitions for specific post type
16
+	 */
17
+	protected array $CPT;
18 18
 
19 19
 
20
-    /**
21
-     * @param WP_Query $wp_query
22
-     * @param array    $CPT
23
-     */
24
-    public function __construct(WP_Query $wp_query, array $CPT = [])
25
-    {
26
-        $this->CPT = $CPT;
27
-        if (! $wp_query->is_tag) {
28
-            $wp_query->is_espresso_venue_single   = is_singular()
29
-                && (
30
-                    (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::VENUES)
31
-                    || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::VENUES)
32
-                );
33
-            $wp_query->is_espresso_venue_archive  = is_post_type_archive(EspressoPostType::VENUES);
34
-            $wp_query->is_espresso_venue_taxonomy = is_tax('espresso_venue_categories');
35
-        }
36
-        add_filter('the_posts', [$this, 'the_posts'], 1, 2);
37
-    }
20
+	/**
21
+	 * @param WP_Query $wp_query
22
+	 * @param array    $CPT
23
+	 */
24
+	public function __construct(WP_Query $wp_query, array $CPT = [])
25
+	{
26
+		$this->CPT = $CPT;
27
+		if (! $wp_query->is_tag) {
28
+			$wp_query->is_espresso_venue_single   = is_singular()
29
+				&& (
30
+					(isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::VENUES)
31
+					|| (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::VENUES)
32
+				);
33
+			$wp_query->is_espresso_venue_archive  = is_post_type_archive(EspressoPostType::VENUES);
34
+			$wp_query->is_espresso_venue_taxonomy = is_tax('espresso_venue_categories');
35
+		}
36
+		add_filter('the_posts', [$this, 'the_posts'], 1, 2);
37
+	}
38 38
 
39 39
 
40
-    /**
41
-     * @param array    $posts
42
-     * @param WP_Query $wp_query
43
-     * @return array
44
-     */
45
-    public function the_posts(array $posts, WP_Query $wp_query): array
46
-    {
47
-        if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::VENUES) {
48
-            return $posts;
49
-        }
50
-        // automagically load the EEH_Venue_View helper so that it's functions are available
51
-        if (
52
-            isset(EE_Registry::instance()->CFG->map_settings->use_google_maps)
53
-            && EE_Registry::instance()->CFG->map_settings->use_google_maps
54
-        ) {
55
-            EEH_Maps::espresso_google_map_js();
56
-        }
57
-        remove_filter('the_posts', [$this, 'the_posts'], 1);
58
-        return $posts;
59
-    }
40
+	/**
41
+	 * @param array    $posts
42
+	 * @param WP_Query $wp_query
43
+	 * @return array
44
+	 */
45
+	public function the_posts(array $posts, WP_Query $wp_query): array
46
+	{
47
+		if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== EspressoPostType::VENUES) {
48
+			return $posts;
49
+		}
50
+		// automagically load the EEH_Venue_View helper so that it's functions are available
51
+		if (
52
+			isset(EE_Registry::instance()->CFG->map_settings->use_google_maps)
53
+			&& EE_Registry::instance()->CFG->map_settings->use_google_maps
54
+		) {
55
+			EEH_Maps::espresso_google_map_js();
56
+		}
57
+		remove_filter('the_posts', [$this, 'the_posts'], 1);
58
+		return $posts;
59
+	}
60 60
 }
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -24,8 +24,8 @@
 block discarded – undo
24 24
     public function __construct(WP_Query $wp_query, array $CPT = [])
25 25
     {
26 26
         $this->CPT = $CPT;
27
-        if (! $wp_query->is_tag) {
28
-            $wp_query->is_espresso_venue_single   = is_singular()
27
+        if ( ! $wp_query->is_tag) {
28
+            $wp_query->is_espresso_venue_single = is_singular()
29 29
                 && (
30 30
                     (isset($wp_query->query->post_type) && $wp_query->query->post_type === EspressoPostType::VENUES)
31 31
                     || (isset($wp_query->query['post_type']) && $wp_query->query['post_type'] === EspressoPostType::VENUES)
Please login to merge, or discard this patch.
core/CPTs/CptQueryModifier.php 2 patches
Indentation   +474 added lines, -474 removed lines patch added patch discarded remove patch
@@ -31,495 +31,495 @@
 block discarded – undo
31 31
  */
32 32
 class CptQueryModifier
33 33
 {
34
-    protected CurrentPage $current_page;
34
+	protected CurrentPage $current_page;
35 35
 
36
-    protected LoaderInterface $loader;
37
-
38
-    protected RequestInterface $request;
39
-
40
-    protected WP_Query $wp_query;
41
-
42
-    protected ?EEM_CPT_Base $model = null;
36
+	protected LoaderInterface $loader;
37
+
38
+	protected RequestInterface $request;
39
+
40
+	protected WP_Query $wp_query;
41
+
42
+	protected ?EEM_CPT_Base $model = null;
43 43
 
44
-    /**
45
-     * meta table for the related CPT
46
-     */
47
-    protected ?EE_Secondary_Table $meta_table = null;
48
-
49
-    protected ?EE_Request_Handler $request_handler = null;
50
-
51
-    protected string $post_type = '';
44
+	/**
45
+	 * meta table for the related CPT
46
+	 */
47
+	protected ?EE_Secondary_Table $meta_table = null;
48
+
49
+	protected ?EE_Request_Handler $request_handler = null;
50
+
51
+	protected string $post_type = '';
52 52
 
53
-    /**
54
-     * @var EE_CPT_Attendee_Strategy|EE_CPT_Default_Strategy|EE_CPT_Event_Strategy|EE_CPT_Venue_Strategy|null
55
-     */
56
-    protected $cpt_strategy = null;
57
-
58
-    /**
59
-     * CPT details from CustomPostTypeDefinitions for specific post type
60
-     *
61
-     * @var array $cpt_details
62
-     */
63
-    protected array $cpt_details = [];
53
+	/**
54
+	 * @var EE_CPT_Attendee_Strategy|EE_CPT_Default_Strategy|EE_CPT_Event_Strategy|EE_CPT_Venue_Strategy|null
55
+	 */
56
+	protected $cpt_strategy = null;
57
+
58
+	/**
59
+	 * CPT details from CustomPostTypeDefinitions for specific post type
60
+	 *
61
+	 * @var array $cpt_details
62
+	 */
63
+	protected array $cpt_details = [];
64 64
 
65
-    /**
66
-     * @var EE_Table_Base[] $model_tables
67
-     */
68
-    protected array $model_tables = [];
65
+	/**
66
+	 * @var EE_Table_Base[] $model_tables
67
+	 */
68
+	protected array $model_tables = [];
69 69
 
70
-    protected array $taxonomies = [];
70
+	protected array $taxonomies = [];
71 71
 
72 72
 
73
-    /**
74
-     * CptQueryModifier constructor
75
-     *
76
-     * @param string           $post_type
77
-     * @param array            $cpt_details
78
-     * @param WP_Query         $wp_query
79
-     * @param CurrentPage      $current_page
80
-     * @param RequestInterface $request
81
-     * @param LoaderInterface  $loader
82
-     * @throws EE_Error
83
-     */
84
-    public function __construct(
85
-        string $post_type,
86
-        array $cpt_details,
87
-        WP_Query $wp_query,
88
-        CurrentPage $current_page,
89
-        RequestInterface $request,
90
-        LoaderInterface $loader
91
-    ) {
92
-        $this->loader       = $loader;
93
-        $this->request      = $request;
94
-        $this->current_page = $current_page;
95
-        $this->setWpQuery($wp_query);
96
-        $this->setPostType($post_type);
97
-        $this->setCptDetails($cpt_details);
98
-        $this->init();
99
-    }
73
+	/**
74
+	 * CptQueryModifier constructor
75
+	 *
76
+	 * @param string           $post_type
77
+	 * @param array            $cpt_details
78
+	 * @param WP_Query         $wp_query
79
+	 * @param CurrentPage      $current_page
80
+	 * @param RequestInterface $request
81
+	 * @param LoaderInterface  $loader
82
+	 * @throws EE_Error
83
+	 */
84
+	public function __construct(
85
+		string $post_type,
86
+		array $cpt_details,
87
+		WP_Query $wp_query,
88
+		CurrentPage $current_page,
89
+		RequestInterface $request,
90
+		LoaderInterface $loader
91
+	) {
92
+		$this->loader       = $loader;
93
+		$this->request      = $request;
94
+		$this->current_page = $current_page;
95
+		$this->setWpQuery($wp_query);
96
+		$this->setPostType($post_type);
97
+		$this->setCptDetails($cpt_details);
98
+		$this->init();
99
+	}
100 100
 
101 101
 
102
-    public function postType(): string
103
-    {
104
-        return $this->post_type;
105
-    }
102
+	public function postType(): string
103
+	{
104
+		return $this->post_type;
105
+	}
106 106
 
107 107
 
108
-    protected function setPostType(string $post_type)
109
-    {
110
-        $this->post_type = $post_type;
111
-    }
108
+	protected function setPostType(string $post_type)
109
+	{
110
+		$this->post_type = $post_type;
111
+	}
112 112
 
113 113
 
114
-    public function cptDetails(): array
115
-    {
116
-        return $this->cpt_details;
117
-    }
114
+	public function cptDetails(): array
115
+	{
116
+		return $this->cpt_details;
117
+	}
118 118
 
119 119
 
120
-    protected function setCptDetails(array $cpt_details)
121
-    {
122
-        $this->cpt_details = $cpt_details;
123
-    }
120
+	protected function setCptDetails(array $cpt_details)
121
+	{
122
+		$this->cpt_details = $cpt_details;
123
+	}
124 124
 
125 125
 
126
-    /**
127
-     * @return EE_Table_Base[]
128
-     */
129
-    public function modelTables(): array
130
-    {
131
-        return $this->model_tables;
132
-    }
133
-
134
-
135
-    /**
136
-     * @param EE_Table_Base[] $model_tables
137
-     */
138
-    protected function setModelTables(array $model_tables)
139
-    {
140
-        $this->model_tables = $model_tables;
141
-    }
142
-
143
-
144
-    public function taxonomies(): array
145
-    {
146
-        if (empty($this->taxonomies)) {
147
-            $this->initializeTaxonomies();
148
-        }
149
-        return $this->taxonomies;
150
-    }
151
-
152
-
153
-    protected function setTaxonomies(array $taxonomies)
154
-    {
155
-        $this->taxonomies = $taxonomies;
156
-    }
157
-
158
-
159
-    public function metaTable(): ?EE_Secondary_Table
160
-    {
161
-        return $this->meta_table;
162
-    }
163
-
164
-
165
-    public function setMetaTable(EE_Secondary_Table $meta_table)
166
-    {
167
-        $this->meta_table = $meta_table;
168
-    }
169
-
170
-
171
-    public function model(): ?EEM_CPT_Base
172
-    {
173
-        return $this->model;
174
-    }
175
-
176
-
177
-    protected function setModel(EEM_CPT_Base $CPT_model)
178
-    {
179
-        $this->model = $CPT_model;
180
-    }
181
-
182
-
183
-    /**
184
-     * @return EE_Request_Handler
185
-     * @deprecated 4.9.63.p
186
-     */
187
-    public function request(): ?EE_Request_Handler
188
-    {
189
-        if (! $this->request_handler instanceof EE_Request_Handler) {
190
-            $this->request_handler = LoaderFactory::getLoader()->getShared('EE_Request_Handler');
191
-        }
192
-        return $this->request_handler;
193
-    }
194
-
195
-
196
-    // phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
197
-
198
-
199
-    public function WpQuery(): WP_Query
200
-    {
201
-        return $this->wp_query;
202
-    }
203
-
204
-
205
-    // phpcs:enable
206
-
207
-
208
-    public function setWpQuery(WP_Query $wp_query)
209
-    {
210
-        $this->wp_query = $wp_query;
211
-    }
212
-
213
-
214
-    protected function initializeTaxonomies()
215
-    {
216
-        // check if taxonomies have already been set and that this CPT has taxonomies registered for it
217
-        if (
218
-            empty($this->taxonomies)
219
-            && isset($this->cpt_details['args']['taxonomies'])
220
-        ) {
221
-            // if so then grab them, but we want the taxonomy name as the key
222
-            $taxonomies = array_flip($this->cpt_details['args']['taxonomies']);
223
-            // then grab the list of ALL taxonomies
224
-            /** @var CustomTaxonomyDefinitions $taxonomy_definitions */
225
-            $taxonomy_definitions = $this->loader->getShared(CustomTaxonomyDefinitions::class);
226
-            $all_taxonomies       = $taxonomy_definitions->getCustomTaxonomyDefinitions();
227
-            foreach ($taxonomies as $taxonomy => &$details) {
228
-                // add details to our taxonomies if they exist
229
-                $details = $all_taxonomies[ $taxonomy ] ?? [];
230
-            }
231
-            // ALWAYS unset() variables that were passed by reference
232
-            unset($details);
233
-            $this->setTaxonomies($taxonomies);
234
-        }
235
-    }
236
-
237
-
238
-    /**
239
-     * @throws EE_Error
240
-     * @since 4.9.63.p
241
-     */
242
-    protected function init()
243
-    {
244
-        $this->setAdditionalCptDetails();
245
-        $this->setRequestVarsIfCpt();
246
-        // convert post_type to model name
247
-        $model_name = str_replace('EE_', '', $this->cpt_details['class_name']);
248
-        // load all tables related to CPT
249
-        $this->setupModelsAndTables($model_name);
250
-        // load and instantiate CPT_*_Strategy
251
-        $this->cpt_strategy = $this->cpt_strategy === null
252
-            ? $this->cptStrategyClass($model_name)
253
-            : $this->cpt_strategy;
254
-        // !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
255
-        // here's the list of available filters in the WP_Query object
256
-        // 'posts_where_paged'
257
-        // 'posts_groupby'
258
-        // 'posts_join_paged'
259
-        // 'posts_orderby'
260
-        // 'posts_distinct'
261
-        // 'post_limits'
262
-        // 'posts_fields'
263
-        // 'posts_join'
264
-        add_filter('posts_fields', [$this, 'postsFields'], 10, 2);
265
-        add_filter('posts_join', [$this, 'postsJoin'], 10, 2);
266
-        add_filter('the_posts', [$this, 'thePosts'], 1, 2);
267
-        if ($this->wp_query->is_main_query()) {
268
-            add_filter('get_edit_post_link', [$this, 'getEditPostLink'], 10, 2);
269
-            $this->addTemplateFilters();
270
-        }
271
-    }
272
-
273
-
274
-    /**
275
-     * sets some basic query vars that pertain to the CPT
276
-     *
277
-     * @return void
278
-     */
279
-    protected function setAdditionalCptDetails()
280
-    {
281
-        // the post or category or term that is triggering EE
282
-        $this->cpt_details['espresso_page'] = $this->current_page->isEspressoPage();
283
-        // requested post name
284
-        $this->cpt_details['post_name'] = $this->request->getRequestParam('post_name');
285
-        // add support for viewing 'private', 'draft', or 'pending' posts
286
-        if (
287
-            isset($this->wp_query->query_vars['p'])
288
-            && $this->wp_query->query_vars['p'] !== 0
289
-            && is_user_logged_in()
290
-            && current_user_can('edit_post', $this->wp_query->query_vars['p'])
291
-        ) {
292
-            // we can just inject directly into the WP_Query object
293
-            $this->wp_query->query['post_status'] = ['publish', 'private', 'draft', 'pending'];
294
-            // now set the main 'ee' request var so that the appropriate module can load the appropriate template(s)
295
-            $this->request->setRequestParam('ee', $this->cpt_details['singular_slug']);
296
-        }
297
-    }
298
-
299
-
300
-    /**
301
-     * Checks if we're on a EE-CPT archive-or-single page, and if we've never set the EE request var.
302
-     * If so, sets the 'ee' request variable
303
-     * so other parts of EE can know what CPT is getting queried.
304
-     * To Mike's knowledge, this must be called from during or after the pre_get_posts hook
305
-     * in order for is_archive() and is_single() methods to work properly.
306
-     *
307
-     * @return void
308
-     */
309
-    public function setRequestVarsIfCpt()
310
-    {
311
-        // check if ee action var has been set
312
-        if (! $this->request->requestParamIsSet('ee')) {
313
-            // check that route exists for CPT archive slug
314
-            if (is_archive() && EE_Config::get_route($this->cpt_details['plural_slug'])) {
315
-                // ie: set "ee" to "events"
316
-                $this->request->setRequestParam('ee', $this->cpt_details['plural_slug']);
317
-                // or does it match a single page CPT like /event/
318
-            } elseif (is_single() && EE_Config::get_route($this->cpt_details['singular_slug'])) {
319
-                // ie: set "ee" to "event"
320
-                $this->request->setRequestParam('ee', $this->cpt_details['singular_slug']);
321
-            }
322
-        }
323
-    }
324
-
325
-
326
-    /**
327
-     * setupModelsAndTables
328
-     *
329
-     * @param string $model_name
330
-     * @throws EE_Error
331
-     */
332
-    protected function setupModelsAndTables(string $model_name)
333
-    {
334
-        // get CPT table data via CPT Model
335
-        $full_model_name = strpos($model_name, 'EEM_') !== 0
336
-            ? 'EEM_' . $model_name
337
-            : $model_name;
338
-        $model           = $this->loader->getShared($full_model_name);
339
-        if (! $model instanceof EEM_CPT_Base) {
340
-            throw new EE_Error(
341
-                sprintf(
342
-                    esc_html__(
343
-                        'The "%1$s" model could not be loaded.',
344
-                        'event_espresso'
345
-                    ),
346
-                    $full_model_name
347
-                )
348
-            );
349
-        }
350
-        $this->setModel($model);
351
-        $this->setModelTables($this->model->get_tables());
352
-        $meta_model = $model_name . '_Meta';
353
-        // is there a Meta Table for this CPT?
354
-        if (
355
-            isset($this->cpt_details['tables'][ $meta_model ])
356
-            && $this->cpt_details['tables'][ $meta_model ] instanceof EE_Secondary_Table
357
-        ) {
358
-            $this->setMetaTable($this->cpt_details['tables'][ $meta_model ]);
359
-        }
360
-    }
361
-
362
-
363
-    /**
364
-     * cptStrategyClass
365
-     *
366
-     * @param string $model_name
367
-     * @return EE_CPT_Event_Strategy|EE_CPT_Attendee_Strategy|EE_CPT_Default_Strategy|EE_CPT_Venue_Strategy
368
-     */
369
-    protected function cptStrategyClass(string $model_name)
370
-    {
371
-        // creates classname like:  CPT_Event_Strategy
372
-        $CPT_Strategy_class_name = 'EE_CPT_' . $model_name . '_Strategy';
373
-        // load and instantiate
374
-        $CPT_Strategy = $this->loader->getShared($CPT_Strategy_class_name, [$this->wp_query, $this->cpt_details]);
375
-        if ($CPT_Strategy === null) {
376
-            $CPT_Strategy = $this->loader->getShared('EE_CPT_Default_Strategy', [$this->wp_query, $this->cpt_details]);
377
-        }
378
-        return $CPT_Strategy;
379
-    }
380
-
381
-
382
-    /**
383
-     * @param string   $SQL
384
-     * @param WP_Query $wp_query
385
-     * @return string
386
-     */
387
-    public function postsFields(string $SQL, WP_Query $wp_query): string
388
-    {
389
-        if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== $this->post_type) {
390
-            return $SQL;
391
-        }
392
-        // does this CPT have a meta table ?
393
-        if ($this->meta_table instanceof EE_Secondary_Table) {
394
-            // adds something like ", wp_esp_event_meta.* " to WP Query SELECT statement
395
-            $SQL .= ', ' . $this->meta_table->get_table_name() . '.* ';
396
-        }
397
-        remove_filter('posts_fields', [$this, 'postsFields']);
398
-        return $SQL;
399
-    }
400
-
401
-
402
-    /**
403
-     * @param string $SQL
404
-     * @param WP_Query $wp_query
405
-     * @return string
406
-     */
407
-    public function postsJoin(string $SQL, WP_Query $wp_query): string
408
-    {
409
-        if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== $this->post_type) {
410
-            return $SQL;
411
-        }
412
-        // does this CPT have a meta table ?
413
-        if ($this->meta_table instanceof EE_Secondary_Table) {
414
-            global $wpdb;
415
-            // adds something like " LEFT JOIN wp_esp_event_meta ON ( wp_esp_event_meta.EVT_ID = wp_posts.ID ) " to WP Query JOIN statement
416
-            $posts_table = $wpdb->posts;
417
-            $meta_table = $this->meta_table->get_table_name();
418
-            $foreign_key = $this->meta_table->get_fk_on_table();
419
-            $SQL .= " LEFT JOIN $meta_table ON ( $meta_table.$foreign_key = $posts_table.ID ) ";
420
-        }
421
-        remove_filter('posts_join', [$this, 'postsJoin']);
422
-        return $SQL;
423
-    }
424
-
425
-
426
-    /**
427
-     * thePosts
428
-     *
429
-     * @param WP_Post[] $posts
430
-     * @param WP_Query  $wp_query
431
-     * @return WP_Post[]
432
-     */
433
-    public function thePosts(array $posts, WP_Query $wp_query): array
434
-    {
435
-        if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== $this->post_type) {
436
-            return $posts;
437
-        }
438
-        $CPT_class = $this->cpt_details['class_name'];
439
-        // loop thru posts
440
-        if ($this->model instanceof EEM_CPT_Base) {
441
-            foreach ($posts as $post) {
442
-                if ($post->post_type === $this->post_type) {
443
-                    $post->{$CPT_class} = $this->model->instantiate_class_from_post_object($post);
444
-                }
445
-            }
446
-        }
447
-        remove_filter('the_posts', [$this, 'thePosts'], 1);
448
-        return $posts;
449
-    }
450
-
451
-
452
-    /**
453
-     * @param string|null $url
454
-     * @param int    $ID
455
-     * @return null|string
456
-     */
457
-    public function getEditPostLink(?string $url, int $ID): ?string
458
-    {
459
-        // need to make sure we only edit links if our cpt
460
-        global $post;
461
-        // notice if the cpt is registered with `show_ee_ui` set to false, we take that to mean that the WordPress core ui
462
-        // for interacting with the CPT is desired and there is no EE UI for interacting with the CPT in the admin.
463
-        if (
464
-            ! $post instanceof WP_Post
465
-            || $post->post_type !== $this->post_type
466
-            || (
467
-                isset($this->cpt_details['args']['show_ee_ui'])
468
-                && ! $this->cpt_details['args']['show_ee_ui']
469
-            )
470
-        ) {
471
-            return $url;
472
-        }
473
-        // k made it here so all is good.
474
-        return wp_nonce_url(
475
-            add_query_arg(
476
-                ['page' => $this->post_type, 'post' => $ID, 'action' => 'edit'],
477
-                admin_url('admin.php')
478
-            ),
479
-            'edit',
480
-            'edit_nonce'
481
-        );
482
-    }
483
-
484
-
485
-    /**
486
-     * Execute any template filters.
487
-     * This method is only called if in main query.
488
-     *
489
-     * @return void
490
-     */
491
-    public function addTemplateFilters()
492
-    {
493
-        // if requested cpt supports page_templates and it's the main query
494
-        if (! empty($this->cpt_details['args']['page_templates']) && $this->wp_query->is_main_query()) {
495
-            // then let's hook into the appropriate query_template hook
496
-            add_filter('single_template', [$this, 'singleCptTemplate']);
497
-        }
498
-    }
499
-
500
-
501
-    /**
502
-     * Callback for single_template wp filter.
503
-     * This is used to load the set page_template for a single ee cpt if its set.  If "default" then we load the normal
504
-     * hierarchy.
505
-     *
506
-     * @param string $current_template Existing default template path derived for this page call.
507
-     * @return string the path to the full template file.
508
-     */
509
-    public function singleCptTemplate(string $current_template): string
510
-    {
511
-        $object = get_queried_object();
512
-        // does this called object HAVE a page template set that is something other than the default.
513
-        $template = get_post_meta($object->ID, '_wp_page_template', true);
514
-        // exit early if default or not set or invalid path (accounts for theme changes)
515
-        if (
516
-            $template === 'default'
517
-            || empty($template)
518
-            || ! is_readable(get_stylesheet_directory() . '/' . $template)
519
-        ) {
520
-            return $current_template;
521
-        }
522
-        // made it here so we SHOULD be able to just locate the template and then return it.
523
-        return locate_template([$template]);
524
-    }
126
+	/**
127
+	 * @return EE_Table_Base[]
128
+	 */
129
+	public function modelTables(): array
130
+	{
131
+		return $this->model_tables;
132
+	}
133
+
134
+
135
+	/**
136
+	 * @param EE_Table_Base[] $model_tables
137
+	 */
138
+	protected function setModelTables(array $model_tables)
139
+	{
140
+		$this->model_tables = $model_tables;
141
+	}
142
+
143
+
144
+	public function taxonomies(): array
145
+	{
146
+		if (empty($this->taxonomies)) {
147
+			$this->initializeTaxonomies();
148
+		}
149
+		return $this->taxonomies;
150
+	}
151
+
152
+
153
+	protected function setTaxonomies(array $taxonomies)
154
+	{
155
+		$this->taxonomies = $taxonomies;
156
+	}
157
+
158
+
159
+	public function metaTable(): ?EE_Secondary_Table
160
+	{
161
+		return $this->meta_table;
162
+	}
163
+
164
+
165
+	public function setMetaTable(EE_Secondary_Table $meta_table)
166
+	{
167
+		$this->meta_table = $meta_table;
168
+	}
169
+
170
+
171
+	public function model(): ?EEM_CPT_Base
172
+	{
173
+		return $this->model;
174
+	}
175
+
176
+
177
+	protected function setModel(EEM_CPT_Base $CPT_model)
178
+	{
179
+		$this->model = $CPT_model;
180
+	}
181
+
182
+
183
+	/**
184
+	 * @return EE_Request_Handler
185
+	 * @deprecated 4.9.63.p
186
+	 */
187
+	public function request(): ?EE_Request_Handler
188
+	{
189
+		if (! $this->request_handler instanceof EE_Request_Handler) {
190
+			$this->request_handler = LoaderFactory::getLoader()->getShared('EE_Request_Handler');
191
+		}
192
+		return $this->request_handler;
193
+	}
194
+
195
+
196
+	// phpcs:disable PSR1.Methods.CamelCapsMethodName.NotCamelCaps
197
+
198
+
199
+	public function WpQuery(): WP_Query
200
+	{
201
+		return $this->wp_query;
202
+	}
203
+
204
+
205
+	// phpcs:enable
206
+
207
+
208
+	public function setWpQuery(WP_Query $wp_query)
209
+	{
210
+		$this->wp_query = $wp_query;
211
+	}
212
+
213
+
214
+	protected function initializeTaxonomies()
215
+	{
216
+		// check if taxonomies have already been set and that this CPT has taxonomies registered for it
217
+		if (
218
+			empty($this->taxonomies)
219
+			&& isset($this->cpt_details['args']['taxonomies'])
220
+		) {
221
+			// if so then grab them, but we want the taxonomy name as the key
222
+			$taxonomies = array_flip($this->cpt_details['args']['taxonomies']);
223
+			// then grab the list of ALL taxonomies
224
+			/** @var CustomTaxonomyDefinitions $taxonomy_definitions */
225
+			$taxonomy_definitions = $this->loader->getShared(CustomTaxonomyDefinitions::class);
226
+			$all_taxonomies       = $taxonomy_definitions->getCustomTaxonomyDefinitions();
227
+			foreach ($taxonomies as $taxonomy => &$details) {
228
+				// add details to our taxonomies if they exist
229
+				$details = $all_taxonomies[ $taxonomy ] ?? [];
230
+			}
231
+			// ALWAYS unset() variables that were passed by reference
232
+			unset($details);
233
+			$this->setTaxonomies($taxonomies);
234
+		}
235
+	}
236
+
237
+
238
+	/**
239
+	 * @throws EE_Error
240
+	 * @since 4.9.63.p
241
+	 */
242
+	protected function init()
243
+	{
244
+		$this->setAdditionalCptDetails();
245
+		$this->setRequestVarsIfCpt();
246
+		// convert post_type to model name
247
+		$model_name = str_replace('EE_', '', $this->cpt_details['class_name']);
248
+		// load all tables related to CPT
249
+		$this->setupModelsAndTables($model_name);
250
+		// load and instantiate CPT_*_Strategy
251
+		$this->cpt_strategy = $this->cpt_strategy === null
252
+			? $this->cptStrategyClass($model_name)
253
+			: $this->cpt_strategy;
254
+		// !!!!!!!!!!  IMPORTANT !!!!!!!!!!!!
255
+		// here's the list of available filters in the WP_Query object
256
+		// 'posts_where_paged'
257
+		// 'posts_groupby'
258
+		// 'posts_join_paged'
259
+		// 'posts_orderby'
260
+		// 'posts_distinct'
261
+		// 'post_limits'
262
+		// 'posts_fields'
263
+		// 'posts_join'
264
+		add_filter('posts_fields', [$this, 'postsFields'], 10, 2);
265
+		add_filter('posts_join', [$this, 'postsJoin'], 10, 2);
266
+		add_filter('the_posts', [$this, 'thePosts'], 1, 2);
267
+		if ($this->wp_query->is_main_query()) {
268
+			add_filter('get_edit_post_link', [$this, 'getEditPostLink'], 10, 2);
269
+			$this->addTemplateFilters();
270
+		}
271
+	}
272
+
273
+
274
+	/**
275
+	 * sets some basic query vars that pertain to the CPT
276
+	 *
277
+	 * @return void
278
+	 */
279
+	protected function setAdditionalCptDetails()
280
+	{
281
+		// the post or category or term that is triggering EE
282
+		$this->cpt_details['espresso_page'] = $this->current_page->isEspressoPage();
283
+		// requested post name
284
+		$this->cpt_details['post_name'] = $this->request->getRequestParam('post_name');
285
+		// add support for viewing 'private', 'draft', or 'pending' posts
286
+		if (
287
+			isset($this->wp_query->query_vars['p'])
288
+			&& $this->wp_query->query_vars['p'] !== 0
289
+			&& is_user_logged_in()
290
+			&& current_user_can('edit_post', $this->wp_query->query_vars['p'])
291
+		) {
292
+			// we can just inject directly into the WP_Query object
293
+			$this->wp_query->query['post_status'] = ['publish', 'private', 'draft', 'pending'];
294
+			// now set the main 'ee' request var so that the appropriate module can load the appropriate template(s)
295
+			$this->request->setRequestParam('ee', $this->cpt_details['singular_slug']);
296
+		}
297
+	}
298
+
299
+
300
+	/**
301
+	 * Checks if we're on a EE-CPT archive-or-single page, and if we've never set the EE request var.
302
+	 * If so, sets the 'ee' request variable
303
+	 * so other parts of EE can know what CPT is getting queried.
304
+	 * To Mike's knowledge, this must be called from during or after the pre_get_posts hook
305
+	 * in order for is_archive() and is_single() methods to work properly.
306
+	 *
307
+	 * @return void
308
+	 */
309
+	public function setRequestVarsIfCpt()
310
+	{
311
+		// check if ee action var has been set
312
+		if (! $this->request->requestParamIsSet('ee')) {
313
+			// check that route exists for CPT archive slug
314
+			if (is_archive() && EE_Config::get_route($this->cpt_details['plural_slug'])) {
315
+				// ie: set "ee" to "events"
316
+				$this->request->setRequestParam('ee', $this->cpt_details['plural_slug']);
317
+				// or does it match a single page CPT like /event/
318
+			} elseif (is_single() && EE_Config::get_route($this->cpt_details['singular_slug'])) {
319
+				// ie: set "ee" to "event"
320
+				$this->request->setRequestParam('ee', $this->cpt_details['singular_slug']);
321
+			}
322
+		}
323
+	}
324
+
325
+
326
+	/**
327
+	 * setupModelsAndTables
328
+	 *
329
+	 * @param string $model_name
330
+	 * @throws EE_Error
331
+	 */
332
+	protected function setupModelsAndTables(string $model_name)
333
+	{
334
+		// get CPT table data via CPT Model
335
+		$full_model_name = strpos($model_name, 'EEM_') !== 0
336
+			? 'EEM_' . $model_name
337
+			: $model_name;
338
+		$model           = $this->loader->getShared($full_model_name);
339
+		if (! $model instanceof EEM_CPT_Base) {
340
+			throw new EE_Error(
341
+				sprintf(
342
+					esc_html__(
343
+						'The "%1$s" model could not be loaded.',
344
+						'event_espresso'
345
+					),
346
+					$full_model_name
347
+				)
348
+			);
349
+		}
350
+		$this->setModel($model);
351
+		$this->setModelTables($this->model->get_tables());
352
+		$meta_model = $model_name . '_Meta';
353
+		// is there a Meta Table for this CPT?
354
+		if (
355
+			isset($this->cpt_details['tables'][ $meta_model ])
356
+			&& $this->cpt_details['tables'][ $meta_model ] instanceof EE_Secondary_Table
357
+		) {
358
+			$this->setMetaTable($this->cpt_details['tables'][ $meta_model ]);
359
+		}
360
+	}
361
+
362
+
363
+	/**
364
+	 * cptStrategyClass
365
+	 *
366
+	 * @param string $model_name
367
+	 * @return EE_CPT_Event_Strategy|EE_CPT_Attendee_Strategy|EE_CPT_Default_Strategy|EE_CPT_Venue_Strategy
368
+	 */
369
+	protected function cptStrategyClass(string $model_name)
370
+	{
371
+		// creates classname like:  CPT_Event_Strategy
372
+		$CPT_Strategy_class_name = 'EE_CPT_' . $model_name . '_Strategy';
373
+		// load and instantiate
374
+		$CPT_Strategy = $this->loader->getShared($CPT_Strategy_class_name, [$this->wp_query, $this->cpt_details]);
375
+		if ($CPT_Strategy === null) {
376
+			$CPT_Strategy = $this->loader->getShared('EE_CPT_Default_Strategy', [$this->wp_query, $this->cpt_details]);
377
+		}
378
+		return $CPT_Strategy;
379
+	}
380
+
381
+
382
+	/**
383
+	 * @param string   $SQL
384
+	 * @param WP_Query $wp_query
385
+	 * @return string
386
+	 */
387
+	public function postsFields(string $SQL, WP_Query $wp_query): string
388
+	{
389
+		if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== $this->post_type) {
390
+			return $SQL;
391
+		}
392
+		// does this CPT have a meta table ?
393
+		if ($this->meta_table instanceof EE_Secondary_Table) {
394
+			// adds something like ", wp_esp_event_meta.* " to WP Query SELECT statement
395
+			$SQL .= ', ' . $this->meta_table->get_table_name() . '.* ';
396
+		}
397
+		remove_filter('posts_fields', [$this, 'postsFields']);
398
+		return $SQL;
399
+	}
400
+
401
+
402
+	/**
403
+	 * @param string $SQL
404
+	 * @param WP_Query $wp_query
405
+	 * @return string
406
+	 */
407
+	public function postsJoin(string $SQL, WP_Query $wp_query): string
408
+	{
409
+		if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== $this->post_type) {
410
+			return $SQL;
411
+		}
412
+		// does this CPT have a meta table ?
413
+		if ($this->meta_table instanceof EE_Secondary_Table) {
414
+			global $wpdb;
415
+			// adds something like " LEFT JOIN wp_esp_event_meta ON ( wp_esp_event_meta.EVT_ID = wp_posts.ID ) " to WP Query JOIN statement
416
+			$posts_table = $wpdb->posts;
417
+			$meta_table = $this->meta_table->get_table_name();
418
+			$foreign_key = $this->meta_table->get_fk_on_table();
419
+			$SQL .= " LEFT JOIN $meta_table ON ( $meta_table.$foreign_key = $posts_table.ID ) ";
420
+		}
421
+		remove_filter('posts_join', [$this, 'postsJoin']);
422
+		return $SQL;
423
+	}
424
+
425
+
426
+	/**
427
+	 * thePosts
428
+	 *
429
+	 * @param WP_Post[] $posts
430
+	 * @param WP_Query  $wp_query
431
+	 * @return WP_Post[]
432
+	 */
433
+	public function thePosts(array $posts, WP_Query $wp_query): array
434
+	{
435
+		if (EE_CPT_Strategy::instance()->wpQueryPostType($wp_query) !== $this->post_type) {
436
+			return $posts;
437
+		}
438
+		$CPT_class = $this->cpt_details['class_name'];
439
+		// loop thru posts
440
+		if ($this->model instanceof EEM_CPT_Base) {
441
+			foreach ($posts as $post) {
442
+				if ($post->post_type === $this->post_type) {
443
+					$post->{$CPT_class} = $this->model->instantiate_class_from_post_object($post);
444
+				}
445
+			}
446
+		}
447
+		remove_filter('the_posts', [$this, 'thePosts'], 1);
448
+		return $posts;
449
+	}
450
+
451
+
452
+	/**
453
+	 * @param string|null $url
454
+	 * @param int    $ID
455
+	 * @return null|string
456
+	 */
457
+	public function getEditPostLink(?string $url, int $ID): ?string
458
+	{
459
+		// need to make sure we only edit links if our cpt
460
+		global $post;
461
+		// notice if the cpt is registered with `show_ee_ui` set to false, we take that to mean that the WordPress core ui
462
+		// for interacting with the CPT is desired and there is no EE UI for interacting with the CPT in the admin.
463
+		if (
464
+			! $post instanceof WP_Post
465
+			|| $post->post_type !== $this->post_type
466
+			|| (
467
+				isset($this->cpt_details['args']['show_ee_ui'])
468
+				&& ! $this->cpt_details['args']['show_ee_ui']
469
+			)
470
+		) {
471
+			return $url;
472
+		}
473
+		// k made it here so all is good.
474
+		return wp_nonce_url(
475
+			add_query_arg(
476
+				['page' => $this->post_type, 'post' => $ID, 'action' => 'edit'],
477
+				admin_url('admin.php')
478
+			),
479
+			'edit',
480
+			'edit_nonce'
481
+		);
482
+	}
483
+
484
+
485
+	/**
486
+	 * Execute any template filters.
487
+	 * This method is only called if in main query.
488
+	 *
489
+	 * @return void
490
+	 */
491
+	public function addTemplateFilters()
492
+	{
493
+		// if requested cpt supports page_templates and it's the main query
494
+		if (! empty($this->cpt_details['args']['page_templates']) && $this->wp_query->is_main_query()) {
495
+			// then let's hook into the appropriate query_template hook
496
+			add_filter('single_template', [$this, 'singleCptTemplate']);
497
+		}
498
+	}
499
+
500
+
501
+	/**
502
+	 * Callback for single_template wp filter.
503
+	 * This is used to load the set page_template for a single ee cpt if its set.  If "default" then we load the normal
504
+	 * hierarchy.
505
+	 *
506
+	 * @param string $current_template Existing default template path derived for this page call.
507
+	 * @return string the path to the full template file.
508
+	 */
509
+	public function singleCptTemplate(string $current_template): string
510
+	{
511
+		$object = get_queried_object();
512
+		// does this called object HAVE a page template set that is something other than the default.
513
+		$template = get_post_meta($object->ID, '_wp_page_template', true);
514
+		// exit early if default or not set or invalid path (accounts for theme changes)
515
+		if (
516
+			$template === 'default'
517
+			|| empty($template)
518
+			|| ! is_readable(get_stylesheet_directory() . '/' . $template)
519
+		) {
520
+			return $current_template;
521
+		}
522
+		// made it here so we SHOULD be able to just locate the template and then return it.
523
+		return locate_template([$template]);
524
+	}
525 525
 }
Please login to merge, or discard this patch.
Spacing   +13 added lines, -13 removed lines patch added patch discarded remove patch
@@ -186,7 +186,7 @@  discard block
 block discarded – undo
186 186
      */
187 187
     public function request(): ?EE_Request_Handler
188 188
     {
189
-        if (! $this->request_handler instanceof EE_Request_Handler) {
189
+        if ( ! $this->request_handler instanceof EE_Request_Handler) {
190 190
             $this->request_handler = LoaderFactory::getLoader()->getShared('EE_Request_Handler');
191 191
         }
192 192
         return $this->request_handler;
@@ -226,7 +226,7 @@  discard block
 block discarded – undo
226 226
             $all_taxonomies       = $taxonomy_definitions->getCustomTaxonomyDefinitions();
227 227
             foreach ($taxonomies as $taxonomy => &$details) {
228 228
                 // add details to our taxonomies if they exist
229
-                $details = $all_taxonomies[ $taxonomy ] ?? [];
229
+                $details = $all_taxonomies[$taxonomy] ?? [];
230 230
             }
231 231
             // ALWAYS unset() variables that were passed by reference
232 232
             unset($details);
@@ -309,7 +309,7 @@  discard block
 block discarded – undo
309 309
     public function setRequestVarsIfCpt()
310 310
     {
311 311
         // check if ee action var has been set
312
-        if (! $this->request->requestParamIsSet('ee')) {
312
+        if ( ! $this->request->requestParamIsSet('ee')) {
313 313
             // check that route exists for CPT archive slug
314 314
             if (is_archive() && EE_Config::get_route($this->cpt_details['plural_slug'])) {
315 315
                 // ie: set "ee" to "events"
@@ -333,10 +333,10 @@  discard block
 block discarded – undo
333 333
     {
334 334
         // get CPT table data via CPT Model
335 335
         $full_model_name = strpos($model_name, 'EEM_') !== 0
336
-            ? 'EEM_' . $model_name
336
+            ? 'EEM_'.$model_name
337 337
             : $model_name;
338 338
         $model           = $this->loader->getShared($full_model_name);
339
-        if (! $model instanceof EEM_CPT_Base) {
339
+        if ( ! $model instanceof EEM_CPT_Base) {
340 340
             throw new EE_Error(
341 341
                 sprintf(
342 342
                     esc_html__(
@@ -349,13 +349,13 @@  discard block
 block discarded – undo
349 349
         }
350 350
         $this->setModel($model);
351 351
         $this->setModelTables($this->model->get_tables());
352
-        $meta_model = $model_name . '_Meta';
352
+        $meta_model = $model_name.'_Meta';
353 353
         // is there a Meta Table for this CPT?
354 354
         if (
355
-            isset($this->cpt_details['tables'][ $meta_model ])
356
-            && $this->cpt_details['tables'][ $meta_model ] instanceof EE_Secondary_Table
355
+            isset($this->cpt_details['tables'][$meta_model])
356
+            && $this->cpt_details['tables'][$meta_model] instanceof EE_Secondary_Table
357 357
         ) {
358
-            $this->setMetaTable($this->cpt_details['tables'][ $meta_model ]);
358
+            $this->setMetaTable($this->cpt_details['tables'][$meta_model]);
359 359
         }
360 360
     }
361 361
 
@@ -369,7 +369,7 @@  discard block
 block discarded – undo
369 369
     protected function cptStrategyClass(string $model_name)
370 370
     {
371 371
         // creates classname like:  CPT_Event_Strategy
372
-        $CPT_Strategy_class_name = 'EE_CPT_' . $model_name . '_Strategy';
372
+        $CPT_Strategy_class_name = 'EE_CPT_'.$model_name.'_Strategy';
373 373
         // load and instantiate
374 374
         $CPT_Strategy = $this->loader->getShared($CPT_Strategy_class_name, [$this->wp_query, $this->cpt_details]);
375 375
         if ($CPT_Strategy === null) {
@@ -392,7 +392,7 @@  discard block
 block discarded – undo
392 392
         // does this CPT have a meta table ?
393 393
         if ($this->meta_table instanceof EE_Secondary_Table) {
394 394
             // adds something like ", wp_esp_event_meta.* " to WP Query SELECT statement
395
-            $SQL .= ', ' . $this->meta_table->get_table_name() . '.* ';
395
+            $SQL .= ', '.$this->meta_table->get_table_name().'.* ';
396 396
         }
397 397
         remove_filter('posts_fields', [$this, 'postsFields']);
398 398
         return $SQL;
@@ -491,7 +491,7 @@  discard block
 block discarded – undo
491 491
     public function addTemplateFilters()
492 492
     {
493 493
         // if requested cpt supports page_templates and it's the main query
494
-        if (! empty($this->cpt_details['args']['page_templates']) && $this->wp_query->is_main_query()) {
494
+        if ( ! empty($this->cpt_details['args']['page_templates']) && $this->wp_query->is_main_query()) {
495 495
             // then let's hook into the appropriate query_template hook
496 496
             add_filter('single_template', [$this, 'singleCptTemplate']);
497 497
         }
@@ -515,7 +515,7 @@  discard block
 block discarded – undo
515 515
         if (
516 516
             $template === 'default'
517 517
             || empty($template)
518
-            || ! is_readable(get_stylesheet_directory() . '/' . $template)
518
+            || ! is_readable(get_stylesheet_directory().'/'.$template)
519 519
         ) {
520 520
             return $current_template;
521 521
         }
Please login to merge, or discard this patch.
core/CPTs/EE_CPT_Attendee_Strategy.core.php 1 patch
Indentation   +24 added lines, -24 removed lines patch added patch discarded remove patch
@@ -9,32 +9,32 @@
 block discarded – undo
9 9
  */
10 10
 class EE_CPT_Attendee_Strategy
11 11
 {
12
-    /**
13
-     * CPT details from CustomPostTypeDefinitions for specific post type
14
-     */
15
-    protected array $CPT;
12
+	/**
13
+	 * CPT details from CustomPostTypeDefinitions for specific post type
14
+	 */
15
+	protected array $CPT;
16 16
 
17 17
 
18
-    /**
19
-     * @param WP_Query $wp_query
20
-     * @param array    $CPT
21
-     */
22
-    public function __construct(WP_Query $wp_query, array $CPT = [])
23
-    {
24
-        $this->CPT = $CPT;
25
-    }
18
+	/**
19
+	 * @param WP_Query $wp_query
20
+	 * @param array    $CPT
21
+	 */
22
+	public function __construct(WP_Query $wp_query, array $CPT = [])
23
+	{
24
+		$this->CPT = $CPT;
25
+	}
26 26
 
27 27
 
28
-    /**
29
-     *    the_posts
30
-     *
31
-     * @access    public
32
-     * @param          $posts
33
-     * @param WP_Query $wp_query
34
-     * @return    void
35
-     */
36
-    public function the_posts($posts, WP_Query $wp_query)
37
-    {
38
-        return $posts;
39
-    }
28
+	/**
29
+	 *    the_posts
30
+	 *
31
+	 * @access    public
32
+	 * @param          $posts
33
+	 * @param WP_Query $wp_query
34
+	 * @return    void
35
+	 */
36
+	public function the_posts($posts, WP_Query $wp_query)
37
+	{
38
+		return $posts;
39
+	}
40 40
 }
Please login to merge, or discard this patch.
core/EE_System.core.php 1 patch
Indentation   +1244 added lines, -1244 removed lines patch added patch discarded remove patch
@@ -26,1248 +26,1248 @@
 block discarded – undo
26 26
  */
27 27
 final class EE_System implements ResettableInterface
28 28
 {
29
-    /**
30
-     * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
31
-     * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
32
-     */
33
-    const req_type_normal = 0;
34
-
35
-    /**
36
-     * Indicates this is a brand new installation of EE so we should install
37
-     * tables and default data etc
38
-     */
39
-    const req_type_new_activation = 1;
40
-
41
-    /**
42
-     * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
43
-     * and we just exited maintenance mode). We MUST check the database is setup properly
44
-     * and that default data is setup too
45
-     */
46
-    const req_type_reactivation = 2;
47
-
48
-    /**
49
-     * indicates that EE has been upgraded since its previous request.
50
-     * We may have data migration scripts to call and will want to trigger maintenance mode
51
-     */
52
-    const req_type_upgrade = 3;
53
-
54
-    /**
55
-     * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
56
-     */
57
-    const req_type_downgrade = 4;
58
-
59
-    /**
60
-     * @deprecated since version 4.6.0.dev.006
61
-     * Now whenever a new_activation is detected the request type is still just
62
-     * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
63
-     * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
64
-     * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
65
-     * (Specifically, when the migration manager indicates migrations are finished
66
-     * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
67
-     */
68
-    const req_type_activation_but_not_installed = 5;
69
-
70
-    /**
71
-     * option prefix for recording the activation history (like core's "espresso_db_update") of addons
72
-     */
73
-    const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
74
-
75
-    /**
76
-     * @var AddonManager $addon_manager
77
-     */
78
-    private $addon_manager;
79
-
80
-    /**
81
-     * @var EE_System $_instance
82
-     */
83
-    private static $_instance;
84
-
85
-    /**
86
-     * @var EE_Registry $registry
87
-     */
88
-    private $registry;
89
-
90
-    /**
91
-     * @var LoaderInterface $loader
92
-     */
93
-    private $loader;
94
-
95
-    /**
96
-     * @var EE_Capabilities $capabilities
97
-     */
98
-    private $capabilities;
99
-
100
-    /**
101
-     * @var EE_Maintenance_Mode $maintenance_mode
102
-     */
103
-    private $maintenance_mode;
104
-
105
-    /**
106
-     * @var RequestInterface $request
107
-     */
108
-    private $request;
109
-
110
-    /**
111
-     * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
112
-     * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
113
-     *
114
-     * @var int $_req_type
115
-     */
116
-    private $_req_type;
117
-
118
-    /**
119
-     * Whether or not there was a non-micro version change in EE core version during this request
120
-     *
121
-     * @var boolean $_major_version_change
122
-     */
123
-    private $_major_version_change = false;
124
-
125
-    /**
126
-     * @var Router $router
127
-     */
128
-    private $router;
129
-
130
-    /**
131
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
132
-     */
133
-    private $register_custom_post_types;
134
-
135
-    /**
136
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
137
-     */
138
-    private $register_custom_taxonomies;
139
-
140
-    /**
141
-     * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
142
-     */
143
-    private $register_custom_taxonomy_terms;
144
-
145
-
146
-    /**
147
-     * @singleton method used to instantiate class object
148
-     * @param LoaderInterface|null     $loader
149
-     * @param EE_Maintenance_Mode|null $maintenance_mode
150
-     * @param EE_Registry|null         $registry
151
-     * @param RequestInterface|null    $request
152
-     * @param Router|null              $router
153
-     * @return EE_System
154
-     */
155
-    public static function instance(
156
-        LoaderInterface $loader = null,
157
-        EE_Maintenance_Mode $maintenance_mode = null,
158
-        EE_Registry $registry = null,
159
-        RequestInterface $request = null,
160
-        Router $router = null
161
-    ): EE_System {
162
-        // check if class object is instantiated
163
-        if (! self::$_instance instanceof EE_System) {
164
-            self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
165
-        }
166
-        return self::$_instance;
167
-    }
168
-
169
-
170
-    /**
171
-     * resets the instance and returns it
172
-     *
173
-     * @return EE_System
174
-     */
175
-    public static function reset(): EE_System
176
-    {
177
-        self::$_instance->_req_type = null;
178
-        // make sure none of the old hooks are left hanging around
179
-        remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
180
-        // we need to reset the migration manager in order for it to detect DMSs properly
181
-        EE_Data_Migration_Manager::reset();
182
-        self::instance()->detect_activations_or_upgrades();
183
-        self::instance()->perform_activations_upgrades_and_migrations();
184
-        return self::instance();
185
-    }
186
-
187
-
188
-    /**
189
-     * sets hooks for running rest of system
190
-     * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
191
-     * starting EE Addons from any other point may lead to problems
192
-     *
193
-     * @param LoaderInterface     $loader
194
-     * @param EE_Maintenance_Mode $maintenance_mode
195
-     * @param EE_Registry         $registry
196
-     * @param RequestInterface    $request
197
-     * @param Router              $router
198
-     */
199
-    private function __construct(
200
-        LoaderInterface $loader,
201
-        EE_Maintenance_Mode $maintenance_mode,
202
-        EE_Registry $registry,
203
-        RequestInterface $request,
204
-        Router $router
205
-    ) {
206
-        $this->registry         = $registry;
207
-        $this->loader           = $loader;
208
-        $this->request          = $request;
209
-        $this->router           = $router;
210
-        $this->maintenance_mode = $maintenance_mode;
211
-        do_action('AHEE__EE_System__construct__begin', $this);
212
-        add_action(
213
-            'AHEE__EE_Bootstrap__load_espresso_addons',
214
-            [$this, 'loadWpGraphQL'],
215
-            3
216
-        );
217
-        add_action(
218
-            'AHEE__EE_Bootstrap__load_espresso_addons',
219
-            [$this, 'loadCapabilities'],
220
-            5
221
-        );
222
-        add_action(
223
-            'AHEE__EE_Bootstrap__load_espresso_addons',
224
-            [$this, 'loadCommandBus'],
225
-            7
226
-        );
227
-        add_action(
228
-            'AHEE__EE_Bootstrap__load_espresso_addons',
229
-            [$this, 'loadPluginApi'],
230
-            9
231
-        );
232
-        // give caff stuff a chance to play during the activation process too.
233
-        add_action(
234
-            'AHEE__EE_Bootstrap__load_espresso_addons',
235
-            [$this, 'brewCaffeinated'],
236
-            9
237
-        );
238
-        // allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
239
-        add_action(
240
-            'AHEE__EE_Bootstrap__load_espresso_addons',
241
-            [$this, 'load_espresso_addons']
242
-        );
243
-        // when an ee addon is activated, we want to call the core hook(s) again
244
-        // because the newly-activated addon didn't get a chance to run at all
245
-        add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
246
-        // detect whether install or upgrade
247
-        add_action(
248
-            'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
249
-            [$this, 'detect_activations_or_upgrades'],
250
-            3
251
-        );
252
-        // load EE_Config, EE_Textdomain, etc
253
-        add_action(
254
-            'AHEE__EE_Bootstrap__load_core_configuration',
255
-            [$this, 'load_core_configuration'],
256
-            5
257
-        );
258
-        // load specifications for matching routes to current request
259
-        add_action(
260
-            'AHEE__EE_Bootstrap__load_core_configuration',
261
-            [$this, 'loadRouteMatchSpecifications']
262
-        );
263
-        // load specifications for custom post types
264
-        add_action(
265
-            'AHEE__EE_Bootstrap__load_core_configuration',
266
-            [$this, 'loadCustomPostTypes']
267
-        );
268
-        // load specifications for custom post types
269
-        add_action(
270
-            'AHEE__EE_Bootstrap__load_core_configuration',
271
-            [$this, 'loadCustomPostTypes']
272
-        );
273
-        // load EE_Config, EE_Textdomain, etc
274
-        add_action(
275
-            'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
276
-            [$this, 'register_shortcodes_modules_and_widgets'],
277
-            7
278
-        );
279
-        // you wanna get going? I wanna get going... let's get going!
280
-        add_action(
281
-            'AHEE__EE_Bootstrap__brew_espresso',
282
-            [$this, 'brew_espresso'],
283
-            9
284
-        );
285
-        // other housekeeping
286
-        // exclude EE critical pages from wp_list_pages
287
-        add_filter(
288
-            'wp_list_pages_excludes',
289
-            [$this, 'remove_pages_from_wp_list_pages'],
290
-            10
291
-        );
292
-        // ALL EE Addons should use the following hook point to attach their initial setup too
293
-        // it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
294
-        do_action('AHEE__EE_System__construct__complete', $this);
295
-    }
296
-
297
-
298
-    /**
299
-     * load and setup EE_Capabilities
300
-     *
301
-     * @return void
302
-     */
303
-    public function loadWpGraphQL()
304
-    {
305
-        espressoLoadWpGraphQL();
306
-    }
307
-
308
-
309
-    /**
310
-     * load and setup EE_Capabilities
311
-     *
312
-     * @return void
313
-     */
314
-    public function loadCapabilities()
315
-    {
316
-        $this->capabilities = $this->loader->getShared('EE_Capabilities');
317
-    }
318
-
319
-
320
-    /**
321
-     * create and cache the CommandBus, and also add middleware
322
-     * The CapChecker middleware requires the use of EE_Capabilities
323
-     * which is why we need to load the CommandBus after Caps are set up
324
-     * CommandBus middleware operate FIFO - First In First Out
325
-     * so LocateMovedCommands will run first in order to return any new commands
326
-     *
327
-     * @return void
328
-     */
329
-    public function loadCommandBus()
330
-    {
331
-        $this->loader->getShared(
332
-            'CommandBusInterface',
333
-            [
334
-                null,
335
-                apply_filters(
336
-                    'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
337
-                    [
338
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\LocateMovedCommands'),
339
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
340
-                        $this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
341
-                    ]
342
-                ),
343
-            ]
344
-        );
345
-    }
346
-
347
-
348
-    /**
349
-     * @return void
350
-     * @throws Exception
351
-     */
352
-    public function loadPluginApi()
353
-    {
354
-        $this->addon_manager = $this->loader->getShared(AddonManager::class);
355
-        $this->addon_manager->initialize();
356
-        $this->loader->getShared('EE_Request_Handler');
357
-    }
358
-
359
-
360
-    /**
361
-     * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
362
-     * that need to be setup before our EE_System launches.
363
-     *
364
-     * @return void
365
-     * @throws DomainException
366
-     * @throws InvalidArgumentException
367
-     * @throws InvalidDataTypeException
368
-     * @throws InvalidInterfaceException
369
-     * @throws InvalidClassException
370
-     * @throws InvalidFilePathException
371
-     * @throws EE_Error
372
-     */
373
-    public function brewCaffeinated()
374
-    {
375
-        static $brew;
376
-        /** @var Domain $domain */
377
-        $domain = DomainFactory::getEventEspressoCoreDomain();
378
-        if ($domain->isCaffeinated() && ! $brew instanceof EE_Brewing_Regular) {
379
-            require_once EE_CAFF_PATH . 'brewing_regular.php';
380
-            /** @var EE_Brewing_Regular $brew */
381
-            $brew = LoaderFactory::getLoader()->getShared(EE_Brewing_Regular::class);
382
-            $brew->initializePUE();
383
-            add_action(
384
-                'AHEE__EE_System__load_core_configuration__begin',
385
-                [$brew, 'caffeinated']
386
-            );
387
-        }
388
-    }
389
-
390
-
391
-    /**
392
-     * load_espresso_addons
393
-     * allow addons to load first so that they can set hooks for running DMS's, etc
394
-     * this is hooked into both:
395
-     *    'AHEE__EE_Bootstrap__load_core_configuration'
396
-     *        which runs during the WP 'plugins_loaded' action at priority 5
397
-     *    and the WP 'activate_plugin' hook point
398
-     *
399
-     * @return void
400
-     * @throws Exception
401
-     */
402
-    public function load_espresso_addons()
403
-    {
404
-        // looking for hooks? they've been moved into the AddonManager to maintain compatibility
405
-        $this->addon_manager->loadAddons();
406
-    }
407
-
408
-
409
-    /**
410
-     * detect_activations_or_upgrades
411
-     * Checks for activation or upgrade of core first;
412
-     * then also checks if any registered addons have been activated or upgraded
413
-     * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
414
-     * which runs during the WP 'plugins_loaded' action at priority 3
415
-     *
416
-     * @access public
417
-     * @return void
418
-     */
419
-    public function detect_activations_or_upgrades()
420
-    {
421
-        // first off: let's make sure to handle core
422
-        $this->detect_if_activation_or_upgrade();
423
-        foreach ($this->registry->addons as $addon) {
424
-            if ($addon instanceof EE_Addon) {
425
-                // detect teh request type for that addon
426
-                $addon->detect_req_type();
427
-            }
428
-        }
429
-    }
430
-
431
-
432
-    /**
433
-     * detect_if_activation_or_upgrade
434
-     * Takes care of detecting whether this is a brand new install or code upgrade,
435
-     * and either setting up the DB or setting up maintenance mode etc.
436
-     *
437
-     * @access public
438
-     * @return void
439
-     */
440
-    public function detect_if_activation_or_upgrade()
441
-    {
442
-        do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
443
-        // check if db has been updated, or if its a brand-new installation
444
-        $espresso_db_update = $this->fix_espresso_db_upgrade_option();
445
-        $request_type       = $this->detect_req_type($espresso_db_update);
446
-        switch ($request_type) {
447
-            case EE_System::req_type_new_activation:
448
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
449
-                $this->_handle_core_version_change($espresso_db_update);
450
-                break;
451
-            case EE_System::req_type_reactivation:
452
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
453
-                $this->_handle_core_version_change($espresso_db_update);
454
-                break;
455
-            case EE_System::req_type_upgrade:
456
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
457
-                // migrations may be required now that we've upgraded
458
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
459
-                $this->_handle_core_version_change($espresso_db_update);
460
-                break;
461
-            case EE_System::req_type_downgrade:
462
-                do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
463
-                // its possible migrations are no longer required
464
-                $this->maintenance_mode->set_maintenance_mode_if_db_old();
465
-                $this->_handle_core_version_change($espresso_db_update);
466
-                break;
467
-            case EE_System::req_type_normal:
468
-            default:
469
-                break;
470
-        }
471
-        do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
472
-    }
473
-
474
-
475
-    /**
476
-     * Updates the list of installed versions and sets hooks for
477
-     * initializing the database later during the request
478
-     *
479
-     * @param array $espresso_db_update
480
-     */
481
-    private function _handle_core_version_change(array $espresso_db_update)
482
-    {
483
-        $this->update_list_of_installed_versions($espresso_db_update);
484
-        // get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
485
-        add_action(
486
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
487
-            [$this, 'initialize_db_if_no_migrations_required']
488
-        );
489
-    }
490
-
491
-
492
-    /**
493
-     * standardizes the wp option 'espresso_db_upgrade' which actually stores
494
-     * information about what versions of EE have been installed and activated,
495
-     * NOT necessarily the state of the database
496
-     *
497
-     * @param mixed $espresso_db_update           the value of the WordPress option.
498
-     *                                            If not supplied, fetches it from the options table
499
-     * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
500
-     */
501
-    private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
502
-    {
503
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
504
-        if (! $espresso_db_update) {
505
-            $espresso_db_update = get_option('espresso_db_update');
506
-        }
507
-        // check that option is an array
508
-        if (! is_array($espresso_db_update)) {
509
-            // if option is FALSE, then it never existed
510
-            if ($espresso_db_update === false) {
511
-                // make $espresso_db_update an array and save option with autoload OFF
512
-                $espresso_db_update = [];
513
-                add_option('espresso_db_update', $espresso_db_update, '', 'no');
514
-            } else {
515
-                // option is NOT FALSE but also is NOT an array, so make it an array and save it
516
-                $espresso_db_update = [$espresso_db_update => []];
517
-                update_option('espresso_db_update', $espresso_db_update);
518
-            }
519
-        } else {
520
-            $corrected_db_update = [];
521
-            // if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
522
-            foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
523
-                if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
524
-                    // the key is an int, and the value IS NOT an array
525
-                    // so it must be numerically-indexed, where values are versions installed...
526
-                    // fix it!
527
-                    $version_string                         = $should_be_array;
528
-                    $corrected_db_update[ $version_string ] = ['unknown-date'];
529
-                } else {
530
-                    // ok it checks out
531
-                    $corrected_db_update[ $should_be_version_string ] = $should_be_array;
532
-                }
533
-            }
534
-            $espresso_db_update = $corrected_db_update;
535
-            update_option('espresso_db_update', $espresso_db_update);
536
-        }
537
-        do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
538
-        return ! empty($espresso_db_update)
539
-            ? $espresso_db_update
540
-            : [];
541
-    }
542
-
543
-
544
-    /**
545
-     * Does the traditional work of setting up the plugin's database and adding default data.
546
-     * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
547
-     * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
548
-     * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
549
-     * so that it will be done when migrations are finished
550
-     *
551
-     * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
552
-     * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
553
-     *                                       This is a resource-intensive job
554
-     *                                       so we prefer to only do it when necessary
555
-     * @return void
556
-     * @throws EE_Error
557
-     * @throws ReflectionException
558
-     */
559
-    public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
560
-    {
561
-        $request_type = $this->detect_req_type();
562
-        // only initialize system if we're not in maintenance mode.
563
-        if (! MaintenanceStatus::isFullSite()) {
564
-            /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
565
-            $rewrite_rules = $this->loader->getShared(
566
-                'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
567
-            );
568
-            $rewrite_rules->flush();
569
-            if ($verify_schema) {
570
-                EEH_Activation::initialize_db_and_folders();
571
-            }
572
-            EEH_Activation::initialize_db_content();
573
-            EEH_Activation::system_initialization();
574
-            if ($initialize_addons_too) {
575
-                $this->initialize_addons();
576
-            }
577
-        } else {
578
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
579
-        }
580
-        if (
581
-            $request_type === EE_System::req_type_new_activation
582
-            || $request_type === EE_System::req_type_reactivation
583
-            || (
584
-                $request_type === EE_System::req_type_upgrade
585
-                && $this->is_major_version_change()
586
-            )
587
-        ) {
588
-            add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
589
-        }
590
-    }
591
-
592
-
593
-    /**
594
-     * Initializes the db for all registered addons
595
-     *
596
-     * @throws EE_Error
597
-     * @throws ReflectionException
598
-     */
599
-    public function initialize_addons()
600
-    {
601
-        // foreach registered addon, make sure its db is up-to-date too
602
-        foreach ($this->registry->addons as $addon) {
603
-            if ($addon instanceof EE_Addon) {
604
-                $addon->initialize_db_if_no_migrations_required();
605
-            }
606
-        }
607
-    }
608
-
609
-
610
-    /**
611
-     * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
612
-     *
613
-     * @param array  $version_history
614
-     * @param string $current_version_to_add version to be added to the version history
615
-     * @return    boolean success as to whether or not this option was changed
616
-     */
617
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
618
-    {
619
-        if (! $version_history) {
620
-            $version_history = $this->fix_espresso_db_upgrade_option($version_history);
621
-        }
622
-        if ($current_version_to_add === null) {
623
-            $current_version_to_add = espresso_version();
624
-        }
625
-        $version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
626
-        // re-save
627
-        return update_option('espresso_db_update', $version_history);
628
-    }
629
-
630
-
631
-    /**
632
-     * Detects if the current version indicated in the has existed in the list of
633
-     * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
634
-     *
635
-     * @param array|null $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
636
-     *                                       If not supplied, fetches it from the options table.
637
-     *                                       Also, caches its result so later parts of the code can also know whether
638
-     *                                       there's been an update or not. This way we can add the current version to
639
-     *                                       espresso_db_update, but still know if this is a new install or not
640
-     * @return int one of the constants on EE_System::req_type_
641
-     */
642
-    public function detect_req_type(?array $espresso_db_update = null): int
643
-    {
644
-        if ($this->_req_type === null) {
645
-            $espresso_db_update          = ! empty($espresso_db_update)
646
-                ? $espresso_db_update
647
-                : $this->fix_espresso_db_upgrade_option();
648
-            $this->_req_type             = EE_System::detect_req_type_given_activation_history(
649
-                $espresso_db_update,
650
-                'ee_espresso_activation',
651
-                espresso_version()
652
-            );
653
-            $this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
654
-            $this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
655
-        }
656
-        return $this->_req_type;
657
-    }
658
-
659
-
660
-    /**
661
-     * Returns whether or not there was a non-micro version change (ie, change in either
662
-     * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
663
-     * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
664
-     *
665
-     * @param $activation_history
666
-     * @return bool
667
-     */
668
-    private function _detect_major_version_change($activation_history): bool
669
-    {
670
-        $previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
671
-        $previous_version_parts = explode('.', $previous_version);
672
-        $current_version_parts  = explode('.', espresso_version());
673
-        return isset(
674
-                   $previous_version_parts[0],
675
-                   $previous_version_parts[1],
676
-                   $current_version_parts[0],
677
-                   $current_version_parts[1]
678
-               ) && (
679
-                   $previous_version_parts[0] !== $current_version_parts[0]
680
-                   || $previous_version_parts[1] !== $current_version_parts[1]
681
-               );
682
-    }
683
-
684
-
685
-    /**
686
-     * Returns true if either the major or minor version of EE changed during this request.
687
-     * 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
688
-     *
689
-     * @return bool
690
-     */
691
-    public function is_major_version_change(): bool
692
-    {
693
-        return $this->_major_version_change;
694
-    }
695
-
696
-
697
-    /**
698
-     * Determines the request type for any ee addon, given three piece of info: the current array of activation
699
-     * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
700
-     * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
701
-     * just activated to (for core that will always be espresso_version())
702
-     *
703
-     * @param array|null $activation_history               the option's value which stores the activation history for
704
-     *                                                     this
705
-     *                                                     ee plugin. for core that's 'espresso_db_update'
706
-     * @param string     $activation_indicator_option_name the name of the WordPress option that is temporarily set to
707
-     *                                                     indicate that this plugin was just activated
708
-     * @param string     $current_version                  the version that was just upgraded to (for core that will be
709
-     *                                                     espresso_version())
710
-     * @return int one of the constants on EE_System::req_type_
711
-     */
712
-    public static function detect_req_type_given_activation_history(
713
-        array $activation_history,
714
-        string $activation_indicator_option_name,
715
-        string $current_version
716
-    ): int {
717
-        $version_change = self::compareVersionWithPrevious($activation_history, $current_version);
718
-        $is_activation  = get_option($activation_indicator_option_name, false);
719
-        $req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
720
-        if ($is_activation) {
721
-            // cleanup in aisle 6
722
-            delete_option($activation_indicator_option_name);
723
-        }
724
-        return $req_type;
725
-    }
726
-
727
-
728
-    /**
729
-     * @param array $activation_history
730
-     * @param int   $version_change
731
-     * @param bool  $is_activation
732
-     * @return int
733
-     * @since 5.0.0.p
734
-     */
735
-    private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
736
-    {
737
-        // if no previous activation history exists, then this is a brand new install
738
-        if (empty($activation_history)) {
739
-            return EE_System::req_type_new_activation;
740
-        }
741
-        // current version is higher than previous version, so it's an upgrade
742
-        if ($version_change === 1) {
743
-            return EE_System::req_type_upgrade;
744
-        }
745
-        // current version is lower than previous version, so it's a downgrade
746
-        if ($version_change === -1) {
747
-            return EE_System::req_type_downgrade;
748
-        }
749
-        // version hasn't changed since last version so check if the activation indicator is set
750
-        // to determine if it's a reactivation, or just a normal request
751
-        return $is_activation
752
-            ? EE_System::req_type_reactivation
753
-            : EE_System::req_type_normal;
754
-    }
755
-
756
-
757
-    /**
758
-     * Detects if the $version_to_upgrade_to is higher than the most recent version in
759
-     * the $activation_history_for_addon
760
-     *
761
-     * @param array  $activation_history    array where keys are versions,
762
-     *                                      values are arrays of times activated (sometimes 'unknown-date')
763
-     * @param string $current_version
764
-     * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
765
-     *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
766
-     *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
767
-     *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
768
-     */
769
-    private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
770
-    {
771
-        // find the most recently-activated version
772
-        $most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
773
-        return version_compare($current_version, $most_recently_active_version);
774
-    }
775
-
776
-
777
-    /**
778
-     * Gets the most recently active version listed in the activation history,
779
-     * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
780
-     *
781
-     * @param array|null $activation_history (keys are versions, values are arrays of times activated,
782
-     *                                       sometimes containing 'unknown-date'
783
-     * @return string
784
-     */
785
-    private static function getMostRecentlyActiveVersion(?array $activation_history): string
786
-    {
787
-        $most_recent_activation_date  = '1970-01-01 00:00:00';
788
-        $most_recently_active_version = '0.0.0.dev.000';
789
-        if (is_array($activation_history)) {
790
-            foreach ($activation_history as $version => $activation_dates) {
791
-                // check there is a record of when this version was activated.
792
-                // Otherwise, mark it as unknown
793
-                if (! $activation_dates) {
794
-                    $activation_dates = ['unknown-date'];
795
-                }
796
-                $activation_dates = is_string($activation_dates)
797
-                    ? [$activation_dates]
798
-                    : $activation_dates;
799
-                foreach ($activation_dates as $activation_date) {
800
-                    if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
801
-                        $most_recently_active_version = $version;
802
-                        $most_recent_activation_date  = $activation_date;
803
-                    }
804
-                }
805
-            }
806
-        }
807
-        return $most_recently_active_version;
808
-    }
809
-
810
-
811
-    /**
812
-     * This redirects to the about EE page after activation
813
-     *
814
-     * @return void
815
-     */
816
-    public function redirect_to_about_ee()
817
-    {
818
-        $notices = EE_Error::get_notices(false);
819
-        // if current user is an admin and it's not an ajax or rest request
820
-        if (
821
-            ! isset($notices['errors'])
822
-            && $this->request->isAdmin()
823
-            && apply_filters(
824
-                'FHEE__EE_System__redirect_to_about_ee__do_redirect',
825
-                $this->capabilities->current_user_can('manage_options', 'espresso_about_default')
826
-            )
827
-        ) {
828
-            $query_params = ['page' => 'espresso_about'];
829
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
830
-                $query_params['new_activation'] = true;
831
-            }
832
-            if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
833
-                $query_params['reactivation'] = true;
834
-            }
835
-            $url = add_query_arg($query_params, admin_url('admin.php'));
836
-            EEH_URL::safeRedirectAndExit($url);
837
-        }
838
-    }
839
-
840
-
841
-    /**
842
-     * load_core_configuration
843
-     * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
844
-     * which runs during the WP 'plugins_loaded' action at priority 5
845
-     *
846
-     * @return void
847
-     * @throws ReflectionException
848
-     * @throws Exception
849
-     */
850
-    public function load_core_configuration()
851
-    {
852
-        do_action('AHEE__EE_System__load_core_configuration__begin', $this);
853
-        $this->loader->getShared('EE_Load_Textdomain');
854
-        // load textdomain
855
-        EE_Load_Textdomain::load_textdomain();
856
-        // load and setup EE_Config and EE_Network_Config
857
-        $config = $this->loader->getShared('EE_Config');
858
-        $this->loader->getShared('EE_Network_Config');
859
-        // setup autoloaders
860
-        // enable logging?
861
-        $this->loader->getShared('EventEspresso\core\services\orm\TrashLogger');
862
-        if ($config->admin->use_remote_logging) {
863
-            $this->loader->getShared('EE_Log');
864
-        }
865
-        // check for activation errors
866
-        $activation_errors = get_option('ee_plugin_activation_errors', false);
867
-        if ($activation_errors) {
868
-            EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
869
-            update_option('ee_plugin_activation_errors', false);
870
-        }
871
-        // get model names
872
-        $this->_parse_model_names();
873
-        // configure custom post type definitions
874
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
875
-        $this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
876
-        do_action('AHEE__EE_System__load_core_configuration__complete', $this);
877
-    }
878
-
879
-
880
-    /**
881
-     * cycles through all of the models/*.model.php files, and assembles an array of model names
882
-     *
883
-     * @return void
884
-     * @throws ReflectionException
885
-     */
886
-    private function _parse_model_names()
887
-    {
888
-        // get all the files in the EE_MODELS folder that end in .model.php
889
-        $models                 = glob(EE_MODELS . '*.model.php');
890
-        $model_names            = [];
891
-        $non_abstract_db_models = [];
892
-        foreach ($models as $model) {
893
-            // get model classname
894
-            $classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
895
-            $short_name      = str_replace('EEM_', '', $classname);
896
-            $reflectionClass = new ReflectionClass($classname);
897
-            if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
898
-                $non_abstract_db_models[ $short_name ] = $classname;
899
-            }
900
-            $model_names[ $short_name ] = $classname;
901
-        }
902
-        $this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
903
-        $this->registry->non_abstract_db_models = apply_filters(
904
-            'FHEE__EE_System__parse_implemented_model_names',
905
-            $non_abstract_db_models
906
-        );
907
-    }
908
-
909
-
910
-    /**
911
-     * @throws Exception
912
-     * @since 4.9.71.p
913
-     */
914
-    public function loadRouteMatchSpecifications()
915
-    {
916
-        try {
917
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
918
-            $this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
919
-            $this->router->loadPrimaryRoutes();
920
-        } catch (Exception $exception) {
921
-            new ExceptionStackTraceDisplay($exception);
922
-        }
923
-        do_action('AHEE__EE_System__loadRouteMatchSpecifications');
924
-    }
925
-
926
-
927
-    /**
928
-     * loading CPT related classes earlier so that their definitions are available
929
-     * but not performing any actual registration with WP core until load_CPTs_and_session() is called
930
-     *
931
-     * @since   4.10.21.p
932
-     */
933
-    public function loadCustomPostTypes()
934
-    {
935
-        $this->register_custom_taxonomies     = $this->loader->getShared(
936
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
937
-        );
938
-        $this->register_custom_post_types     = $this->loader->getShared(
939
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
940
-        );
941
-        $this->register_custom_taxonomy_terms = $this->loader->getShared(
942
-            'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
943
-        );
944
-        // integrate WP_Query with the EE models
945
-        $this->loader->getShared('EE_CPT_Strategy');
946
-        // load legacy EE_Request_Handler in case add-ons still need it
947
-        $this->loader->getShared('EE_Request_Handler');
948
-    }
949
-
950
-
951
-    /**
952
-     * register_shortcodes_modules_and_widgets
953
-     * generate lists of shortcodes and modules, then verify paths and classes
954
-     * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
955
-     * which runs during the WP 'plugins_loaded' action at priority 7
956
-     *
957
-     * @access public
958
-     * @return void
959
-     * @throws Exception
960
-     */
961
-    public function register_shortcodes_modules_and_widgets()
962
-    {
963
-        $this->router->registerShortcodesModulesAndWidgets();
964
-        do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
965
-        // check for addons using old hook point
966
-        if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
967
-            $this->_incompatible_addon_error();
968
-        }
969
-    }
970
-
971
-
972
-    /**
973
-     * _incompatible_addon_error
974
-     *
975
-     * @access public
976
-     * @return void
977
-     */
978
-    private function _incompatible_addon_error()
979
-    {
980
-        // get array of classes hooking into here
981
-        $class_names = WordPressHooks::getClassNamesForAllCallbacksOnHook(
982
-            'AHEE__EE_System__register_shortcodes_modules_and_addons'
983
-        );
984
-        if (! empty($class_names)) {
985
-            $msg = esc_html__(
986
-                'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
987
-                'event_espresso'
988
-            );
989
-            $msg .= '<ul>';
990
-            foreach ($class_names as $class_name) {
991
-                $msg .= '<li><b>Event Espresso - '
992
-                        . str_replace(
993
-                            ['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
994
-                            '',
995
-                            $class_name
996
-                        ) . '</b></li>';
997
-            }
998
-            $msg .= '</ul>';
999
-            $msg .= esc_html__(
1000
-                'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1001
-                'event_espresso'
1002
-            );
1003
-            // save list of incompatible addons to wp-options for later use
1004
-            add_option('ee_incompatible_addons', $class_names, '', 'no');
1005
-            if (is_admin()) {
1006
-                EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1007
-            }
1008
-        }
1009
-    }
1010
-
1011
-
1012
-    /**
1013
-     * brew_espresso
1014
-     * begins the process of setting hooks for initializing EE in the correct order
1015
-     * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1016
-     * which runs during the WP 'plugins_loaded' action at priority 9
1017
-     *
1018
-     * @return void
1019
-     * @throws Exception
1020
-     */
1021
-    public function brew_espresso()
1022
-    {
1023
-        do_action('AHEE__EE_System__brew_espresso__begin', $this);
1024
-        // load some final core systems
1025
-        add_action('init', [$this, 'set_hooks_for_core'], 1);
1026
-        add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
1027
-        add_action('init', [$this, 'load_CPTs_and_session'], 5);
1028
-        add_action('init', [$this, 'load_controllers'], 7);
1029
-        add_action('init', [$this, 'core_loaded_and_ready'], 9);
1030
-        add_action('init', [$this, 'initialize'], 10);
1031
-        add_action('init', [$this, 'initialize_last'], 100);
1032
-        $this->router->brewEspresso();
1033
-        $this->loader->getShared('EventEspresso\PaymentMethods\Manager');
1034
-        $this->loader->getShared('EE_Payment_Method_Manager');
1035
-        do_action('AHEE__EE_System__brew_espresso__complete', $this);
1036
-    }
1037
-
1038
-
1039
-    /**
1040
-    /**
1041
-     *    set_hooks_for_core
1042
-     *
1043
-     * @access public
1044
-     * @return    void
1045
-     * @throws EE_Error
1046
-     */
1047
-    public function set_hooks_for_core()
1048
-    {
1049
-        $this->_deactivate_incompatible_addons();
1050
-        do_action('AHEE__EE_System__set_hooks_for_core');
1051
-        $this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1052
-        // caps need to be initialized on every request so that capability maps are set.
1053
-        // @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1054
-        $this->capabilities->init_caps();
1055
-    }
1056
-
1057
-
1058
-    /**
1059
-     * Using the information gathered in EE_System::_incompatible_addon_error,
1060
-     * deactivates any addons considered incompatible with the current version of EE
1061
-     */
1062
-    private function _deactivate_incompatible_addons()
1063
-    {
1064
-        $incompatible_addons = get_option('ee_incompatible_addons', []);
1065
-        if (! empty($incompatible_addons)) {
1066
-            $active_plugins = get_option('active_plugins', []);
1067
-            foreach ($active_plugins as $active_plugin) {
1068
-                foreach ($incompatible_addons as $incompatible_addon) {
1069
-                    if (strpos($active_plugin, $incompatible_addon) !== false) {
1070
-                        $this->request->unSetRequestParams(['activate'], true);
1071
-                        espresso_deactivate_plugin($active_plugin);
1072
-                    }
1073
-                }
1074
-            }
1075
-        }
1076
-    }
1077
-
1078
-
1079
-    /**
1080
-     *    perform_activations_upgrades_and_migrations
1081
-     *
1082
-     * @access public
1083
-     * @return    void
1084
-     */
1085
-    public function perform_activations_upgrades_and_migrations()
1086
-    {
1087
-        do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1088
-    }
1089
-
1090
-
1091
-    /**
1092
-     * @return void
1093
-     * @throws DomainException
1094
-     */
1095
-    public function load_CPTs_and_session()
1096
-    {
1097
-        do_action('AHEE__EE_System__load_CPTs_and_session__start');
1098
-        $this->register_custom_taxonomies->registerCustomTaxonomies();
1099
-        $this->register_custom_post_types->registerCustomPostTypes();
1100
-        $this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1101
-        do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1102
-    }
1103
-
1104
-
1105
-    /**
1106
-     * load_controllers
1107
-     * this is the best place to load any additional controllers that needs access to EE core.
1108
-     * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1109
-     * time
1110
-     *
1111
-     * @access public
1112
-     * @return void
1113
-     * @throws Exception
1114
-     */
1115
-    public function load_controllers()
1116
-    {
1117
-        do_action('AHEE__EE_System__load_controllers__start');
1118
-        $this->router->loadControllers();
1119
-        do_action('AHEE__EE_System__load_controllers__complete');
1120
-    }
1121
-
1122
-
1123
-    /**
1124
-     * core_loaded_and_ready
1125
-     * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1126
-     *
1127
-     * @access public
1128
-     * @return void
1129
-     * @throws Exception
1130
-     */
1131
-    public function core_loaded_and_ready()
1132
-    {
1133
-        $this->router->coreLoadedAndReady();
1134
-        do_action('AHEE__EE_System__core_loaded_and_ready');
1135
-        // always load template tags, because it's faster than checking if it's a front-end request, and many page
1136
-        // builders require these even on the front-end
1137
-        require_once EE_PUBLIC . 'template_tags.php';
1138
-        do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1139
-    }
1140
-
1141
-
1142
-    /**
1143
-     * initialize
1144
-     * this is the best place to begin initializing client code
1145
-     *
1146
-     * @access public
1147
-     * @return void
1148
-     */
1149
-    public function initialize()
1150
-    {
1151
-        do_action('AHEE__EE_System__initialize');
1152
-        add_filter(
1153
-            'safe_style_css',
1154
-            function ($styles) {
1155
-                $styles[] = 'display';
1156
-                $styles[] = 'visibility';
1157
-                $styles[] = 'position';
1158
-                $styles[] = 'top';
1159
-                $styles[] = 'right';
1160
-                $styles[] = 'bottom';
1161
-                $styles[] = 'left';
1162
-                $styles[] = 'resize';
1163
-                $styles[] = 'max-width';
1164
-                $styles[] = 'max-height';
1165
-                return $styles;
1166
-            }
1167
-        );
1168
-    }
1169
-
1170
-
1171
-    /**
1172
-     * initialize_last
1173
-     * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1174
-     * initialize has done so
1175
-     *
1176
-     * @access public
1177
-     * @return void
1178
-     * @throws Exception
1179
-     */
1180
-    public function initialize_last()
1181
-    {
1182
-        $this->router->initializeLast();
1183
-        do_action('AHEE__EE_System__initialize_last');
1184
-        /** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1185
-        $rewrite_rules = $this->loader->getShared(
1186
-            'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1187
-        );
1188
-        $rewrite_rules->flushRewriteRules();
1189
-        add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1190
-    }
1191
-
1192
-
1193
-    /**
1194
-     * @return void
1195
-     */
1196
-    public function addEspressoToolbar()
1197
-    {
1198
-        $this->loader->getShared(
1199
-            'EventEspresso\core\domain\services\admin\AdminToolBar',
1200
-            [$this->capabilities]
1201
-        );
1202
-    }
1203
-
1204
-
1205
-    /**
1206
-     * do_not_cache
1207
-     * sets no cache headers and defines no cache constants for WP plugins
1208
-     *
1209
-     * @access public
1210
-     * @return void
1211
-     */
1212
-    public static function do_not_cache()
1213
-    {
1214
-        // set no cache constants
1215
-        if (! defined('DONOTCACHEPAGE')) {
1216
-            define('DONOTCACHEPAGE', true);
1217
-        }
1218
-        if (! defined('DONOTCACHCEOBJECT')) {
1219
-            define('DONOTCACHCEOBJECT', true);
1220
-        }
1221
-        if (! defined('DONOTCACHEDB')) {
1222
-            define('DONOTCACHEDB', true);
1223
-        }
1224
-        // add no cache headers
1225
-        add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1226
-        // plus a little extra for nginx and Google Chrome
1227
-        add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1228
-        // prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1229
-        remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1230
-    }
1231
-
1232
-
1233
-    /**
1234
-     *    extra_nocache_headers
1235
-     *
1236
-     * @access    public
1237
-     * @param $headers
1238
-     * @return    array
1239
-     */
1240
-    public static function extra_nocache_headers($headers): array
1241
-    {
1242
-        // for NGINX
1243
-        $headers['X-Accel-Expires'] = 0;
1244
-        // plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1245
-        $headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1246
-        return $headers;
1247
-    }
1248
-
1249
-
1250
-    /**
1251
-     *    nocache_headers
1252
-     *
1253
-     * @access    public
1254
-     * @return    void
1255
-     */
1256
-    public static function nocache_headers()
1257
-    {
1258
-        nocache_headers();
1259
-    }
1260
-
1261
-
1262
-    /**
1263
-     * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1264
-     * never returned with the function.
1265
-     *
1266
-     * @param array $exclude_array any existing pages being excluded are in this array.
1267
-     * @return array
1268
-     */
1269
-    public function remove_pages_from_wp_list_pages(array $exclude_array): array
1270
-    {
1271
-        return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1272
-    }
29
+	/**
30
+	 * indicates this is a 'normal' request. Ie, not activation, nor upgrade, nor activation.
31
+	 * So examples of this would be a normal GET request on the frontend or backend, or a POST, etc
32
+	 */
33
+	const req_type_normal = 0;
34
+
35
+	/**
36
+	 * Indicates this is a brand new installation of EE so we should install
37
+	 * tables and default data etc
38
+	 */
39
+	const req_type_new_activation = 1;
40
+
41
+	/**
42
+	 * we've detected that EE has been reactivated (or EE was activated during maintenance mode,
43
+	 * and we just exited maintenance mode). We MUST check the database is setup properly
44
+	 * and that default data is setup too
45
+	 */
46
+	const req_type_reactivation = 2;
47
+
48
+	/**
49
+	 * indicates that EE has been upgraded since its previous request.
50
+	 * We may have data migration scripts to call and will want to trigger maintenance mode
51
+	 */
52
+	const req_type_upgrade = 3;
53
+
54
+	/**
55
+	 * TODO  will detect that EE has been DOWNGRADED. We probably don't want to run in this case...
56
+	 */
57
+	const req_type_downgrade = 4;
58
+
59
+	/**
60
+	 * @deprecated since version 4.6.0.dev.006
61
+	 * Now whenever a new_activation is detected the request type is still just
62
+	 * new_activation (same for reactivation, upgrade, downgrade etc), but if we're in maintenance mode
63
+	 * EE_System::initialize_db_if_no_migrations_required and EE_Addon::initialize_db_if_no_migrations_required
64
+	 * will instead enqueue that EE plugin's db initialization for when we're taken out of maintenance mode.
65
+	 * (Specifically, when the migration manager indicates migrations are finished
66
+	 * EE_Data_Migration_Manager::initialize_db_for_enqueued_ee_plugins() will be called)
67
+	 */
68
+	const req_type_activation_but_not_installed = 5;
69
+
70
+	/**
71
+	 * option prefix for recording the activation history (like core's "espresso_db_update") of addons
72
+	 */
73
+	const addon_activation_history_option_prefix = 'ee_addon_activation_history_';
74
+
75
+	/**
76
+	 * @var AddonManager $addon_manager
77
+	 */
78
+	private $addon_manager;
79
+
80
+	/**
81
+	 * @var EE_System $_instance
82
+	 */
83
+	private static $_instance;
84
+
85
+	/**
86
+	 * @var EE_Registry $registry
87
+	 */
88
+	private $registry;
89
+
90
+	/**
91
+	 * @var LoaderInterface $loader
92
+	 */
93
+	private $loader;
94
+
95
+	/**
96
+	 * @var EE_Capabilities $capabilities
97
+	 */
98
+	private $capabilities;
99
+
100
+	/**
101
+	 * @var EE_Maintenance_Mode $maintenance_mode
102
+	 */
103
+	private $maintenance_mode;
104
+
105
+	/**
106
+	 * @var RequestInterface $request
107
+	 */
108
+	private $request;
109
+
110
+	/**
111
+	 * Stores which type of request this is, options being one of the constants on EE_System starting with req_type_*.
112
+	 * It can be a brand-new activation, a reactivation, an upgrade, a downgrade, or a normal request.
113
+	 *
114
+	 * @var int $_req_type
115
+	 */
116
+	private $_req_type;
117
+
118
+	/**
119
+	 * Whether or not there was a non-micro version change in EE core version during this request
120
+	 *
121
+	 * @var boolean $_major_version_change
122
+	 */
123
+	private $_major_version_change = false;
124
+
125
+	/**
126
+	 * @var Router $router
127
+	 */
128
+	private $router;
129
+
130
+	/**
131
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes
132
+	 */
133
+	private $register_custom_post_types;
134
+
135
+	/**
136
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies
137
+	 */
138
+	private $register_custom_taxonomies;
139
+
140
+	/**
141
+	 * @param EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms
142
+	 */
143
+	private $register_custom_taxonomy_terms;
144
+
145
+
146
+	/**
147
+	 * @singleton method used to instantiate class object
148
+	 * @param LoaderInterface|null     $loader
149
+	 * @param EE_Maintenance_Mode|null $maintenance_mode
150
+	 * @param EE_Registry|null         $registry
151
+	 * @param RequestInterface|null    $request
152
+	 * @param Router|null              $router
153
+	 * @return EE_System
154
+	 */
155
+	public static function instance(
156
+		LoaderInterface $loader = null,
157
+		EE_Maintenance_Mode $maintenance_mode = null,
158
+		EE_Registry $registry = null,
159
+		RequestInterface $request = null,
160
+		Router $router = null
161
+	): EE_System {
162
+		// check if class object is instantiated
163
+		if (! self::$_instance instanceof EE_System) {
164
+			self::$_instance = new self($loader, $maintenance_mode, $registry, $request, $router);
165
+		}
166
+		return self::$_instance;
167
+	}
168
+
169
+
170
+	/**
171
+	 * resets the instance and returns it
172
+	 *
173
+	 * @return EE_System
174
+	 */
175
+	public static function reset(): EE_System
176
+	{
177
+		self::$_instance->_req_type = null;
178
+		// make sure none of the old hooks are left hanging around
179
+		remove_all_actions('AHEE__EE_System__perform_activations_upgrades_and_migrations');
180
+		// we need to reset the migration manager in order for it to detect DMSs properly
181
+		EE_Data_Migration_Manager::reset();
182
+		self::instance()->detect_activations_or_upgrades();
183
+		self::instance()->perform_activations_upgrades_and_migrations();
184
+		return self::instance();
185
+	}
186
+
187
+
188
+	/**
189
+	 * sets hooks for running rest of system
190
+	 * provides "AHEE__EE_System__construct__complete" hook for EE Addons to use as their starting point
191
+	 * starting EE Addons from any other point may lead to problems
192
+	 *
193
+	 * @param LoaderInterface     $loader
194
+	 * @param EE_Maintenance_Mode $maintenance_mode
195
+	 * @param EE_Registry         $registry
196
+	 * @param RequestInterface    $request
197
+	 * @param Router              $router
198
+	 */
199
+	private function __construct(
200
+		LoaderInterface $loader,
201
+		EE_Maintenance_Mode $maintenance_mode,
202
+		EE_Registry $registry,
203
+		RequestInterface $request,
204
+		Router $router
205
+	) {
206
+		$this->registry         = $registry;
207
+		$this->loader           = $loader;
208
+		$this->request          = $request;
209
+		$this->router           = $router;
210
+		$this->maintenance_mode = $maintenance_mode;
211
+		do_action('AHEE__EE_System__construct__begin', $this);
212
+		add_action(
213
+			'AHEE__EE_Bootstrap__load_espresso_addons',
214
+			[$this, 'loadWpGraphQL'],
215
+			3
216
+		);
217
+		add_action(
218
+			'AHEE__EE_Bootstrap__load_espresso_addons',
219
+			[$this, 'loadCapabilities'],
220
+			5
221
+		);
222
+		add_action(
223
+			'AHEE__EE_Bootstrap__load_espresso_addons',
224
+			[$this, 'loadCommandBus'],
225
+			7
226
+		);
227
+		add_action(
228
+			'AHEE__EE_Bootstrap__load_espresso_addons',
229
+			[$this, 'loadPluginApi'],
230
+			9
231
+		);
232
+		// give caff stuff a chance to play during the activation process too.
233
+		add_action(
234
+			'AHEE__EE_Bootstrap__load_espresso_addons',
235
+			[$this, 'brewCaffeinated'],
236
+			9
237
+		);
238
+		// allow addons to load first so that they can register autoloaders, set hooks for running DMS's, etc
239
+		add_action(
240
+			'AHEE__EE_Bootstrap__load_espresso_addons',
241
+			[$this, 'load_espresso_addons']
242
+		);
243
+		// when an ee addon is activated, we want to call the core hook(s) again
244
+		// because the newly-activated addon didn't get a chance to run at all
245
+		add_action('activate_plugin', [$this, 'load_espresso_addons'], 1);
246
+		// detect whether install or upgrade
247
+		add_action(
248
+			'AHEE__EE_Bootstrap__detect_activations_or_upgrades',
249
+			[$this, 'detect_activations_or_upgrades'],
250
+			3
251
+		);
252
+		// load EE_Config, EE_Textdomain, etc
253
+		add_action(
254
+			'AHEE__EE_Bootstrap__load_core_configuration',
255
+			[$this, 'load_core_configuration'],
256
+			5
257
+		);
258
+		// load specifications for matching routes to current request
259
+		add_action(
260
+			'AHEE__EE_Bootstrap__load_core_configuration',
261
+			[$this, 'loadRouteMatchSpecifications']
262
+		);
263
+		// load specifications for custom post types
264
+		add_action(
265
+			'AHEE__EE_Bootstrap__load_core_configuration',
266
+			[$this, 'loadCustomPostTypes']
267
+		);
268
+		// load specifications for custom post types
269
+		add_action(
270
+			'AHEE__EE_Bootstrap__load_core_configuration',
271
+			[$this, 'loadCustomPostTypes']
272
+		);
273
+		// load EE_Config, EE_Textdomain, etc
274
+		add_action(
275
+			'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets',
276
+			[$this, 'register_shortcodes_modules_and_widgets'],
277
+			7
278
+		);
279
+		// you wanna get going? I wanna get going... let's get going!
280
+		add_action(
281
+			'AHEE__EE_Bootstrap__brew_espresso',
282
+			[$this, 'brew_espresso'],
283
+			9
284
+		);
285
+		// other housekeeping
286
+		// exclude EE critical pages from wp_list_pages
287
+		add_filter(
288
+			'wp_list_pages_excludes',
289
+			[$this, 'remove_pages_from_wp_list_pages'],
290
+			10
291
+		);
292
+		// ALL EE Addons should use the following hook point to attach their initial setup too
293
+		// it's extremely important for EE Addons to register any class autoloaders so that they can be available when the EE_Config loads
294
+		do_action('AHEE__EE_System__construct__complete', $this);
295
+	}
296
+
297
+
298
+	/**
299
+	 * load and setup EE_Capabilities
300
+	 *
301
+	 * @return void
302
+	 */
303
+	public function loadWpGraphQL()
304
+	{
305
+		espressoLoadWpGraphQL();
306
+	}
307
+
308
+
309
+	/**
310
+	 * load and setup EE_Capabilities
311
+	 *
312
+	 * @return void
313
+	 */
314
+	public function loadCapabilities()
315
+	{
316
+		$this->capabilities = $this->loader->getShared('EE_Capabilities');
317
+	}
318
+
319
+
320
+	/**
321
+	 * create and cache the CommandBus, and also add middleware
322
+	 * The CapChecker middleware requires the use of EE_Capabilities
323
+	 * which is why we need to load the CommandBus after Caps are set up
324
+	 * CommandBus middleware operate FIFO - First In First Out
325
+	 * so LocateMovedCommands will run first in order to return any new commands
326
+	 *
327
+	 * @return void
328
+	 */
329
+	public function loadCommandBus()
330
+	{
331
+		$this->loader->getShared(
332
+			'CommandBusInterface',
333
+			[
334
+				null,
335
+				apply_filters(
336
+					'FHEE__EE_Load_Espresso_Core__handle_request__CommandBus_middleware',
337
+					[
338
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\LocateMovedCommands'),
339
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\CapChecker'),
340
+						$this->loader->getShared('EventEspresso\core\services\commands\middleware\AddActionHook'),
341
+					]
342
+				),
343
+			]
344
+		);
345
+	}
346
+
347
+
348
+	/**
349
+	 * @return void
350
+	 * @throws Exception
351
+	 */
352
+	public function loadPluginApi()
353
+	{
354
+		$this->addon_manager = $this->loader->getShared(AddonManager::class);
355
+		$this->addon_manager->initialize();
356
+		$this->loader->getShared('EE_Request_Handler');
357
+	}
358
+
359
+
360
+	/**
361
+	 * The purpose of this method is to simply check for a file named "caffeinated/brewing_regular.php" for any hooks
362
+	 * that need to be setup before our EE_System launches.
363
+	 *
364
+	 * @return void
365
+	 * @throws DomainException
366
+	 * @throws InvalidArgumentException
367
+	 * @throws InvalidDataTypeException
368
+	 * @throws InvalidInterfaceException
369
+	 * @throws InvalidClassException
370
+	 * @throws InvalidFilePathException
371
+	 * @throws EE_Error
372
+	 */
373
+	public function brewCaffeinated()
374
+	{
375
+		static $brew;
376
+		/** @var Domain $domain */
377
+		$domain = DomainFactory::getEventEspressoCoreDomain();
378
+		if ($domain->isCaffeinated() && ! $brew instanceof EE_Brewing_Regular) {
379
+			require_once EE_CAFF_PATH . 'brewing_regular.php';
380
+			/** @var EE_Brewing_Regular $brew */
381
+			$brew = LoaderFactory::getLoader()->getShared(EE_Brewing_Regular::class);
382
+			$brew->initializePUE();
383
+			add_action(
384
+				'AHEE__EE_System__load_core_configuration__begin',
385
+				[$brew, 'caffeinated']
386
+			);
387
+		}
388
+	}
389
+
390
+
391
+	/**
392
+	 * load_espresso_addons
393
+	 * allow addons to load first so that they can set hooks for running DMS's, etc
394
+	 * this is hooked into both:
395
+	 *    'AHEE__EE_Bootstrap__load_core_configuration'
396
+	 *        which runs during the WP 'plugins_loaded' action at priority 5
397
+	 *    and the WP 'activate_plugin' hook point
398
+	 *
399
+	 * @return void
400
+	 * @throws Exception
401
+	 */
402
+	public function load_espresso_addons()
403
+	{
404
+		// looking for hooks? they've been moved into the AddonManager to maintain compatibility
405
+		$this->addon_manager->loadAddons();
406
+	}
407
+
408
+
409
+	/**
410
+	 * detect_activations_or_upgrades
411
+	 * Checks for activation or upgrade of core first;
412
+	 * then also checks if any registered addons have been activated or upgraded
413
+	 * This is hooked into 'AHEE__EE_Bootstrap__detect_activations_or_upgrades'
414
+	 * which runs during the WP 'plugins_loaded' action at priority 3
415
+	 *
416
+	 * @access public
417
+	 * @return void
418
+	 */
419
+	public function detect_activations_or_upgrades()
420
+	{
421
+		// first off: let's make sure to handle core
422
+		$this->detect_if_activation_or_upgrade();
423
+		foreach ($this->registry->addons as $addon) {
424
+			if ($addon instanceof EE_Addon) {
425
+				// detect teh request type for that addon
426
+				$addon->detect_req_type();
427
+			}
428
+		}
429
+	}
430
+
431
+
432
+	/**
433
+	 * detect_if_activation_or_upgrade
434
+	 * Takes care of detecting whether this is a brand new install or code upgrade,
435
+	 * and either setting up the DB or setting up maintenance mode etc.
436
+	 *
437
+	 * @access public
438
+	 * @return void
439
+	 */
440
+	public function detect_if_activation_or_upgrade()
441
+	{
442
+		do_action('AHEE__EE_System___detect_if_activation_or_upgrade__begin');
443
+		// check if db has been updated, or if its a brand-new installation
444
+		$espresso_db_update = $this->fix_espresso_db_upgrade_option();
445
+		$request_type       = $this->detect_req_type($espresso_db_update);
446
+		switch ($request_type) {
447
+			case EE_System::req_type_new_activation:
448
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__new_activation');
449
+				$this->_handle_core_version_change($espresso_db_update);
450
+				break;
451
+			case EE_System::req_type_reactivation:
452
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__reactivation');
453
+				$this->_handle_core_version_change($espresso_db_update);
454
+				break;
455
+			case EE_System::req_type_upgrade:
456
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__upgrade');
457
+				// migrations may be required now that we've upgraded
458
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
459
+				$this->_handle_core_version_change($espresso_db_update);
460
+				break;
461
+			case EE_System::req_type_downgrade:
462
+				do_action('AHEE__EE_System__detect_if_activation_or_upgrade__downgrade');
463
+				// its possible migrations are no longer required
464
+				$this->maintenance_mode->set_maintenance_mode_if_db_old();
465
+				$this->_handle_core_version_change($espresso_db_update);
466
+				break;
467
+			case EE_System::req_type_normal:
468
+			default:
469
+				break;
470
+		}
471
+		do_action('AHEE__EE_System__detect_if_activation_or_upgrade__complete');
472
+	}
473
+
474
+
475
+	/**
476
+	 * Updates the list of installed versions and sets hooks for
477
+	 * initializing the database later during the request
478
+	 *
479
+	 * @param array $espresso_db_update
480
+	 */
481
+	private function _handle_core_version_change(array $espresso_db_update)
482
+	{
483
+		$this->update_list_of_installed_versions($espresso_db_update);
484
+		// get ready to verify the DB is ok (provided we aren't in maintenance mode, of course)
485
+		add_action(
486
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
487
+			[$this, 'initialize_db_if_no_migrations_required']
488
+		);
489
+	}
490
+
491
+
492
+	/**
493
+	 * standardizes the wp option 'espresso_db_upgrade' which actually stores
494
+	 * information about what versions of EE have been installed and activated,
495
+	 * NOT necessarily the state of the database
496
+	 *
497
+	 * @param mixed $espresso_db_update           the value of the WordPress option.
498
+	 *                                            If not supplied, fetches it from the options table
499
+	 * @return array the correct value of 'espresso_db_upgrade', after saving it, if it needed correction
500
+	 */
501
+	private function fix_espresso_db_upgrade_option($espresso_db_update = null): array
502
+	{
503
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__begin', $espresso_db_update);
504
+		if (! $espresso_db_update) {
505
+			$espresso_db_update = get_option('espresso_db_update');
506
+		}
507
+		// check that option is an array
508
+		if (! is_array($espresso_db_update)) {
509
+			// if option is FALSE, then it never existed
510
+			if ($espresso_db_update === false) {
511
+				// make $espresso_db_update an array and save option with autoload OFF
512
+				$espresso_db_update = [];
513
+				add_option('espresso_db_update', $espresso_db_update, '', 'no');
514
+			} else {
515
+				// option is NOT FALSE but also is NOT an array, so make it an array and save it
516
+				$espresso_db_update = [$espresso_db_update => []];
517
+				update_option('espresso_db_update', $espresso_db_update);
518
+			}
519
+		} else {
520
+			$corrected_db_update = [];
521
+			// if IS an array, but is it an array where KEYS are version numbers, and values are arrays?
522
+			foreach ($espresso_db_update as $should_be_version_string => $should_be_array) {
523
+				if (is_int($should_be_version_string) && ! is_array($should_be_array)) {
524
+					// the key is an int, and the value IS NOT an array
525
+					// so it must be numerically-indexed, where values are versions installed...
526
+					// fix it!
527
+					$version_string                         = $should_be_array;
528
+					$corrected_db_update[ $version_string ] = ['unknown-date'];
529
+				} else {
530
+					// ok it checks out
531
+					$corrected_db_update[ $should_be_version_string ] = $should_be_array;
532
+				}
533
+			}
534
+			$espresso_db_update = $corrected_db_update;
535
+			update_option('espresso_db_update', $espresso_db_update);
536
+		}
537
+		do_action('FHEE__EE_System__manage_fix_espresso_db_upgrade_option__complete', $espresso_db_update);
538
+		return ! empty($espresso_db_update)
539
+			? $espresso_db_update
540
+			: [];
541
+	}
542
+
543
+
544
+	/**
545
+	 * Does the traditional work of setting up the plugin's database and adding default data.
546
+	 * If migration script/process did not exist, this is what would happen on every activation/reactivation/upgrade.
547
+	 * NOTE: if we're in maintenance mode (which would be the case if we detect there are data
548
+	 * migration scripts that need to be run and a version change happens), enqueues core for database initialization,
549
+	 * so that it will be done when migrations are finished
550
+	 *
551
+	 * @param boolean $initialize_addons_too if true, we double-check addons' database tables etc too;
552
+	 * @param boolean $verify_schema         if true will re-check the database tables have the correct schema.
553
+	 *                                       This is a resource-intensive job
554
+	 *                                       so we prefer to only do it when necessary
555
+	 * @return void
556
+	 * @throws EE_Error
557
+	 * @throws ReflectionException
558
+	 */
559
+	public function initialize_db_if_no_migrations_required($initialize_addons_too = false, $verify_schema = true)
560
+	{
561
+		$request_type = $this->detect_req_type();
562
+		// only initialize system if we're not in maintenance mode.
563
+		if (! MaintenanceStatus::isFullSite()) {
564
+			/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
565
+			$rewrite_rules = $this->loader->getShared(
566
+				'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
567
+			);
568
+			$rewrite_rules->flush();
569
+			if ($verify_schema) {
570
+				EEH_Activation::initialize_db_and_folders();
571
+			}
572
+			EEH_Activation::initialize_db_content();
573
+			EEH_Activation::system_initialization();
574
+			if ($initialize_addons_too) {
575
+				$this->initialize_addons();
576
+			}
577
+		} else {
578
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for('Core');
579
+		}
580
+		if (
581
+			$request_type === EE_System::req_type_new_activation
582
+			|| $request_type === EE_System::req_type_reactivation
583
+			|| (
584
+				$request_type === EE_System::req_type_upgrade
585
+				&& $this->is_major_version_change()
586
+			)
587
+		) {
588
+			add_action('AHEE__EE_System__initialize_last', [$this, 'redirect_to_about_ee'], 9);
589
+		}
590
+	}
591
+
592
+
593
+	/**
594
+	 * Initializes the db for all registered addons
595
+	 *
596
+	 * @throws EE_Error
597
+	 * @throws ReflectionException
598
+	 */
599
+	public function initialize_addons()
600
+	{
601
+		// foreach registered addon, make sure its db is up-to-date too
602
+		foreach ($this->registry->addons as $addon) {
603
+			if ($addon instanceof EE_Addon) {
604
+				$addon->initialize_db_if_no_migrations_required();
605
+			}
606
+		}
607
+	}
608
+
609
+
610
+	/**
611
+	 * Adds the current code version to the saved wp option which stores a list of all ee versions ever installed.
612
+	 *
613
+	 * @param array  $version_history
614
+	 * @param string $current_version_to_add version to be added to the version history
615
+	 * @return    boolean success as to whether or not this option was changed
616
+	 */
617
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null): bool
618
+	{
619
+		if (! $version_history) {
620
+			$version_history = $this->fix_espresso_db_upgrade_option($version_history);
621
+		}
622
+		if ($current_version_to_add === null) {
623
+			$current_version_to_add = espresso_version();
624
+		}
625
+		$version_history[ $current_version_to_add ][] = date('Y-m-d H:i:s', time());
626
+		// re-save
627
+		return update_option('espresso_db_update', $version_history);
628
+	}
629
+
630
+
631
+	/**
632
+	 * Detects if the current version indicated in the has existed in the list of
633
+	 * previously-installed versions of EE (espresso_db_update). Does NOT modify it (ie, no side-effect)
634
+	 *
635
+	 * @param array|null $espresso_db_update array from the wp option stored under the name 'espresso_db_update'.
636
+	 *                                       If not supplied, fetches it from the options table.
637
+	 *                                       Also, caches its result so later parts of the code can also know whether
638
+	 *                                       there's been an update or not. This way we can add the current version to
639
+	 *                                       espresso_db_update, but still know if this is a new install or not
640
+	 * @return int one of the constants on EE_System::req_type_
641
+	 */
642
+	public function detect_req_type(?array $espresso_db_update = null): int
643
+	{
644
+		if ($this->_req_type === null) {
645
+			$espresso_db_update          = ! empty($espresso_db_update)
646
+				? $espresso_db_update
647
+				: $this->fix_espresso_db_upgrade_option();
648
+			$this->_req_type             = EE_System::detect_req_type_given_activation_history(
649
+				$espresso_db_update,
650
+				'ee_espresso_activation',
651
+				espresso_version()
652
+			);
653
+			$this->_major_version_change = $this->_detect_major_version_change($espresso_db_update);
654
+			$this->request->setIsActivation($this->_req_type !== EE_System::req_type_normal);
655
+		}
656
+		return $this->_req_type;
657
+	}
658
+
659
+
660
+	/**
661
+	 * Returns whether or not there was a non-micro version change (ie, change in either
662
+	 * the first or second number in the version. Eg 4.9.0.rc.001 to 4.10.0.rc.000,
663
+	 * but not 4.9.0.rc.0001 to 4.9.1.rc.0001
664
+	 *
665
+	 * @param $activation_history
666
+	 * @return bool
667
+	 */
668
+	private function _detect_major_version_change($activation_history): bool
669
+	{
670
+		$previous_version       = EE_System::getMostRecentlyActiveVersion($activation_history);
671
+		$previous_version_parts = explode('.', $previous_version);
672
+		$current_version_parts  = explode('.', espresso_version());
673
+		return isset(
674
+				   $previous_version_parts[0],
675
+				   $previous_version_parts[1],
676
+				   $current_version_parts[0],
677
+				   $current_version_parts[1]
678
+			   ) && (
679
+				   $previous_version_parts[0] !== $current_version_parts[0]
680
+				   || $previous_version_parts[1] !== $current_version_parts[1]
681
+			   );
682
+	}
683
+
684
+
685
+	/**
686
+	 * Returns true if either the major or minor version of EE changed during this request.
687
+	 * 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
688
+	 *
689
+	 * @return bool
690
+	 */
691
+	public function is_major_version_change(): bool
692
+	{
693
+		return $this->_major_version_change;
694
+	}
695
+
696
+
697
+	/**
698
+	 * Determines the request type for any ee addon, given three piece of info: the current array of activation
699
+	 * histories (for core that' 'espresso_db_update' wp option); the name of the WordPress option which is temporarily
700
+	 * set upon activation of the plugin (for core it's 'ee_espresso_activation'); and the version that this plugin was
701
+	 * just activated to (for core that will always be espresso_version())
702
+	 *
703
+	 * @param array|null $activation_history               the option's value which stores the activation history for
704
+	 *                                                     this
705
+	 *                                                     ee plugin. for core that's 'espresso_db_update'
706
+	 * @param string     $activation_indicator_option_name the name of the WordPress option that is temporarily set to
707
+	 *                                                     indicate that this plugin was just activated
708
+	 * @param string     $current_version                  the version that was just upgraded to (for core that will be
709
+	 *                                                     espresso_version())
710
+	 * @return int one of the constants on EE_System::req_type_
711
+	 */
712
+	public static function detect_req_type_given_activation_history(
713
+		array $activation_history,
714
+		string $activation_indicator_option_name,
715
+		string $current_version
716
+	): int {
717
+		$version_change = self::compareVersionWithPrevious($activation_history, $current_version);
718
+		$is_activation  = get_option($activation_indicator_option_name, false);
719
+		$req_type       = self::getRequestType($activation_history, $version_change, $is_activation);
720
+		if ($is_activation) {
721
+			// cleanup in aisle 6
722
+			delete_option($activation_indicator_option_name);
723
+		}
724
+		return $req_type;
725
+	}
726
+
727
+
728
+	/**
729
+	 * @param array $activation_history
730
+	 * @param int   $version_change
731
+	 * @param bool  $is_activation
732
+	 * @return int
733
+	 * @since 5.0.0.p
734
+	 */
735
+	private static function getRequestType(array $activation_history, int $version_change, bool $is_activation): int
736
+	{
737
+		// if no previous activation history exists, then this is a brand new install
738
+		if (empty($activation_history)) {
739
+			return EE_System::req_type_new_activation;
740
+		}
741
+		// current version is higher than previous version, so it's an upgrade
742
+		if ($version_change === 1) {
743
+			return EE_System::req_type_upgrade;
744
+		}
745
+		// current version is lower than previous version, so it's a downgrade
746
+		if ($version_change === -1) {
747
+			return EE_System::req_type_downgrade;
748
+		}
749
+		// version hasn't changed since last version so check if the activation indicator is set
750
+		// to determine if it's a reactivation, or just a normal request
751
+		return $is_activation
752
+			? EE_System::req_type_reactivation
753
+			: EE_System::req_type_normal;
754
+	}
755
+
756
+
757
+	/**
758
+	 * Detects if the $version_to_upgrade_to is higher than the most recent version in
759
+	 * the $activation_history_for_addon
760
+	 *
761
+	 * @param array  $activation_history    array where keys are versions,
762
+	 *                                      values are arrays of times activated (sometimes 'unknown-date')
763
+	 * @param string $current_version
764
+	 * @return int results of version_compare( $version_to_upgrade_to, $most_recently_active_version ).
765
+	 *                                      -1 if $version_to_upgrade_to is LOWER (downgrade);
766
+	 *                                      0 if $version_to_upgrade_to MATCHES (reactivation or normal request);
767
+	 *                                      1 if $version_to_upgrade_to is HIGHER (upgrade) ;
768
+	 */
769
+	private static function compareVersionWithPrevious(array $activation_history, string $current_version): int
770
+	{
771
+		// find the most recently-activated version
772
+		$most_recently_active_version = EE_System::getMostRecentlyActiveVersion($activation_history);
773
+		return version_compare($current_version, $most_recently_active_version);
774
+	}
775
+
776
+
777
+	/**
778
+	 * Gets the most recently active version listed in the activation history,
779
+	 * and if none are found (ie, it's a brand new install) returns '0.0.0.dev.000'.
780
+	 *
781
+	 * @param array|null $activation_history (keys are versions, values are arrays of times activated,
782
+	 *                                       sometimes containing 'unknown-date'
783
+	 * @return string
784
+	 */
785
+	private static function getMostRecentlyActiveVersion(?array $activation_history): string
786
+	{
787
+		$most_recent_activation_date  = '1970-01-01 00:00:00';
788
+		$most_recently_active_version = '0.0.0.dev.000';
789
+		if (is_array($activation_history)) {
790
+			foreach ($activation_history as $version => $activation_dates) {
791
+				// check there is a record of when this version was activated.
792
+				// Otherwise, mark it as unknown
793
+				if (! $activation_dates) {
794
+					$activation_dates = ['unknown-date'];
795
+				}
796
+				$activation_dates = is_string($activation_dates)
797
+					? [$activation_dates]
798
+					: $activation_dates;
799
+				foreach ($activation_dates as $activation_date) {
800
+					if ($activation_date !== 'unknown-date' && $activation_date > $most_recent_activation_date) {
801
+						$most_recently_active_version = $version;
802
+						$most_recent_activation_date  = $activation_date;
803
+					}
804
+				}
805
+			}
806
+		}
807
+		return $most_recently_active_version;
808
+	}
809
+
810
+
811
+	/**
812
+	 * This redirects to the about EE page after activation
813
+	 *
814
+	 * @return void
815
+	 */
816
+	public function redirect_to_about_ee()
817
+	{
818
+		$notices = EE_Error::get_notices(false);
819
+		// if current user is an admin and it's not an ajax or rest request
820
+		if (
821
+			! isset($notices['errors'])
822
+			&& $this->request->isAdmin()
823
+			&& apply_filters(
824
+				'FHEE__EE_System__redirect_to_about_ee__do_redirect',
825
+				$this->capabilities->current_user_can('manage_options', 'espresso_about_default')
826
+			)
827
+		) {
828
+			$query_params = ['page' => 'espresso_about'];
829
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_new_activation) {
830
+				$query_params['new_activation'] = true;
831
+			}
832
+			if (EE_System::instance()->detect_req_type() === EE_System::req_type_reactivation) {
833
+				$query_params['reactivation'] = true;
834
+			}
835
+			$url = add_query_arg($query_params, admin_url('admin.php'));
836
+			EEH_URL::safeRedirectAndExit($url);
837
+		}
838
+	}
839
+
840
+
841
+	/**
842
+	 * load_core_configuration
843
+	 * this is hooked into 'AHEE__EE_Bootstrap__load_core_configuration'
844
+	 * which runs during the WP 'plugins_loaded' action at priority 5
845
+	 *
846
+	 * @return void
847
+	 * @throws ReflectionException
848
+	 * @throws Exception
849
+	 */
850
+	public function load_core_configuration()
851
+	{
852
+		do_action('AHEE__EE_System__load_core_configuration__begin', $this);
853
+		$this->loader->getShared('EE_Load_Textdomain');
854
+		// load textdomain
855
+		EE_Load_Textdomain::load_textdomain();
856
+		// load and setup EE_Config and EE_Network_Config
857
+		$config = $this->loader->getShared('EE_Config');
858
+		$this->loader->getShared('EE_Network_Config');
859
+		// setup autoloaders
860
+		// enable logging?
861
+		$this->loader->getShared('EventEspresso\core\services\orm\TrashLogger');
862
+		if ($config->admin->use_remote_logging) {
863
+			$this->loader->getShared('EE_Log');
864
+		}
865
+		// check for activation errors
866
+		$activation_errors = get_option('ee_plugin_activation_errors', false);
867
+		if ($activation_errors) {
868
+			EE_Error::add_error($activation_errors, __FILE__, __FUNCTION__, __LINE__);
869
+			update_option('ee_plugin_activation_errors', false);
870
+		}
871
+		// get model names
872
+		$this->_parse_model_names();
873
+		// configure custom post type definitions
874
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomTaxonomyDefinitions');
875
+		$this->loader->getShared('EventEspresso\core\domain\entities\custom_post_types\CustomPostTypeDefinitions');
876
+		do_action('AHEE__EE_System__load_core_configuration__complete', $this);
877
+	}
878
+
879
+
880
+	/**
881
+	 * cycles through all of the models/*.model.php files, and assembles an array of model names
882
+	 *
883
+	 * @return void
884
+	 * @throws ReflectionException
885
+	 */
886
+	private function _parse_model_names()
887
+	{
888
+		// get all the files in the EE_MODELS folder that end in .model.php
889
+		$models                 = glob(EE_MODELS . '*.model.php');
890
+		$model_names            = [];
891
+		$non_abstract_db_models = [];
892
+		foreach ($models as $model) {
893
+			// get model classname
894
+			$classname       = EEH_File::get_classname_from_filepath_with_standard_filename($model);
895
+			$short_name      = str_replace('EEM_', '', $classname);
896
+			$reflectionClass = new ReflectionClass($classname);
897
+			if ($reflectionClass->isSubclassOf('EEM_Base') && ! $reflectionClass->isAbstract()) {
898
+				$non_abstract_db_models[ $short_name ] = $classname;
899
+			}
900
+			$model_names[ $short_name ] = $classname;
901
+		}
902
+		$this->registry->models                 = apply_filters('FHEE__EE_System__parse_model_names', $model_names);
903
+		$this->registry->non_abstract_db_models = apply_filters(
904
+			'FHEE__EE_System__parse_implemented_model_names',
905
+			$non_abstract_db_models
906
+		);
907
+	}
908
+
909
+
910
+	/**
911
+	 * @throws Exception
912
+	 * @since 4.9.71.p
913
+	 */
914
+	public function loadRouteMatchSpecifications()
915
+	{
916
+		try {
917
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteMatchSpecificationManager');
918
+			$this->loader->getShared('EventEspresso\core\services\routing\RouteCollection');
919
+			$this->router->loadPrimaryRoutes();
920
+		} catch (Exception $exception) {
921
+			new ExceptionStackTraceDisplay($exception);
922
+		}
923
+		do_action('AHEE__EE_System__loadRouteMatchSpecifications');
924
+	}
925
+
926
+
927
+	/**
928
+	 * loading CPT related classes earlier so that their definitions are available
929
+	 * but not performing any actual registration with WP core until load_CPTs_and_session() is called
930
+	 *
931
+	 * @since   4.10.21.p
932
+	 */
933
+	public function loadCustomPostTypes()
934
+	{
935
+		$this->register_custom_taxonomies     = $this->loader->getShared(
936
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomies'
937
+		);
938
+		$this->register_custom_post_types     = $this->loader->getShared(
939
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomPostTypes'
940
+		);
941
+		$this->register_custom_taxonomy_terms = $this->loader->getShared(
942
+			'EventEspresso\core\domain\services\custom_post_types\RegisterCustomTaxonomyTerms'
943
+		);
944
+		// integrate WP_Query with the EE models
945
+		$this->loader->getShared('EE_CPT_Strategy');
946
+		// load legacy EE_Request_Handler in case add-ons still need it
947
+		$this->loader->getShared('EE_Request_Handler');
948
+	}
949
+
950
+
951
+	/**
952
+	 * register_shortcodes_modules_and_widgets
953
+	 * generate lists of shortcodes and modules, then verify paths and classes
954
+	 * This is hooked into 'AHEE__EE_Bootstrap__register_shortcodes_modules_and_widgets'
955
+	 * which runs during the WP 'plugins_loaded' action at priority 7
956
+	 *
957
+	 * @access public
958
+	 * @return void
959
+	 * @throws Exception
960
+	 */
961
+	public function register_shortcodes_modules_and_widgets()
962
+	{
963
+		$this->router->registerShortcodesModulesAndWidgets();
964
+		do_action('AHEE__EE_System__register_shortcodes_modules_and_widgets');
965
+		// check for addons using old hook point
966
+		if (has_action('AHEE__EE_System__register_shortcodes_modules_and_addons')) {
967
+			$this->_incompatible_addon_error();
968
+		}
969
+	}
970
+
971
+
972
+	/**
973
+	 * _incompatible_addon_error
974
+	 *
975
+	 * @access public
976
+	 * @return void
977
+	 */
978
+	private function _incompatible_addon_error()
979
+	{
980
+		// get array of classes hooking into here
981
+		$class_names = WordPressHooks::getClassNamesForAllCallbacksOnHook(
982
+			'AHEE__EE_System__register_shortcodes_modules_and_addons'
983
+		);
984
+		if (! empty($class_names)) {
985
+			$msg = esc_html__(
986
+				'The following plugins, addons, or modules appear to be incompatible with this version of Event Espresso and were automatically deactivated to avoid fatal errors:',
987
+				'event_espresso'
988
+			);
989
+			$msg .= '<ul>';
990
+			foreach ($class_names as $class_name) {
991
+				$msg .= '<li><b>Event Espresso - '
992
+						. str_replace(
993
+							['EE_', 'EEM_', 'EED_', 'EES_', 'EEW_'],
994
+							'',
995
+							$class_name
996
+						) . '</b></li>';
997
+			}
998
+			$msg .= '</ul>';
999
+			$msg .= esc_html__(
1000
+				'Compatibility issues can be avoided and/or resolved by keeping addons and plugins updated to the latest version.',
1001
+				'event_espresso'
1002
+			);
1003
+			// save list of incompatible addons to wp-options for later use
1004
+			add_option('ee_incompatible_addons', $class_names, '', 'no');
1005
+			if (is_admin()) {
1006
+				EE_Error::add_error($msg, __FILE__, __FUNCTION__, __LINE__);
1007
+			}
1008
+		}
1009
+	}
1010
+
1011
+
1012
+	/**
1013
+	 * brew_espresso
1014
+	 * begins the process of setting hooks for initializing EE in the correct order
1015
+	 * This is happening on the 'AHEE__EE_Bootstrap__brew_espresso' hook point
1016
+	 * which runs during the WP 'plugins_loaded' action at priority 9
1017
+	 *
1018
+	 * @return void
1019
+	 * @throws Exception
1020
+	 */
1021
+	public function brew_espresso()
1022
+	{
1023
+		do_action('AHEE__EE_System__brew_espresso__begin', $this);
1024
+		// load some final core systems
1025
+		add_action('init', [$this, 'set_hooks_for_core'], 1);
1026
+		add_action('init', [$this, 'perform_activations_upgrades_and_migrations'], 3);
1027
+		add_action('init', [$this, 'load_CPTs_and_session'], 5);
1028
+		add_action('init', [$this, 'load_controllers'], 7);
1029
+		add_action('init', [$this, 'core_loaded_and_ready'], 9);
1030
+		add_action('init', [$this, 'initialize'], 10);
1031
+		add_action('init', [$this, 'initialize_last'], 100);
1032
+		$this->router->brewEspresso();
1033
+		$this->loader->getShared('EventEspresso\PaymentMethods\Manager');
1034
+		$this->loader->getShared('EE_Payment_Method_Manager');
1035
+		do_action('AHEE__EE_System__brew_espresso__complete', $this);
1036
+	}
1037
+
1038
+
1039
+	/**
1040
+    /**
1041
+	 *    set_hooks_for_core
1042
+	 *
1043
+	 * @access public
1044
+	 * @return    void
1045
+	 * @throws EE_Error
1046
+	 */
1047
+	public function set_hooks_for_core()
1048
+	{
1049
+		$this->_deactivate_incompatible_addons();
1050
+		do_action('AHEE__EE_System__set_hooks_for_core');
1051
+		$this->loader->getShared('EventEspresso\core\domain\values\session\SessionLifespan');
1052
+		// caps need to be initialized on every request so that capability maps are set.
1053
+		// @see https://events.codebasehq.com/projects/event-espresso/tickets/8674
1054
+		$this->capabilities->init_caps();
1055
+	}
1056
+
1057
+
1058
+	/**
1059
+	 * Using the information gathered in EE_System::_incompatible_addon_error,
1060
+	 * deactivates any addons considered incompatible with the current version of EE
1061
+	 */
1062
+	private function _deactivate_incompatible_addons()
1063
+	{
1064
+		$incompatible_addons = get_option('ee_incompatible_addons', []);
1065
+		if (! empty($incompatible_addons)) {
1066
+			$active_plugins = get_option('active_plugins', []);
1067
+			foreach ($active_plugins as $active_plugin) {
1068
+				foreach ($incompatible_addons as $incompatible_addon) {
1069
+					if (strpos($active_plugin, $incompatible_addon) !== false) {
1070
+						$this->request->unSetRequestParams(['activate'], true);
1071
+						espresso_deactivate_plugin($active_plugin);
1072
+					}
1073
+				}
1074
+			}
1075
+		}
1076
+	}
1077
+
1078
+
1079
+	/**
1080
+	 *    perform_activations_upgrades_and_migrations
1081
+	 *
1082
+	 * @access public
1083
+	 * @return    void
1084
+	 */
1085
+	public function perform_activations_upgrades_and_migrations()
1086
+	{
1087
+		do_action('AHEE__EE_System__perform_activations_upgrades_and_migrations');
1088
+	}
1089
+
1090
+
1091
+	/**
1092
+	 * @return void
1093
+	 * @throws DomainException
1094
+	 */
1095
+	public function load_CPTs_and_session()
1096
+	{
1097
+		do_action('AHEE__EE_System__load_CPTs_and_session__start');
1098
+		$this->register_custom_taxonomies->registerCustomTaxonomies();
1099
+		$this->register_custom_post_types->registerCustomPostTypes();
1100
+		$this->register_custom_taxonomy_terms->registerCustomTaxonomyTerms();
1101
+		do_action('AHEE__EE_System__load_CPTs_and_session__complete');
1102
+	}
1103
+
1104
+
1105
+	/**
1106
+	 * load_controllers
1107
+	 * this is the best place to load any additional controllers that needs access to EE core.
1108
+	 * it is expected that all basic core EE systems, that are not dependant on the current request are loaded at this
1109
+	 * time
1110
+	 *
1111
+	 * @access public
1112
+	 * @return void
1113
+	 * @throws Exception
1114
+	 */
1115
+	public function load_controllers()
1116
+	{
1117
+		do_action('AHEE__EE_System__load_controllers__start');
1118
+		$this->router->loadControllers();
1119
+		do_action('AHEE__EE_System__load_controllers__complete');
1120
+	}
1121
+
1122
+
1123
+	/**
1124
+	 * core_loaded_and_ready
1125
+	 * all of the basic EE core should be loaded at this point and available regardless of M-Mode
1126
+	 *
1127
+	 * @access public
1128
+	 * @return void
1129
+	 * @throws Exception
1130
+	 */
1131
+	public function core_loaded_and_ready()
1132
+	{
1133
+		$this->router->coreLoadedAndReady();
1134
+		do_action('AHEE__EE_System__core_loaded_and_ready');
1135
+		// always load template tags, because it's faster than checking if it's a front-end request, and many page
1136
+		// builders require these even on the front-end
1137
+		require_once EE_PUBLIC . 'template_tags.php';
1138
+		do_action('AHEE__EE_System__set_hooks_for_shortcodes_modules_and_addons');
1139
+	}
1140
+
1141
+
1142
+	/**
1143
+	 * initialize
1144
+	 * this is the best place to begin initializing client code
1145
+	 *
1146
+	 * @access public
1147
+	 * @return void
1148
+	 */
1149
+	public function initialize()
1150
+	{
1151
+		do_action('AHEE__EE_System__initialize');
1152
+		add_filter(
1153
+			'safe_style_css',
1154
+			function ($styles) {
1155
+				$styles[] = 'display';
1156
+				$styles[] = 'visibility';
1157
+				$styles[] = 'position';
1158
+				$styles[] = 'top';
1159
+				$styles[] = 'right';
1160
+				$styles[] = 'bottom';
1161
+				$styles[] = 'left';
1162
+				$styles[] = 'resize';
1163
+				$styles[] = 'max-width';
1164
+				$styles[] = 'max-height';
1165
+				return $styles;
1166
+			}
1167
+		);
1168
+	}
1169
+
1170
+
1171
+	/**
1172
+	 * initialize_last
1173
+	 * this is run really late during the WP init hook point, and ensures that mostly everything else that needs to
1174
+	 * initialize has done so
1175
+	 *
1176
+	 * @access public
1177
+	 * @return void
1178
+	 * @throws Exception
1179
+	 */
1180
+	public function initialize_last()
1181
+	{
1182
+		$this->router->initializeLast();
1183
+		do_action('AHEE__EE_System__initialize_last');
1184
+		/** @var EventEspresso\core\domain\services\custom_post_types\RewriteRules $rewrite_rules */
1185
+		$rewrite_rules = $this->loader->getShared(
1186
+			'EventEspresso\core\domain\services\custom_post_types\RewriteRules'
1187
+		);
1188
+		$rewrite_rules->flushRewriteRules();
1189
+		add_action('admin_bar_init', [$this, 'addEspressoToolbar']);
1190
+	}
1191
+
1192
+
1193
+	/**
1194
+	 * @return void
1195
+	 */
1196
+	public function addEspressoToolbar()
1197
+	{
1198
+		$this->loader->getShared(
1199
+			'EventEspresso\core\domain\services\admin\AdminToolBar',
1200
+			[$this->capabilities]
1201
+		);
1202
+	}
1203
+
1204
+
1205
+	/**
1206
+	 * do_not_cache
1207
+	 * sets no cache headers and defines no cache constants for WP plugins
1208
+	 *
1209
+	 * @access public
1210
+	 * @return void
1211
+	 */
1212
+	public static function do_not_cache()
1213
+	{
1214
+		// set no cache constants
1215
+		if (! defined('DONOTCACHEPAGE')) {
1216
+			define('DONOTCACHEPAGE', true);
1217
+		}
1218
+		if (! defined('DONOTCACHCEOBJECT')) {
1219
+			define('DONOTCACHCEOBJECT', true);
1220
+		}
1221
+		if (! defined('DONOTCACHEDB')) {
1222
+			define('DONOTCACHEDB', true);
1223
+		}
1224
+		// add no cache headers
1225
+		add_action('send_headers', ['EE_System', 'nocache_headers'], 10);
1226
+		// plus a little extra for nginx and Google Chrome
1227
+		add_filter('nocache_headers', ['EE_System', 'extra_nocache_headers'], 10, 1);
1228
+		// prevent browsers from prefetching of the rel='next' link, because it may contain content that interferes with the registration process
1229
+		remove_action('wp_head', 'adjacent_posts_rel_link_wp_head');
1230
+	}
1231
+
1232
+
1233
+	/**
1234
+	 *    extra_nocache_headers
1235
+	 *
1236
+	 * @access    public
1237
+	 * @param $headers
1238
+	 * @return    array
1239
+	 */
1240
+	public static function extra_nocache_headers($headers): array
1241
+	{
1242
+		// for NGINX
1243
+		$headers['X-Accel-Expires'] = 0;
1244
+		// plus extra for Google Chrome since it doesn't seem to respect "no-cache", but WILL respect "no-store"
1245
+		$headers['Cache-Control'] = 'no-store, no-cache, must-revalidate, max-age=0';
1246
+		return $headers;
1247
+	}
1248
+
1249
+
1250
+	/**
1251
+	 *    nocache_headers
1252
+	 *
1253
+	 * @access    public
1254
+	 * @return    void
1255
+	 */
1256
+	public static function nocache_headers()
1257
+	{
1258
+		nocache_headers();
1259
+	}
1260
+
1261
+
1262
+	/**
1263
+	 * simply hooks into "wp_list_pages_exclude" filter (for wp_list_pages method) and makes sure EE critical pages are
1264
+	 * never returned with the function.
1265
+	 *
1266
+	 * @param array $exclude_array any existing pages being excluded are in this array.
1267
+	 * @return array
1268
+	 */
1269
+	public function remove_pages_from_wp_list_pages(array $exclude_array): array
1270
+	{
1271
+		return array_merge($exclude_array, $this->registry->CFG->core->get_critical_pages_array());
1272
+	}
1273 1273
 }
Please login to merge, or discard this patch.
core/domain/services/admin/notices/status_change/StatusChangeNotice.php 1 patch
Indentation   +96 added lines, -96 removed lines patch added patch discarded remove patch
@@ -16,112 +16,112 @@
 block discarded – undo
16 16
  */
17 17
 class StatusChangeNotice extends WordPressOption
18 18
 {
19
-    public function __construct()
20
-    {
21
-        parent::__construct('ee_hide_status_change_notices_for_users', []);
22
-    }
19
+	public function __construct()
20
+	{
21
+		parent::__construct('ee_hide_status_change_notices_for_users', []);
22
+	}
23 23
 
24 24
 
25
-    public static function loadAssets()
26
-    {
27
-        wp_enqueue_style(
28
-            'status_change_notice',
29
-            EE_PLUGIN_DIR_URL . 'core/domain/services/admin/notices/status_change/status_change_notice.css',
30
-            ['espresso_menu'],
31
-            EVENT_ESPRESSO_VERSION
32
-        );
33
-        wp_enqueue_script(
34
-            'status_change_notice',
35
-            EE_PLUGIN_DIR_URL . 'core/domain/services/admin/notices/status_change/status_change_notice.js',
36
-            ['jquery'],
37
-            EVENT_ESPRESSO_VERSION,
38
-            true
39
-        );
40
-        wp_localize_script(
41
-            'status_change_notice',
42
-            'eeStatusChangeNotice',
43
-            [
44
-                'failed_request_msg' => wp_strip_all_tags(
45
-                    __(
46
-                        'Request failed. The server returned status code: ',
47
-                        'event_espresso'
48
-                    )
49
-                ),
50
-                'unknown_error_msg' => wp_strip_all_tags(
51
-                    __(
52
-                        'Oops... an unknown error has occurred on the server and this notice could not be dismissed.',
53
-                        'event_espresso'
54
-                    )
55
-                ),
56
-            ]
57
-        );
58
-    }
25
+	public static function loadAssets()
26
+	{
27
+		wp_enqueue_style(
28
+			'status_change_notice',
29
+			EE_PLUGIN_DIR_URL . 'core/domain/services/admin/notices/status_change/status_change_notice.css',
30
+			['espresso_menu'],
31
+			EVENT_ESPRESSO_VERSION
32
+		);
33
+		wp_enqueue_script(
34
+			'status_change_notice',
35
+			EE_PLUGIN_DIR_URL . 'core/domain/services/admin/notices/status_change/status_change_notice.js',
36
+			['jquery'],
37
+			EVENT_ESPRESSO_VERSION,
38
+			true
39
+		);
40
+		wp_localize_script(
41
+			'status_change_notice',
42
+			'eeStatusChangeNotice',
43
+			[
44
+				'failed_request_msg' => wp_strip_all_tags(
45
+					__(
46
+						'Request failed. The server returned status code: ',
47
+						'event_espresso'
48
+					)
49
+				),
50
+				'unknown_error_msg' => wp_strip_all_tags(
51
+					__(
52
+						'Oops... an unknown error has occurred on the server and this notice could not be dismissed.',
53
+						'event_espresso'
54
+					)
55
+				),
56
+			]
57
+		);
58
+	}
59 59
 
60 60
 
61
-    public function display(string $context, string $page_slug): string
62
-    {
63
-        return $this->isNotDismissed()
64
-            ? EEH_Template::display_template(
65
-                __DIR__ . '/status_change_notice.template.php',
66
-                [
67
-                    'context'   => $context,
68
-                    'page_slug' => ! empty($page_slug) ? "$page_slug-page" : '',
69
-                ],
70
-                true
71
-            )
72
-            : '';
73
-    }
61
+	public function display(string $context, string $page_slug): string
62
+	{
63
+		return $this->isNotDismissed()
64
+			? EEH_Template::display_template(
65
+				__DIR__ . '/status_change_notice.template.php',
66
+				[
67
+					'context'   => $context,
68
+					'page_slug' => ! empty($page_slug) ? "$page_slug-page" : '',
69
+				],
70
+				true
71
+			)
72
+			: '';
73
+	}
74 74
 
75 75
 
76
-    /**
77
-     * @return int
78
-     * @throws RuntimeException
79
-     */
80
-    public function dismiss(): int
81
-    {
82
-        $user      = $this->getCurrentUser();
83
-        $dismissed = (array) $this->loadOption();
84
-        if (! in_array($user, $dismissed)) {
85
-            $dismissed[] = $user;
86
-        }
87
-        return $this->updateOption($dismissed);
88
-    }
76
+	/**
77
+	 * @return int
78
+	 * @throws RuntimeException
79
+	 */
80
+	public function dismiss(): int
81
+	{
82
+		$user      = $this->getCurrentUser();
83
+		$dismissed = (array) $this->loadOption();
84
+		if (! in_array($user, $dismissed)) {
85
+			$dismissed[] = $user;
86
+		}
87
+		return $this->updateOption($dismissed);
88
+	}
89 89
 
90 90
 
91
-    /**
92
-     * @return bool
93
-     * @throws RuntimeException
94
-     */
95
-    public function isDismissed(): bool
96
-    {
97
-        $user      = $this->getCurrentUser();
98
-        $dismissed = (array) $this->loadOption();
99
-        return in_array($user, $dismissed);
100
-    }
91
+	/**
92
+	 * @return bool
93
+	 * @throws RuntimeException
94
+	 */
95
+	public function isDismissed(): bool
96
+	{
97
+		$user      = $this->getCurrentUser();
98
+		$dismissed = (array) $this->loadOption();
99
+		return in_array($user, $dismissed);
100
+	}
101 101
 
102 102
 
103
-    /**
104
-     * @return bool
105
-     * @throws RuntimeException
106
-     */
107
-    public function isNotDismissed(): bool
108
-    {
109
-        return ! $this->isDismissed();
110
-    }
103
+	/**
104
+	 * @return bool
105
+	 * @throws RuntimeException
106
+	 */
107
+	public function isNotDismissed(): bool
108
+	{
109
+		return ! $this->isDismissed();
110
+	}
111 111
 
112 112
 
113
-    /**
114
-     * @return string
115
-     * @throws RuntimeException
116
-     */
117
-    private function getCurrentUser(): string
118
-    {
119
-        $user = wp_get_current_user();
120
-        if (! $user instanceof WP_User || ! $user->exists()) {
121
-            throw new RuntimeException(
122
-                esc_html__('A valid WP User could not be retrieved.', 'event_espresso')
123
-            );
124
-        }
125
-        return $user->user_login;
126
-    }
113
+	/**
114
+	 * @return string
115
+	 * @throws RuntimeException
116
+	 */
117
+	private function getCurrentUser(): string
118
+	{
119
+		$user = wp_get_current_user();
120
+		if (! $user instanceof WP_User || ! $user->exists()) {
121
+			throw new RuntimeException(
122
+				esc_html__('A valid WP User could not be retrieved.', 'event_espresso')
123
+			);
124
+		}
125
+		return $user->user_login;
126
+	}
127 127
 }
Please login to merge, or discard this patch.
core/domain/services/admin/registrations/list_table/QueryBuilder.php 2 patches
Indentation   +412 added lines, -412 removed lines patch added patch discarded remove patch
@@ -22,416 +22,416 @@
 block discarded – undo
22 22
  */
23 23
 class QueryBuilder
24 24
 {
25
-    protected RequestInterface $request;
26
-
27
-    protected EEM_Registration $registration_model;
28
-
29
-    protected array $filters;
30
-
31
-    protected string $view;
32
-
33
-    protected array $where_params;
34
-
35
-
36
-    /**
37
-     * QueryBuilder constructor.
38
-     *
39
-     * @param RequestInterface $request
40
-     * @param EEM_Registration $registration_model
41
-     * @param array            $extra_request_params
42
-     */
43
-    public function __construct(
44
-        RequestInterface $request,
45
-        EEM_Registration $registration_model,
46
-        array $extra_request_params = []
47
-    ) {
48
-        $this->request = $request;
49
-        $this->filters = $this->request->getRequestParam('filters', [], DataType::STRING, true);
50
-        $this->registration_model = $registration_model;
51
-        foreach ($extra_request_params as $key => $value) {
52
-            if (! $this->request->requestParamIsSet($key)) {
53
-                $this->request->setRequestParam($key, $value);
54
-            }
55
-        }
56
-        $this->view = $this->request->getRequestParam('status', '');
57
-        $this->where_params = [];
58
-    }
59
-
60
-
61
-    /**
62
-     * Sets up the where conditions for the registrations query.
63
-     *
64
-     * @param int  $per_page
65
-     * @param bool $count_query
66
-     * @return array
67
-     * @throws EE_Error
68
-     * @throws InvalidArgumentException
69
-     * @throws InvalidDataTypeException
70
-     * @throws InvalidInterfaceException
71
-     */
72
-    public function getQueryParams(int $per_page = 10, bool $count_query = false): array
73
-    {
74
-        $query_params = [
75
-            0                          => $this->getWhereClause(),
76
-            'caps'                     => EEM_Base::caps_read_admin,
77
-            'default_where_conditions' => 'this_model_only',
78
-        ];
79
-        if (! $count_query) {
80
-            $query_params = array_merge(
81
-                $query_params,
82
-                $this->getOrderbyClause(),
83
-                $this->getLimitClause($per_page)
84
-            );
85
-        }
86
-
87
-        return $query_params;
88
-    }
89
-
90
-
91
-    /**
92
-     * Sets up the where conditions for the registrations query.
93
-     *
94
-     * @return array
95
-     * @throws EE_Error
96
-     * @throws InvalidArgumentException
97
-     * @throws InvalidDataTypeException
98
-     * @throws InvalidInterfaceException
99
-     */
100
-    protected function getWhereClause(): array
101
-    {
102
-        $this->addAttendeeIdToWhereConditions();
103
-        $this->addEventIdToWhereConditions();
104
-        $this->addCategoryIdToWhereConditions();
105
-        $this->addDatetimeIdToWhereConditions();
106
-        $this->addTicketIdToWhereConditions();
107
-        $this->addRegistrationStatusToWhereConditions();
108
-        $this->addDateToWhereConditions();
109
-        $this->addSearchToWhereConditions();
110
-        return apply_filters(
111
-            'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
112
-            $this->where_params,
113
-            $this->request->requestParams()
114
-        );
115
-    }
116
-
117
-
118
-    /**
119
-     * This will add ATT_ID to the provided $this->where_clause array for EE model query parameters.
120
-     */
121
-    protected function addAttendeeIdToWhereConditions()
122
-    {
123
-        $ATT_ID = $this->request->getRequestParam('attendee_id');
124
-        $ATT_ID = $this->request->getRequestParam('ATT_ID', $ATT_ID, 'int');
125
-        if ($ATT_ID) {
126
-            $this->where_params['ATT_ID'] = $ATT_ID;
127
-        }
128
-    }
129
-
130
-
131
-    /**
132
-     * This will add EVT_ID to the provided $this->where_clause array for EE model query parameters.
133
-     */
134
-    protected function addEventIdToWhereConditions()
135
-    {
136
-        $EVT_ID = $this->request->getRequestParam('event_id');
137
-        $EVT_ID = $this->request->getRequestParam('EVT_ID', $EVT_ID, 'int');
138
-        if ($EVT_ID) {
139
-            $this->where_params['EVT_ID'] = $EVT_ID;
140
-        }
141
-    }
142
-
143
-
144
-    /**
145
-     * Adds category ID if it exists in the request to the where conditions for the registrations query.
146
-     */
147
-    protected function addCategoryIdToWhereConditions()
148
-    {
149
-        $EVT_CAT = $this->request->getRequestParam('EVT_CAT', 0, DataType::INTEGER);
150
-        $EVT_CAT = $this->filters['EVT_CAT'] ?? $EVT_CAT;
151
-        $EVT_CAT = (int) $EVT_CAT;
152
-        if ($EVT_CAT > 0) {
153
-            $this->where_params['Event.Term_Taxonomy.term_id'] = $EVT_CAT;
154
-        }
155
-    }
156
-
157
-
158
-    /**
159
-     * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
160
-     */
161
-    protected function addDatetimeIdToWhereConditions()
162
-    {
163
-        // first look for 'datetime_id' then 'DTT_ID' using first result as fallback default value
164
-        $DTT_ID = $this->request->getRequestParam('datetime_id');
165
-        $DTT_ID = $this->request->getRequestParam('DTT_ID', $DTT_ID, DataType::INTEGER);
166
-        $DTT_ID = $this->filters['datetime_id'] ?? $DTT_ID;
167
-        $DTT_ID = (int) $DTT_ID;
168
-
169
-        if ($DTT_ID) {
170
-            $this->where_params['Ticket.Datetime.DTT_ID'] = $DTT_ID;
171
-        }
172
-    }
173
-
174
-
175
-    /**
176
-     * Adds the ticket ID if it exists in the request to the where conditions for the registrations query.
177
-     */
178
-    protected function addTicketIdToWhereConditions()
179
-    {
180
-        // first look for 'ticket_id' then 'TKT_ID' using first result as fallback default value
181
-        $TKT_ID = $this->request->getRequestParam('ticket_id');
182
-        $TKT_ID = $this->request->getRequestParam('TKT_ID', $TKT_ID, DataType::INTEGER);
183
-        $TKT_ID = $this->filters['ticket_id'] ?? $TKT_ID;
184
-        $TKT_ID = (int) $TKT_ID;
185
-
186
-        if ($TKT_ID) {
187
-            $this->where_params['TKT_ID'] = $TKT_ID;
188
-        }
189
-    }
190
-
191
-
192
-    /**
193
-     * Adds the correct registration status to the where conditions for the registrations query.
194
-     * If filtering by registration status, then we show registrations matching that status.
195
-     * If not filtering by specified status, then we show all registrations excluding incomplete registrations
196
-     * UNLESS viewing trashed registrations.
197
-     */
198
-    protected function addRegistrationStatusToWhereConditions()
199
-    {
200
-        $registration_status = $this->request->getRequestParam('_reg_status');
201
-        $registration_status = $this->filters['_reg_status'] ?? $registration_status;
202
-        if ($registration_status) {
203
-            $this->where_params['STS_ID'] = sanitize_text_field($registration_status);
204
-            return;
205
-        }
206
-        // make sure we exclude incomplete registrations, but only if not trashed.
207
-        if ($this->view === 'trash') {
208
-            $this->where_params['REG_deleted'] = true;
209
-            return;
210
-        }
211
-        $this->where_params['STS_ID'] = $this->view === 'incomplete'
212
-            ? EEM_Registration::status_id_incomplete
213
-            : ['!=', EEM_Registration::status_id_incomplete];
214
-    }
215
-
216
-
217
-    /**
218
-     * Adds any provided date restraints to the where conditions for the registrations query.
219
-     *
220
-     * @throws EE_Error
221
-     * @throws InvalidArgumentException
222
-     * @throws InvalidDataTypeException
223
-     * @throws InvalidInterfaceException
224
-     */
225
-    protected function addDateToWhereConditions()
226
-    {
227
-        $current_time = current_time('timestamp');
228
-        $timezone_string = EEH_DTT_Helper::get_timezone();
229
-        if ($this->view === 'today') {
230
-            $now = date('Y-m-d', $current_time);
231
-            $this->where_params['REG_date'] = [
232
-                'BETWEEN',
233
-                [
234
-                    $this->registration_model->convert_datetime_for_query(
235
-                        'REG_date',
236
-                        $now . ' 00:00:00',
237
-                        'Y-m-d H:i:s',
238
-                        $timezone_string
239
-                    ),
240
-                    $this->registration_model->convert_datetime_for_query(
241
-                        'REG_date',
242
-                        $now . ' 23:59:59',
243
-                        'Y-m-d H:i:s',
244
-                        $timezone_string
245
-                    ),
246
-                ],
247
-            ];
248
-            return;
249
-        }
250
-        if ($this->view === 'yesterday') {
251
-            $yesterday = date('Y-m-d', $current_time - DAY_IN_SECONDS);
252
-            $this->where_params['REG_date'] = [
253
-                'BETWEEN',
254
-                [
255
-                    $this->registration_model->convert_datetime_for_query(
256
-                        'REG_date',
257
-                        $yesterday . ' 00:00:00',
258
-                        'Y-m-d H:i:s',
259
-                        $timezone_string
260
-                    ),
261
-                    $this->registration_model->convert_datetime_for_query(
262
-                        'REG_date',
263
-                        $yesterday . ' 23:59:59',
264
-                        'Y-m-d H:i:s',
265
-                        $timezone_string
266
-                    ),
267
-                ],
268
-            ];
269
-            return;
270
-        }
271
-        if ($this->view === 'month') {
272
-            $current_year_and_month = date('Y-m', $current_time);
273
-            $days_this_month = date('t', $current_time);
274
-            $this->where_params['REG_date'] = [
275
-                'BETWEEN',
276
-                [
277
-                    $this->registration_model->convert_datetime_for_query(
278
-                        'REG_date',
279
-                        $current_year_and_month . '-01 00:00:00',
280
-                        'Y-m-d H:i:s',
281
-                        $timezone_string
282
-                    ),
283
-                    $this->registration_model->convert_datetime_for_query(
284
-                        'REG_date',
285
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
286
-                        'Y-m-d H:i:s',
287
-                        $timezone_string
288
-                    ),
289
-                ],
290
-            ];
291
-            return;
292
-        }
293
-        $month_range = $this->request->getRequestParam('month_range');
294
-        $month_range = $this->filters['month_range'] ?? $month_range;
295
-        if ($month_range) {
296
-            $month_range = sanitize_text_field($month_range);
297
-            $pieces = explode(' ', $month_range, 3);
298
-            $month_requested = ! empty($pieces[0])
299
-                ? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
300
-                : '';
301
-            $year_requested = ! empty($pieces[1])
302
-                ? $pieces[1]
303
-                : '';
304
-            // if there is not a month or year then we can't go further
305
-            if ($month_requested && $year_requested) {
306
-                $days_in_month = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
307
-                $this->where_params['REG_date'] = [
308
-                    'BETWEEN',
309
-                    [
310
-                        $this->registration_model->convert_datetime_for_query(
311
-                            'REG_date',
312
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
313
-                            'Y-m-d H:i:s',
314
-                            $timezone_string
315
-                        ),
316
-                        $this->registration_model->convert_datetime_for_query(
317
-                            'REG_date',
318
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
319
-                            'Y-m-d H:i:s',
320
-                            $timezone_string
321
-                        ),
322
-                    ],
323
-                ];
324
-            }
325
-        }
326
-    }
327
-
328
-
329
-    /**
330
-     * Adds any provided search restraints to the where conditions for the registrations query
331
-     */
332
-    protected function addSearchToWhereConditions()
333
-    {
334
-        $search = $this->request->getRequestParam('s');
335
-        if ($search) {
336
-            $search_string = '%' . sanitize_text_field($search) . '%';
337
-            $this->where_params['OR*search_conditions'] = [
338
-                'Event.EVT_name'                          => ['LIKE', $search_string],
339
-                'Event.EVT_desc'                          => ['LIKE', $search_string],
340
-                'Event.EVT_short_desc'                    => ['LIKE', $search_string],
341
-                'Attendee.ATT_full_name'                  => ['LIKE', $search_string],
342
-                'Attendee.ATT_fname'                      => ['LIKE', $search_string],
343
-                'Attendee.ATT_lname'                      => ['LIKE', $search_string],
344
-                'Attendee.ATT_short_bio'                  => ['LIKE', $search_string],
345
-                'Attendee.ATT_email'                      => ['LIKE', $search_string],
346
-                'Attendee.ATT_address'                    => ['LIKE', $search_string],
347
-                'Attendee.ATT_address2'                   => ['LIKE', $search_string],
348
-                'Attendee.ATT_city'                       => ['LIKE', $search_string],
349
-                'REG_final_price'                         => ['LIKE', $search_string],
350
-                'REG_code'                                => ['LIKE', $search_string],
351
-                'REG_count'                               => ['LIKE', $search_string],
352
-                'REG_group_size'                          => ['LIKE', $search_string],
353
-                'Ticket.TKT_name'                         => ['LIKE', $search_string],
354
-                'Ticket.TKT_description'                  => ['LIKE', $search_string],
355
-                'Transaction.Payment.PAY_txn_id_chq_nmbr' => ['LIKE', $search_string],
356
-            ];
357
-        }
358
-    }
359
-
360
-
361
-    /**
362
-     * Sets up the orderby for the registrations query.
363
-     *
364
-     * @return array
365
-     */
366
-    protected function getOrderbyClause(): array
367
-    {
368
-        $orderby_field = $this->request->getRequestParam('orderby');
369
-        $orderby_field = $orderby_field ? sanitize_text_field($orderby_field) : '_REG_date';
370
-        switch ($orderby_field) {
371
-            case '_REG_ID':
372
-                $orderby = ['REG_ID'];
373
-                break;
374
-            case '_Reg_status':
375
-                $orderby = ['STS_ID'];
376
-                break;
377
-            case 'ATT_fname':
378
-                $orderby = ['Attendee.ATT_fname', 'Attendee.ATT_lname'];
379
-                break;
380
-            case 'ATT_lname':
381
-                $orderby = ['Attendee.ATT_lname', 'Attendee.ATT_fname'];
382
-                break;
383
-            case 'event_name':
384
-                $orderby = ['Event.EVT_name'];
385
-                break;
386
-            case 'DTT_EVT_start':
387
-                $orderby = ['Event.Datetime.DTT_EVT_start'];
388
-                break;
389
-            case '_REG_date':
390
-                $orderby = ['REG_date'];
391
-                break;
392
-            default:
393
-                $orderby = [$orderby_field];
394
-                break;
395
-        }
396
-        $order = $this->request->getRequestParam('order');
397
-        $order = $order ? sanitize_text_field($order) : 'DESC';
398
-
399
-        $orderby = array_combine(
400
-            $orderby,
401
-            array_fill(0, count($orderby), $order)
402
-        );
403
-        // always add REG_count to the orderby array
404
-        $orderby['REG_count'] = 'ASC';
405
-        // because there are many registrations with the same date, define
406
-        // a secondary way to order them, otherwise MySQL seems to be a bit random
407
-        if (empty($orderby['REG_ID'])) {
408
-            $orderby['REG_ID'] = $order;
409
-        }
410
-
411
-        $orderby = apply_filters(
412
-            'FHEE__Registrations_Admin_Page___get_orderby_for_registrations_query',
413
-            $orderby,
414
-            $this->request->requestParams()
415
-        );
416
-        return ['order_by' => $orderby];
417
-    }
418
-
419
-
420
-    /**
421
-     * Sets up the limit for the registrations query.
422
-     *
423
-     * @param int $per_page
424
-     * @return array
425
-     */
426
-    protected function getLimitClause(int $per_page): array
427
-    {
428
-        $current_page = $this->request->getRequestParam('paged', 1, 'int');
429
-        $per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
430
-        // -1 means return all results so get out if that's set.
431
-        if ($per_page === -1) {
432
-            return [];
433
-        }
434
-        $offset = ($current_page - 1) * $per_page;
435
-        return ['limit' => [$offset, $per_page]];
436
-    }
25
+	protected RequestInterface $request;
26
+
27
+	protected EEM_Registration $registration_model;
28
+
29
+	protected array $filters;
30
+
31
+	protected string $view;
32
+
33
+	protected array $where_params;
34
+
35
+
36
+	/**
37
+	 * QueryBuilder constructor.
38
+	 *
39
+	 * @param RequestInterface $request
40
+	 * @param EEM_Registration $registration_model
41
+	 * @param array            $extra_request_params
42
+	 */
43
+	public function __construct(
44
+		RequestInterface $request,
45
+		EEM_Registration $registration_model,
46
+		array $extra_request_params = []
47
+	) {
48
+		$this->request = $request;
49
+		$this->filters = $this->request->getRequestParam('filters', [], DataType::STRING, true);
50
+		$this->registration_model = $registration_model;
51
+		foreach ($extra_request_params as $key => $value) {
52
+			if (! $this->request->requestParamIsSet($key)) {
53
+				$this->request->setRequestParam($key, $value);
54
+			}
55
+		}
56
+		$this->view = $this->request->getRequestParam('status', '');
57
+		$this->where_params = [];
58
+	}
59
+
60
+
61
+	/**
62
+	 * Sets up the where conditions for the registrations query.
63
+	 *
64
+	 * @param int  $per_page
65
+	 * @param bool $count_query
66
+	 * @return array
67
+	 * @throws EE_Error
68
+	 * @throws InvalidArgumentException
69
+	 * @throws InvalidDataTypeException
70
+	 * @throws InvalidInterfaceException
71
+	 */
72
+	public function getQueryParams(int $per_page = 10, bool $count_query = false): array
73
+	{
74
+		$query_params = [
75
+			0                          => $this->getWhereClause(),
76
+			'caps'                     => EEM_Base::caps_read_admin,
77
+			'default_where_conditions' => 'this_model_only',
78
+		];
79
+		if (! $count_query) {
80
+			$query_params = array_merge(
81
+				$query_params,
82
+				$this->getOrderbyClause(),
83
+				$this->getLimitClause($per_page)
84
+			);
85
+		}
86
+
87
+		return $query_params;
88
+	}
89
+
90
+
91
+	/**
92
+	 * Sets up the where conditions for the registrations query.
93
+	 *
94
+	 * @return array
95
+	 * @throws EE_Error
96
+	 * @throws InvalidArgumentException
97
+	 * @throws InvalidDataTypeException
98
+	 * @throws InvalidInterfaceException
99
+	 */
100
+	protected function getWhereClause(): array
101
+	{
102
+		$this->addAttendeeIdToWhereConditions();
103
+		$this->addEventIdToWhereConditions();
104
+		$this->addCategoryIdToWhereConditions();
105
+		$this->addDatetimeIdToWhereConditions();
106
+		$this->addTicketIdToWhereConditions();
107
+		$this->addRegistrationStatusToWhereConditions();
108
+		$this->addDateToWhereConditions();
109
+		$this->addSearchToWhereConditions();
110
+		return apply_filters(
111
+			'FHEE__Registrations_Admin_Page___get_where_conditions_for_registrations_query',
112
+			$this->where_params,
113
+			$this->request->requestParams()
114
+		);
115
+	}
116
+
117
+
118
+	/**
119
+	 * This will add ATT_ID to the provided $this->where_clause array for EE model query parameters.
120
+	 */
121
+	protected function addAttendeeIdToWhereConditions()
122
+	{
123
+		$ATT_ID = $this->request->getRequestParam('attendee_id');
124
+		$ATT_ID = $this->request->getRequestParam('ATT_ID', $ATT_ID, 'int');
125
+		if ($ATT_ID) {
126
+			$this->where_params['ATT_ID'] = $ATT_ID;
127
+		}
128
+	}
129
+
130
+
131
+	/**
132
+	 * This will add EVT_ID to the provided $this->where_clause array for EE model query parameters.
133
+	 */
134
+	protected function addEventIdToWhereConditions()
135
+	{
136
+		$EVT_ID = $this->request->getRequestParam('event_id');
137
+		$EVT_ID = $this->request->getRequestParam('EVT_ID', $EVT_ID, 'int');
138
+		if ($EVT_ID) {
139
+			$this->where_params['EVT_ID'] = $EVT_ID;
140
+		}
141
+	}
142
+
143
+
144
+	/**
145
+	 * Adds category ID if it exists in the request to the where conditions for the registrations query.
146
+	 */
147
+	protected function addCategoryIdToWhereConditions()
148
+	{
149
+		$EVT_CAT = $this->request->getRequestParam('EVT_CAT', 0, DataType::INTEGER);
150
+		$EVT_CAT = $this->filters['EVT_CAT'] ?? $EVT_CAT;
151
+		$EVT_CAT = (int) $EVT_CAT;
152
+		if ($EVT_CAT > 0) {
153
+			$this->where_params['Event.Term_Taxonomy.term_id'] = $EVT_CAT;
154
+		}
155
+	}
156
+
157
+
158
+	/**
159
+	 * Adds the datetime ID if it exists in the request to the where conditions for the registrations query.
160
+	 */
161
+	protected function addDatetimeIdToWhereConditions()
162
+	{
163
+		// first look for 'datetime_id' then 'DTT_ID' using first result as fallback default value
164
+		$DTT_ID = $this->request->getRequestParam('datetime_id');
165
+		$DTT_ID = $this->request->getRequestParam('DTT_ID', $DTT_ID, DataType::INTEGER);
166
+		$DTT_ID = $this->filters['datetime_id'] ?? $DTT_ID;
167
+		$DTT_ID = (int) $DTT_ID;
168
+
169
+		if ($DTT_ID) {
170
+			$this->where_params['Ticket.Datetime.DTT_ID'] = $DTT_ID;
171
+		}
172
+	}
173
+
174
+
175
+	/**
176
+	 * Adds the ticket ID if it exists in the request to the where conditions for the registrations query.
177
+	 */
178
+	protected function addTicketIdToWhereConditions()
179
+	{
180
+		// first look for 'ticket_id' then 'TKT_ID' using first result as fallback default value
181
+		$TKT_ID = $this->request->getRequestParam('ticket_id');
182
+		$TKT_ID = $this->request->getRequestParam('TKT_ID', $TKT_ID, DataType::INTEGER);
183
+		$TKT_ID = $this->filters['ticket_id'] ?? $TKT_ID;
184
+		$TKT_ID = (int) $TKT_ID;
185
+
186
+		if ($TKT_ID) {
187
+			$this->where_params['TKT_ID'] = $TKT_ID;
188
+		}
189
+	}
190
+
191
+
192
+	/**
193
+	 * Adds the correct registration status to the where conditions for the registrations query.
194
+	 * If filtering by registration status, then we show registrations matching that status.
195
+	 * If not filtering by specified status, then we show all registrations excluding incomplete registrations
196
+	 * UNLESS viewing trashed registrations.
197
+	 */
198
+	protected function addRegistrationStatusToWhereConditions()
199
+	{
200
+		$registration_status = $this->request->getRequestParam('_reg_status');
201
+		$registration_status = $this->filters['_reg_status'] ?? $registration_status;
202
+		if ($registration_status) {
203
+			$this->where_params['STS_ID'] = sanitize_text_field($registration_status);
204
+			return;
205
+		}
206
+		// make sure we exclude incomplete registrations, but only if not trashed.
207
+		if ($this->view === 'trash') {
208
+			$this->where_params['REG_deleted'] = true;
209
+			return;
210
+		}
211
+		$this->where_params['STS_ID'] = $this->view === 'incomplete'
212
+			? EEM_Registration::status_id_incomplete
213
+			: ['!=', EEM_Registration::status_id_incomplete];
214
+	}
215
+
216
+
217
+	/**
218
+	 * Adds any provided date restraints to the where conditions for the registrations query.
219
+	 *
220
+	 * @throws EE_Error
221
+	 * @throws InvalidArgumentException
222
+	 * @throws InvalidDataTypeException
223
+	 * @throws InvalidInterfaceException
224
+	 */
225
+	protected function addDateToWhereConditions()
226
+	{
227
+		$current_time = current_time('timestamp');
228
+		$timezone_string = EEH_DTT_Helper::get_timezone();
229
+		if ($this->view === 'today') {
230
+			$now = date('Y-m-d', $current_time);
231
+			$this->where_params['REG_date'] = [
232
+				'BETWEEN',
233
+				[
234
+					$this->registration_model->convert_datetime_for_query(
235
+						'REG_date',
236
+						$now . ' 00:00:00',
237
+						'Y-m-d H:i:s',
238
+						$timezone_string
239
+					),
240
+					$this->registration_model->convert_datetime_for_query(
241
+						'REG_date',
242
+						$now . ' 23:59:59',
243
+						'Y-m-d H:i:s',
244
+						$timezone_string
245
+					),
246
+				],
247
+			];
248
+			return;
249
+		}
250
+		if ($this->view === 'yesterday') {
251
+			$yesterday = date('Y-m-d', $current_time - DAY_IN_SECONDS);
252
+			$this->where_params['REG_date'] = [
253
+				'BETWEEN',
254
+				[
255
+					$this->registration_model->convert_datetime_for_query(
256
+						'REG_date',
257
+						$yesterday . ' 00:00:00',
258
+						'Y-m-d H:i:s',
259
+						$timezone_string
260
+					),
261
+					$this->registration_model->convert_datetime_for_query(
262
+						'REG_date',
263
+						$yesterday . ' 23:59:59',
264
+						'Y-m-d H:i:s',
265
+						$timezone_string
266
+					),
267
+				],
268
+			];
269
+			return;
270
+		}
271
+		if ($this->view === 'month') {
272
+			$current_year_and_month = date('Y-m', $current_time);
273
+			$days_this_month = date('t', $current_time);
274
+			$this->where_params['REG_date'] = [
275
+				'BETWEEN',
276
+				[
277
+					$this->registration_model->convert_datetime_for_query(
278
+						'REG_date',
279
+						$current_year_and_month . '-01 00:00:00',
280
+						'Y-m-d H:i:s',
281
+						$timezone_string
282
+					),
283
+					$this->registration_model->convert_datetime_for_query(
284
+						'REG_date',
285
+						$current_year_and_month . '-' . $days_this_month . ' 23:59:59',
286
+						'Y-m-d H:i:s',
287
+						$timezone_string
288
+					),
289
+				],
290
+			];
291
+			return;
292
+		}
293
+		$month_range = $this->request->getRequestParam('month_range');
294
+		$month_range = $this->filters['month_range'] ?? $month_range;
295
+		if ($month_range) {
296
+			$month_range = sanitize_text_field($month_range);
297
+			$pieces = explode(' ', $month_range, 3);
298
+			$month_requested = ! empty($pieces[0])
299
+				? date('m', EEH_DTT_Helper::first_of_month_timestamp($pieces[0]))
300
+				: '';
301
+			$year_requested = ! empty($pieces[1])
302
+				? $pieces[1]
303
+				: '';
304
+			// if there is not a month or year then we can't go further
305
+			if ($month_requested && $year_requested) {
306
+				$days_in_month = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
307
+				$this->where_params['REG_date'] = [
308
+					'BETWEEN',
309
+					[
310
+						$this->registration_model->convert_datetime_for_query(
311
+							'REG_date',
312
+							$year_requested . '-' . $month_requested . '-01 00:00:00',
313
+							'Y-m-d H:i:s',
314
+							$timezone_string
315
+						),
316
+						$this->registration_model->convert_datetime_for_query(
317
+							'REG_date',
318
+							$year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
319
+							'Y-m-d H:i:s',
320
+							$timezone_string
321
+						),
322
+					],
323
+				];
324
+			}
325
+		}
326
+	}
327
+
328
+
329
+	/**
330
+	 * Adds any provided search restraints to the where conditions for the registrations query
331
+	 */
332
+	protected function addSearchToWhereConditions()
333
+	{
334
+		$search = $this->request->getRequestParam('s');
335
+		if ($search) {
336
+			$search_string = '%' . sanitize_text_field($search) . '%';
337
+			$this->where_params['OR*search_conditions'] = [
338
+				'Event.EVT_name'                          => ['LIKE', $search_string],
339
+				'Event.EVT_desc'                          => ['LIKE', $search_string],
340
+				'Event.EVT_short_desc'                    => ['LIKE', $search_string],
341
+				'Attendee.ATT_full_name'                  => ['LIKE', $search_string],
342
+				'Attendee.ATT_fname'                      => ['LIKE', $search_string],
343
+				'Attendee.ATT_lname'                      => ['LIKE', $search_string],
344
+				'Attendee.ATT_short_bio'                  => ['LIKE', $search_string],
345
+				'Attendee.ATT_email'                      => ['LIKE', $search_string],
346
+				'Attendee.ATT_address'                    => ['LIKE', $search_string],
347
+				'Attendee.ATT_address2'                   => ['LIKE', $search_string],
348
+				'Attendee.ATT_city'                       => ['LIKE', $search_string],
349
+				'REG_final_price'                         => ['LIKE', $search_string],
350
+				'REG_code'                                => ['LIKE', $search_string],
351
+				'REG_count'                               => ['LIKE', $search_string],
352
+				'REG_group_size'                          => ['LIKE', $search_string],
353
+				'Ticket.TKT_name'                         => ['LIKE', $search_string],
354
+				'Ticket.TKT_description'                  => ['LIKE', $search_string],
355
+				'Transaction.Payment.PAY_txn_id_chq_nmbr' => ['LIKE', $search_string],
356
+			];
357
+		}
358
+	}
359
+
360
+
361
+	/**
362
+	 * Sets up the orderby for the registrations query.
363
+	 *
364
+	 * @return array
365
+	 */
366
+	protected function getOrderbyClause(): array
367
+	{
368
+		$orderby_field = $this->request->getRequestParam('orderby');
369
+		$orderby_field = $orderby_field ? sanitize_text_field($orderby_field) : '_REG_date';
370
+		switch ($orderby_field) {
371
+			case '_REG_ID':
372
+				$orderby = ['REG_ID'];
373
+				break;
374
+			case '_Reg_status':
375
+				$orderby = ['STS_ID'];
376
+				break;
377
+			case 'ATT_fname':
378
+				$orderby = ['Attendee.ATT_fname', 'Attendee.ATT_lname'];
379
+				break;
380
+			case 'ATT_lname':
381
+				$orderby = ['Attendee.ATT_lname', 'Attendee.ATT_fname'];
382
+				break;
383
+			case 'event_name':
384
+				$orderby = ['Event.EVT_name'];
385
+				break;
386
+			case 'DTT_EVT_start':
387
+				$orderby = ['Event.Datetime.DTT_EVT_start'];
388
+				break;
389
+			case '_REG_date':
390
+				$orderby = ['REG_date'];
391
+				break;
392
+			default:
393
+				$orderby = [$orderby_field];
394
+				break;
395
+		}
396
+		$order = $this->request->getRequestParam('order');
397
+		$order = $order ? sanitize_text_field($order) : 'DESC';
398
+
399
+		$orderby = array_combine(
400
+			$orderby,
401
+			array_fill(0, count($orderby), $order)
402
+		);
403
+		// always add REG_count to the orderby array
404
+		$orderby['REG_count'] = 'ASC';
405
+		// because there are many registrations with the same date, define
406
+		// a secondary way to order them, otherwise MySQL seems to be a bit random
407
+		if (empty($orderby['REG_ID'])) {
408
+			$orderby['REG_ID'] = $order;
409
+		}
410
+
411
+		$orderby = apply_filters(
412
+			'FHEE__Registrations_Admin_Page___get_orderby_for_registrations_query',
413
+			$orderby,
414
+			$this->request->requestParams()
415
+		);
416
+		return ['order_by' => $orderby];
417
+	}
418
+
419
+
420
+	/**
421
+	 * Sets up the limit for the registrations query.
422
+	 *
423
+	 * @param int $per_page
424
+	 * @return array
425
+	 */
426
+	protected function getLimitClause(int $per_page): array
427
+	{
428
+		$current_page = $this->request->getRequestParam('paged', 1, 'int');
429
+		$per_page = $this->request->getRequestParam('perpage', $per_page, 'int');
430
+		// -1 means return all results so get out if that's set.
431
+		if ($per_page === -1) {
432
+			return [];
433
+		}
434
+		$offset = ($current_page - 1) * $per_page;
435
+		return ['limit' => [$offset, $per_page]];
436
+	}
437 437
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -49,7 +49,7 @@  discard block
 block discarded – undo
49 49
         $this->filters = $this->request->getRequestParam('filters', [], DataType::STRING, true);
50 50
         $this->registration_model = $registration_model;
51 51
         foreach ($extra_request_params as $key => $value) {
52
-            if (! $this->request->requestParamIsSet($key)) {
52
+            if ( ! $this->request->requestParamIsSet($key)) {
53 53
                 $this->request->setRequestParam($key, $value);
54 54
             }
55 55
         }
@@ -76,7 +76,7 @@  discard block
 block discarded – undo
76 76
             'caps'                     => EEM_Base::caps_read_admin,
77 77
             'default_where_conditions' => 'this_model_only',
78 78
         ];
79
-        if (! $count_query) {
79
+        if ( ! $count_query) {
80 80
             $query_params = array_merge(
81 81
                 $query_params,
82 82
                 $this->getOrderbyClause(),
@@ -233,13 +233,13 @@  discard block
 block discarded – undo
233 233
                 [
234 234
                     $this->registration_model->convert_datetime_for_query(
235 235
                         'REG_date',
236
-                        $now . ' 00:00:00',
236
+                        $now.' 00:00:00',
237 237
                         'Y-m-d H:i:s',
238 238
                         $timezone_string
239 239
                     ),
240 240
                     $this->registration_model->convert_datetime_for_query(
241 241
                         'REG_date',
242
-                        $now . ' 23:59:59',
242
+                        $now.' 23:59:59',
243 243
                         'Y-m-d H:i:s',
244 244
                         $timezone_string
245 245
                     ),
@@ -254,13 +254,13 @@  discard block
 block discarded – undo
254 254
                 [
255 255
                     $this->registration_model->convert_datetime_for_query(
256 256
                         'REG_date',
257
-                        $yesterday . ' 00:00:00',
257
+                        $yesterday.' 00:00:00',
258 258
                         'Y-m-d H:i:s',
259 259
                         $timezone_string
260 260
                     ),
261 261
                     $this->registration_model->convert_datetime_for_query(
262 262
                         'REG_date',
263
-                        $yesterday . ' 23:59:59',
263
+                        $yesterday.' 23:59:59',
264 264
                         'Y-m-d H:i:s',
265 265
                         $timezone_string
266 266
                     ),
@@ -276,13 +276,13 @@  discard block
 block discarded – undo
276 276
                 [
277 277
                     $this->registration_model->convert_datetime_for_query(
278 278
                         'REG_date',
279
-                        $current_year_and_month . '-01 00:00:00',
279
+                        $current_year_and_month.'-01 00:00:00',
280 280
                         'Y-m-d H:i:s',
281 281
                         $timezone_string
282 282
                     ),
283 283
                     $this->registration_model->convert_datetime_for_query(
284 284
                         'REG_date',
285
-                        $current_year_and_month . '-' . $days_this_month . ' 23:59:59',
285
+                        $current_year_and_month.'-'.$days_this_month.' 23:59:59',
286 286
                         'Y-m-d H:i:s',
287 287
                         $timezone_string
288 288
                     ),
@@ -303,19 +303,19 @@  discard block
 block discarded – undo
303 303
                 : '';
304 304
             // if there is not a month or year then we can't go further
305 305
             if ($month_requested && $year_requested) {
306
-                $days_in_month = date('t', strtotime($year_requested . '-' . $month_requested . '-' . '01'));
306
+                $days_in_month = date('t', strtotime($year_requested.'-'.$month_requested.'-'.'01'));
307 307
                 $this->where_params['REG_date'] = [
308 308
                     'BETWEEN',
309 309
                     [
310 310
                         $this->registration_model->convert_datetime_for_query(
311 311
                             'REG_date',
312
-                            $year_requested . '-' . $month_requested . '-01 00:00:00',
312
+                            $year_requested.'-'.$month_requested.'-01 00:00:00',
313 313
                             'Y-m-d H:i:s',
314 314
                             $timezone_string
315 315
                         ),
316 316
                         $this->registration_model->convert_datetime_for_query(
317 317
                             'REG_date',
318
-                            $year_requested . '-' . $month_requested . '-' . $days_in_month . ' 23:59:59',
318
+                            $year_requested.'-'.$month_requested.'-'.$days_in_month.' 23:59:59',
319 319
                             'Y-m-d H:i:s',
320 320
                             $timezone_string
321 321
                         ),
@@ -333,7 +333,7 @@  discard block
 block discarded – undo
333 333
     {
334 334
         $search = $this->request->getRequestParam('s');
335 335
         if ($search) {
336
-            $search_string = '%' . sanitize_text_field($search) . '%';
336
+            $search_string = '%'.sanitize_text_field($search).'%';
337 337
             $this->where_params['OR*search_conditions'] = [
338 338
                 'Event.EVT_name'                          => ['LIKE', $search_string],
339 339
                 'Event.EVT_desc'                          => ['LIKE', $search_string],
Please login to merge, or discard this patch.
core/domain/entities/custom_post_types/CustomTaxonomyDefinitions.php 1 patch
Indentation   +119 added lines, -119 removed lines patch added patch discarded remove patch
@@ -14,133 +14,133 @@
 block discarded – undo
14 14
  */
15 15
 class CustomTaxonomyDefinitions
16 16
 {
17
-    private array $taxonomies = [];
17
+	private array $taxonomies = [];
18 18
 
19 19
 
20
-    public function __construct()
21
-    {
22
-        $this->setTaxonomies();
23
-        add_filter('pre_term_description', [$this, 'filterCustomTermDescription'], 1, 2);
24
-    }
20
+	public function __construct()
21
+	{
22
+		$this->setTaxonomies();
23
+		add_filter('pre_term_description', [$this, 'filterCustomTermDescription'], 1, 2);
24
+	}
25 25
 
26 26
 
27
-    private function setTaxonomies()
28
-    {
29
-        $this->taxonomies = [
30
-            'espresso_event_categories' => [
31
-                'singular_name' => esc_html__('Event Category', 'event_espresso'),
32
-                'plural_name'   => esc_html__('Event Categories', 'event_espresso'),
33
-                'args'          => [
34
-                    'public'            => true,
35
-                    'show_in_nav_menus' => true,
36
-                    'show_in_rest'      => true,
37
-                    'capabilities'      => [
38
-                        'manage_terms' => 'ee_manage_event_categories',
39
-                        'edit_terms'   => 'ee_edit_event_category',
40
-                        'delete_terms' => 'ee_delete_event_category',
41
-                        'assign_terms' => 'ee_assign_event_category',
42
-                    ],
43
-                    'rewrite'           => [
44
-                        'slug' => EEH_URL::slugify(
45
-                            esc_html__('event-category', 'event_espresso'),
46
-                            'event-category'
47
-                        ),
48
-                    ],
49
-                ],
50
-            ],
51
-            'espresso_venue_categories' => [
52
-                'singular_name' => esc_html__('Venue Category', 'event_espresso'),
53
-                'plural_name'   => esc_html__('Venue Categories', 'event_espresso'),
54
-                'args'          => [
55
-                    'public'            => true,
56
-                    'show_in_nav_menus' => false, // by default this doesn't show for decaf
57
-                    'show_in_rest'      => true,
58
-                    'capabilities'      => [
59
-                        'manage_terms' => 'ee_manage_venue_categories',
60
-                        'edit_terms'   => 'ee_edit_venue_category',
61
-                        'delete_terms' => 'ee_delete_venue_category',
62
-                        'assign_terms' => 'ee_assign_venue_category',
63
-                    ],
64
-                    'rewrite'           => [
65
-                        'slug' => EEH_URL::slugify(
66
-                            esc_html__('venue-category', 'event_espresso'),
67
-                            'venue-category'
68
-                        ),
69
-                    ],
70
-                ],
71
-            ],
72
-            'espresso_event_type'       => [
73
-                'singular_name' => esc_html__('Event Type', 'event_espresso'),
74
-                'plural_name'   => esc_html__('Event Types', 'event_espresso'),
75
-                'args'          => [
76
-                    'public'       => true,
77
-                    'show_ui'      => false,
78
-                    'show_in_rest' => true,
79
-                    'capabilities' => [
80
-                        'manage_terms' => 'ee_read_event_type',
81
-                        'edit_terms'   => 'ee_edit_event_type',
82
-                        'delete_terms' => 'ee_delete_event_type',
83
-                        'assign_terms' => 'ee_assign_event_type',
84
-                    ],
85
-                    'rewrite'      => [
86
-                        'slug' => EEH_URL::slugify(
87
-                            esc_html__('event-type', 'event_espresso'),
88
-                            'event-type'
89
-                        ),
90
-                    ],
91
-                    'hierarchical' => true,
92
-                ],
93
-            ],
94
-        ];
95
-    }
27
+	private function setTaxonomies()
28
+	{
29
+		$this->taxonomies = [
30
+			'espresso_event_categories' => [
31
+				'singular_name' => esc_html__('Event Category', 'event_espresso'),
32
+				'plural_name'   => esc_html__('Event Categories', 'event_espresso'),
33
+				'args'          => [
34
+					'public'            => true,
35
+					'show_in_nav_menus' => true,
36
+					'show_in_rest'      => true,
37
+					'capabilities'      => [
38
+						'manage_terms' => 'ee_manage_event_categories',
39
+						'edit_terms'   => 'ee_edit_event_category',
40
+						'delete_terms' => 'ee_delete_event_category',
41
+						'assign_terms' => 'ee_assign_event_category',
42
+					],
43
+					'rewrite'           => [
44
+						'slug' => EEH_URL::slugify(
45
+							esc_html__('event-category', 'event_espresso'),
46
+							'event-category'
47
+						),
48
+					],
49
+				],
50
+			],
51
+			'espresso_venue_categories' => [
52
+				'singular_name' => esc_html__('Venue Category', 'event_espresso'),
53
+				'plural_name'   => esc_html__('Venue Categories', 'event_espresso'),
54
+				'args'          => [
55
+					'public'            => true,
56
+					'show_in_nav_menus' => false, // by default this doesn't show for decaf
57
+					'show_in_rest'      => true,
58
+					'capabilities'      => [
59
+						'manage_terms' => 'ee_manage_venue_categories',
60
+						'edit_terms'   => 'ee_edit_venue_category',
61
+						'delete_terms' => 'ee_delete_venue_category',
62
+						'assign_terms' => 'ee_assign_venue_category',
63
+					],
64
+					'rewrite'           => [
65
+						'slug' => EEH_URL::slugify(
66
+							esc_html__('venue-category', 'event_espresso'),
67
+							'venue-category'
68
+						),
69
+					],
70
+				],
71
+			],
72
+			'espresso_event_type'       => [
73
+				'singular_name' => esc_html__('Event Type', 'event_espresso'),
74
+				'plural_name'   => esc_html__('Event Types', 'event_espresso'),
75
+				'args'          => [
76
+					'public'       => true,
77
+					'show_ui'      => false,
78
+					'show_in_rest' => true,
79
+					'capabilities' => [
80
+						'manage_terms' => 'ee_read_event_type',
81
+						'edit_terms'   => 'ee_edit_event_type',
82
+						'delete_terms' => 'ee_delete_event_type',
83
+						'assign_terms' => 'ee_assign_event_type',
84
+					],
85
+					'rewrite'      => [
86
+						'slug' => EEH_URL::slugify(
87
+							esc_html__('event-type', 'event_espresso'),
88
+							'event-type'
89
+						),
90
+					],
91
+					'hierarchical' => true,
92
+				],
93
+			],
94
+		];
95
+	}
96 96
 
97 97
 
98
-    public function getCustomTaxonomyDefinitions(): array
99
-    {
100
-        return (array) apply_filters(
101
-            'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
102
-            // legacy filter applied for now,
103
-            // later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
104
-            apply_filters(
105
-                'FHEE__EE_Register_CPTs__get_taxonomies__taxonomies',
106
-                $this->taxonomies
107
-            )
108
-        );
109
-    }
98
+	public function getCustomTaxonomyDefinitions(): array
99
+	{
100
+		return (array) apply_filters(
101
+			'FHEE__EventEspresso_core_domain_entities_custom_post_types_TaxonomyDefinitions__getTaxonomies',
102
+			// legacy filter applied for now,
103
+			// later on we'll run a has_filter($tag) check and throw a doing_it_wrong() notice
104
+			apply_filters(
105
+				'FHEE__EE_Register_CPTs__get_taxonomies__taxonomies',
106
+				$this->taxonomies
107
+			)
108
+		);
109
+	}
110 110
 
111 111
 
112
-    public function getCustomTaxonomySlugs(): array
113
-    {
114
-        return array_keys($this->getCustomTaxonomyDefinitions());
115
-    }
112
+	public function getCustomTaxonomySlugs(): array
113
+	{
114
+		return array_keys($this->getCustomTaxonomyDefinitions());
115
+	}
116 116
 
117 117
 
118
-    /**
119
-     * By default, WordPress strips all html from term taxonomy description content.
120
-     * The purpose of this method is to remove that restriction
121
-     * and ensure that we still run ee term taxonomy descriptions
122
-     * through some full html sanitization equivalent to the post content field.
123
-     * So first we remove default filter for term description
124
-     * but we have to do this earlier before wp sets their own filter
125
-     * because they just set a global filter on all term descriptions
126
-     * before the custom term description filter.
127
-     * Really sux.
128
-     *
129
-     * @param string $description The description content.
130
-     * @param string $taxonomy    The taxonomy name for the taxonomy being filtered.
131
-     * @return string
132
-     */
133
-    public function filterCustomTermDescription(string $description, string $taxonomy): string
134
-    {
135
-        // get a list of EE taxonomies
136
-        $custom_taxonomies = $this->getCustomTaxonomySlugs();
137
-        // only do our own thing if the taxonomy listed is an ee taxonomy.
138
-        if (in_array($taxonomy, $custom_taxonomies, true)) {
139
-            // remove default wp filter
140
-            remove_filter('pre_term_description', 'wp_filter_kses');
141
-            // sanitize THIS content.
142
-            $description = wp_kses($description, wp_kses_allowed_html('post'));
143
-        }
144
-        return $description;
145
-    }
118
+	/**
119
+	 * By default, WordPress strips all html from term taxonomy description content.
120
+	 * The purpose of this method is to remove that restriction
121
+	 * and ensure that we still run ee term taxonomy descriptions
122
+	 * through some full html sanitization equivalent to the post content field.
123
+	 * So first we remove default filter for term description
124
+	 * but we have to do this earlier before wp sets their own filter
125
+	 * because they just set a global filter on all term descriptions
126
+	 * before the custom term description filter.
127
+	 * Really sux.
128
+	 *
129
+	 * @param string $description The description content.
130
+	 * @param string $taxonomy    The taxonomy name for the taxonomy being filtered.
131
+	 * @return string
132
+	 */
133
+	public function filterCustomTermDescription(string $description, string $taxonomy): string
134
+	{
135
+		// get a list of EE taxonomies
136
+		$custom_taxonomies = $this->getCustomTaxonomySlugs();
137
+		// only do our own thing if the taxonomy listed is an ee taxonomy.
138
+		if (in_array($taxonomy, $custom_taxonomies, true)) {
139
+			// remove default wp filter
140
+			remove_filter('pre_term_description', 'wp_filter_kses');
141
+			// sanitize THIS content.
142
+			$description = wp_kses($description, wp_kses_allowed_html('post'));
143
+		}
144
+		return $description;
145
+	}
146 146
 }
Please login to merge, or discard this patch.
core/domain/entities/custom_post_types/CustomTaxonomyTerm.php 1 patch
Indentation   +21 added lines, -21 removed lines patch added patch discarded remove patch
@@ -12,35 +12,35 @@
 block discarded – undo
12 12
  */
13 13
 class CustomTaxonomyTerm
14 14
 {
15
-    public string $taxonomy_slug;
15
+	public string $taxonomy_slug;
16 16
 
17
-    public string $term_slug;
17
+	public string $term_slug;
18 18
 
19
-    public array $custom_post_type_slugs;
19
+	public array $custom_post_type_slugs;
20 20
 
21 21
 
22
-    public function __construct(string $taxonomy_slug, string $term_slug, array $custom_post_type_slugs = [])
23
-    {
24
-        $this->taxonomy_slug          = $taxonomy_slug;
25
-        $this->term_slug              = $term_slug;
26
-        $this->custom_post_type_slugs = $custom_post_type_slugs;
27
-    }
22
+	public function __construct(string $taxonomy_slug, string $term_slug, array $custom_post_type_slugs = [])
23
+	{
24
+		$this->taxonomy_slug          = $taxonomy_slug;
25
+		$this->term_slug              = $term_slug;
26
+		$this->custom_post_type_slugs = $custom_post_type_slugs;
27
+	}
28 28
 
29 29
 
30
-    public function taxonomySlug(): string
31
-    {
32
-        return $this->taxonomy_slug;
33
-    }
30
+	public function taxonomySlug(): string
31
+	{
32
+		return $this->taxonomy_slug;
33
+	}
34 34
 
35 35
 
36
-    public function termSlug(): string
37
-    {
38
-        return $this->term_slug;
39
-    }
36
+	public function termSlug(): string
37
+	{
38
+		return $this->term_slug;
39
+	}
40 40
 
41 41
 
42
-    public function customPostTypeSlugs(): array
43
-    {
44
-        return $this->custom_post_type_slugs;
45
-    }
42
+	public function customPostTypeSlugs(): array
43
+	{
44
+		return $this->custom_post_type_slugs;
45
+	}
46 46
 }
Please login to merge, or discard this patch.