Completed
Branch BUG-11108-ticket-reserved-coun... (144d27)
by
unknown
14:21 queued 17s
created
core/services/cache/TransientCacheStorage.php 2 patches
Indentation   +375 added lines, -375 removed lines patch added patch discarded remove patch
@@ -19,381 +19,381 @@
 block discarded – undo
19 19
 class TransientCacheStorage implements CacheStorageInterface
20 20
 {
21 21
 
22
-    /**
23
-     * wp-option option_name for tracking transients
24
-     *
25
-     * @type string
26
-     */
27
-    const TRANSIENT_SCHEDULE_OPTIONS_KEY = 'ee_transient_schedule';
28
-
29
-    /**
30
-     * @var int $current_time
31
-     */
32
-    private $current_time;
33
-
34
-    /**
35
-     * how often to perform transient cleanup
36
-     *
37
-     * @var string $transient_cleanup_frequency
38
-     */
39
-    private $transient_cleanup_frequency;
40
-
41
-    /**
42
-     * options for how often to perform transient cleanup
43
-     *
44
-     * @var array $transient_cleanup_frequency_options
45
-     */
46
-    private $transient_cleanup_frequency_options = array();
47
-
48
-    /**
49
-     * @var array $transients
50
-     */
51
-    private $transients;
52
-
53
-
54
-
55
-    /**
56
-     * TransientCacheStorage constructor.
57
-     */
58
-    public function __construct()
59
-    {
60
-        $this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
61
-        // round current time down to closest 5 minutes to simplify scheduling
62
-        $this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
63
-        $this->transients = (array)get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
64
-        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
65
-            add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
66
-        }
67
-    }
68
-
69
-
70
-
71
-    /**
72
-     * Sets how often transient cleanup occurs
73
-     *
74
-     * @return string
75
-     */
76
-    private function setTransientCleanupFrequency()
77
-    {
78
-        // sets how often transients are cleaned up
79
-        $this->transient_cleanup_frequency_options = apply_filters(
80
-            'FHEE__TransientCacheStorage__transient_cleanup_schedule_options',
81
-            array(
82
-                'off',
83
-                '15-minutes',
84
-                'hour',
85
-                '12-hours',
86
-                'day',
87
-            )
88
-        );
89
-        $transient_cleanup_frequency = apply_filters(
90
-            'FHEE__TransientCacheStorage__transient_cleanup_schedule',
91
-            'hour'
92
-        );
93
-        return in_array(
94
-            $transient_cleanup_frequency,
95
-            $this->transient_cleanup_frequency_options,
96
-            true
97
-        )
98
-            ? $transient_cleanup_frequency
99
-            : 'hour';
100
-    }
101
-
102
-
103
-
104
-    /**
105
-     * we need to be able to round timestamps off to match the set transient cleanup frequency
106
-     * so if a transient is set to expire at 1:17 pm for example, and our cleanup schedule is every hour,
107
-     * then that timestamp needs to be rounded up to 2:00 pm so that it is removed
108
-     * during the next scheduled cleanup after its expiration.
109
-     * We also round off the current time timestamp to the closest 5 minutes
110
-     * just to make the timestamps a little easier to round which helps with debugging.
111
-     *
112
-     * @param int    $timestamp [required]
113
-     * @param string $cleanup_frequency
114
-     * @param bool   $round_up
115
-     * @return int
116
-     */
117
-    private function roundTimestamp($timestamp, $cleanup_frequency = 'hour', $round_up = true)
118
-    {
119
-        $cleanup_frequency = $cleanup_frequency ? $cleanup_frequency : $this->transient_cleanup_frequency;
120
-        // in order to round the time to the closest xx minutes (or hours),
121
-        // we take the minutes (or hours) portion of the timestamp and divide it by xx,
122
-        // round down to a whole number, then multiply by xx to bring us almost back up to where we were
123
-        // why round down ? so the minutes (or hours) don't go over 60 (or 24)
124
-        // and bump the hour, which could bump the day, which could bump the month, etc,
125
-        // which would be bad because we don't always want to round up,
126
-        // but when we do we can easily achieve that by simply adding the desired offset,
127
-        $minutes = '00';
128
-        $hours = 'H';
129
-        switch ($cleanup_frequency) {
130
-            case '5-minutes' :
131
-                $minutes = floor((int)date('i', $timestamp) / 5) * 5;
132
-                $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
133
-                $offset = MINUTE_IN_SECONDS * 5;
134
-                break;
135
-            case '15-minutes' :
136
-                $minutes = floor((int)date('i', $timestamp) / 15) * 15;
137
-                $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
138
-                $offset = MINUTE_IN_SECONDS * 15;
139
-                break;
140
-            case '12-hours' :
141
-                $hours = floor((int)date('H', $timestamp) / 12) * 12;
142
-                $hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
143
-                $offset = HOUR_IN_SECONDS * 12;
144
-                break;
145
-            case 'day' :
146
-                $hours = '03'; // run cleanup at 3:00 am (or first site hit after that)
147
-                $offset = DAY_IN_SECONDS;
148
-                break;
149
-            case 'hour' :
150
-            default :
151
-                $offset = HOUR_IN_SECONDS;
152
-                break;
153
-        }
154
-        $rounded_timestamp = (int) strtotime(date("Y-m-d {$hours}:{$minutes}:00", $timestamp));
155
-        $rounded_timestamp += $round_up ? $offset : 0;
156
-        return apply_filters(
157
-            'FHEE__TransientCacheStorage__roundTimestamp__timestamp',
158
-            $rounded_timestamp,
159
-            $timestamp,
160
-            $cleanup_frequency,
161
-            $round_up
162
-        );
163
-    }
164
-
165
-
166
-
167
-    /**
168
-     * Saves supplied data to a transient
169
-     * if an expiration is set, then it automatically schedules the transient for cleanup
170
-     *
171
-     * @param string $transient_key [required]
172
-     * @param string $data          [required]
173
-     * @param int    $expiration    number of seconds until the cache expires
174
-     * @return bool
175
-     */
176
-    public function add($transient_key, $data, $expiration = 0)
177
-    {
178
-        $expiration = (int)abs($expiration);
179
-        $saved = set_transient($transient_key, $data, $expiration);
180
-        if ($saved && $expiration) {
181
-            $this->scheduleTransientCleanup($transient_key, $expiration);
182
-        }
183
-        return $saved;
184
-    }
185
-
186
-
187
-
188
-    /**
189
-     * retrieves transient data
190
-     * automatically triggers early cache refresh for standard cache items
191
-     * in order to avoid cache stampedes on busy sites.
192
-     * For non-standard cache items like PHP Session data where early refreshing is not wanted,
193
-     * the $standard_cache parameter should be set to false when retrieving data
194
-     *
195
-     * @param string $transient_key [required]
196
-     * @param bool   $standard_cache
197
-     * @return mixed|null
198
-     */
199
-    public function get($transient_key, $standard_cache = true)
200
-    {
201
-        if (isset($this->transients[ $transient_key ])) {
202
-            // to avoid cache stampedes (AKA:dogpiles) for standard cache items,
203
-            // check if known cache expires within the next minute,
204
-            // and if so, remove it from our tracking and and return nothing.
205
-            // this should trigger the cache content to be regenerated during this request,
206
-            // while allowing any following requests to still access the existing cache
207
-            // until it gets replaced with the refreshed content
208
-            if (
209
-                $standard_cache
210
-                && $this->transients[$transient_key] - time() <= MINUTE_IN_SECONDS
211
-            ) {
212
-                unset($this->transients[$transient_key]);
213
-                $this->updateTransients();
214
-                return null;
215
-            }
216
-
217
-            // for non standard cache items, remove the key from our tracking,
218
-            // but proceed to retrieve the transient so that it also gets removed from the db
219
-            if ($this->transients[$transient_key] <= time()) {
220
-                unset($this->transients[$transient_key]);
221
-                $this->updateTransients();
222
-            }
223
-        }
224
-
225
-        $content = get_transient($transient_key);
226
-        return $content !== false ? $content : null;
227
-    }
228
-
229
-
230
-
231
-    /**
232
-     * delete a single transient and remove tracking
233
-     *
234
-     * @param string $transient_key [required] full or partial transient key to be deleted
235
-     */
236
-    public function delete($transient_key)
237
-    {
238
-        $this->deleteMany(array($transient_key));
239
-    }
240
-
241
-
242
-
243
-    /**
244
-     * delete multiple transients and remove tracking
245
-     *
246
-     * @param array $transient_keys [required] array of full or partial transient keys to be deleted
247
-     * @param bool  $force_delete   [optional] if true, then will not check incoming keys against those being tracked
248
-     *                              and proceed directly to deleting those entries from the cache storage
249
-     */
250
-    public function deleteMany(array $transient_keys, $force_delete = false)
251
-    {
252
-        $full_transient_keys = $force_delete ? $transient_keys : array();
253
-        if(empty($full_transient_keys)){
254
-            foreach ($this->transients as $transient_key => $expiration) {
255
-                foreach ($transient_keys as $transient_key_to_delete) {
256
-                    if (strpos($transient_key, $transient_key_to_delete) !== false) {
257
-                        $full_transient_keys[] = $transient_key;
258
-                    }
259
-                }
260
-            }
261
-        }
262
-        if ($this->deleteTransientKeys($full_transient_keys)) {
263
-            $this->updateTransients();
264
-        }
265
-    }
266
-
267
-
268
-
269
-    /**
270
-     * sorts transients numerically by timestamp
271
-     * then saves the transient schedule to a WP option
272
-     */
273
-    private function updateTransients()
274
-    {
275
-        asort($this->transients, SORT_NUMERIC);
276
-        update_option(
277
-            TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY,
278
-            $this->transients
279
-        );
280
-    }
281
-
282
-
283
-
284
-    /**
285
-     * schedules a transient for cleanup by adding it to the transient tracking
286
-     *
287
-     * @param string $transient_key [required]
288
-     * @param int    $expiration    [required]
289
-     */
290
-    private function scheduleTransientCleanup($transient_key, $expiration)
291
-    {
292
-        // make sure a valid future timestamp is set
293
-        $expiration += $expiration < time() ? time() : 0;
294
-        // and round to the closest 15 minutes
295
-        $expiration = $this->roundTimestamp($expiration);
296
-        // save transients to clear using their ID as the key to avoid duplicates
297
-        $this->transients[$transient_key] = $expiration;
298
-        $this->updateTransients();
299
-    }
300
-
301
-
302
-
303
-    /**
304
-     * Since our tracked transients are sorted by their timestamps
305
-     * we can grab the first transient and see when it is scheduled for cleanup.
306
-     * If that timestamp is less than or equal to the current time,
307
-     * then cleanup is triggered
308
-     */
309
-    public function checkTransientCleanupSchedule()
310
-    {
311
-        if (empty($this->transients)) {
312
-            return;
313
-        }
314
-        // when do we run the next cleanup job?
315
-        reset($this->transients);
316
-        $next_scheduled_cleanup = current($this->transients);
317
-        // if the next cleanup job is scheduled for the current hour
318
-        if ($next_scheduled_cleanup <= $this->current_time) {
319
-            if ($this->cleanupExpiredTransients()) {
320
-                $this->updateTransients();
321
-            }
322
-        }
323
-    }
324
-
325
-
326
-
327
-    /**
328
-     * loops through the array of tracked transients,
329
-     * compiles a list of those that have expired, and sends that list off for deletion.
330
-     * Also removes any bad records from the transients array
331
-     *
332
-     * @return bool
333
-     */
334
-    private function cleanupExpiredTransients()
335
-    {
336
-        $update = false;
337
-        // filter the query limit. Set to 0 to turn off garbage collection
338
-        $limit = (int)abs(
339
-            apply_filters(
340
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
341
-                50
342
-            )
343
-        );
344
-        // non-zero LIMIT means take out the trash
345
-        if ($limit) {
346
-            $transient_keys = array();
347
-            foreach ($this->transients as $transient_key => $expiration) {
348
-                if ($expiration > $this->current_time) {
349
-                    continue;
350
-                }
351
-                if ( ! $expiration || ! $transient_key) {
352
-                    unset($this->transients[$transient_key]);
353
-                    $update = true;
354
-                    continue;
355
-                }
356
-                $transient_keys[] = $transient_key;
357
-            }
358
-            // delete expired keys, but maintain value of $update if nothing is deleted
359
-            $update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
360
-            do_action( 'FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
361
-        }
362
-        return $update;
363
-    }
364
-
365
-
366
-
367
-    /**
368
-     * calls delete_transient() on each transient key provided, up to the specified limit
369
-     *
370
-     * @param array $transient_keys [required]
371
-     * @param int   $limit
372
-     * @return bool
373
-     */
374
-    private function deleteTransientKeys(array $transient_keys, $limit = 50)
375
-    {
376
-        if (empty($transient_keys)) {
377
-            return false;
378
-        }
379
-        $counter = 0;
380
-        foreach ($transient_keys as $transient_key) {
381
-            if($counter === $limit){
382
-                break;
383
-            }
384
-            // remove any transient prefixes
385
-            $transient_key = strpos($transient_key,  '_transient_timeout_') === 0
386
-                ? str_replace('_transient_timeout_', '', $transient_key)
387
-                : $transient_key;
388
-            $transient_key = strpos($transient_key,  '_transient_') === 0
389
-                ? str_replace('_transient_', '', $transient_key)
390
-                : $transient_key;
391
-            delete_transient($transient_key);
392
-            unset($this->transients[$transient_key]);
393
-            $counter++;
394
-        }
395
-        return $counter > 0;
396
-    }
22
+	/**
23
+	 * wp-option option_name for tracking transients
24
+	 *
25
+	 * @type string
26
+	 */
27
+	const TRANSIENT_SCHEDULE_OPTIONS_KEY = 'ee_transient_schedule';
28
+
29
+	/**
30
+	 * @var int $current_time
31
+	 */
32
+	private $current_time;
33
+
34
+	/**
35
+	 * how often to perform transient cleanup
36
+	 *
37
+	 * @var string $transient_cleanup_frequency
38
+	 */
39
+	private $transient_cleanup_frequency;
40
+
41
+	/**
42
+	 * options for how often to perform transient cleanup
43
+	 *
44
+	 * @var array $transient_cleanup_frequency_options
45
+	 */
46
+	private $transient_cleanup_frequency_options = array();
47
+
48
+	/**
49
+	 * @var array $transients
50
+	 */
51
+	private $transients;
52
+
53
+
54
+
55
+	/**
56
+	 * TransientCacheStorage constructor.
57
+	 */
58
+	public function __construct()
59
+	{
60
+		$this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
61
+		// round current time down to closest 5 minutes to simplify scheduling
62
+		$this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
63
+		$this->transients = (array)get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
64
+		if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
65
+			add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
66
+		}
67
+	}
68
+
69
+
70
+
71
+	/**
72
+	 * Sets how often transient cleanup occurs
73
+	 *
74
+	 * @return string
75
+	 */
76
+	private function setTransientCleanupFrequency()
77
+	{
78
+		// sets how often transients are cleaned up
79
+		$this->transient_cleanup_frequency_options = apply_filters(
80
+			'FHEE__TransientCacheStorage__transient_cleanup_schedule_options',
81
+			array(
82
+				'off',
83
+				'15-minutes',
84
+				'hour',
85
+				'12-hours',
86
+				'day',
87
+			)
88
+		);
89
+		$transient_cleanup_frequency = apply_filters(
90
+			'FHEE__TransientCacheStorage__transient_cleanup_schedule',
91
+			'hour'
92
+		);
93
+		return in_array(
94
+			$transient_cleanup_frequency,
95
+			$this->transient_cleanup_frequency_options,
96
+			true
97
+		)
98
+			? $transient_cleanup_frequency
99
+			: 'hour';
100
+	}
101
+
102
+
103
+
104
+	/**
105
+	 * we need to be able to round timestamps off to match the set transient cleanup frequency
106
+	 * so if a transient is set to expire at 1:17 pm for example, and our cleanup schedule is every hour,
107
+	 * then that timestamp needs to be rounded up to 2:00 pm so that it is removed
108
+	 * during the next scheduled cleanup after its expiration.
109
+	 * We also round off the current time timestamp to the closest 5 minutes
110
+	 * just to make the timestamps a little easier to round which helps with debugging.
111
+	 *
112
+	 * @param int    $timestamp [required]
113
+	 * @param string $cleanup_frequency
114
+	 * @param bool   $round_up
115
+	 * @return int
116
+	 */
117
+	private function roundTimestamp($timestamp, $cleanup_frequency = 'hour', $round_up = true)
118
+	{
119
+		$cleanup_frequency = $cleanup_frequency ? $cleanup_frequency : $this->transient_cleanup_frequency;
120
+		// in order to round the time to the closest xx minutes (or hours),
121
+		// we take the minutes (or hours) portion of the timestamp and divide it by xx,
122
+		// round down to a whole number, then multiply by xx to bring us almost back up to where we were
123
+		// why round down ? so the minutes (or hours) don't go over 60 (or 24)
124
+		// and bump the hour, which could bump the day, which could bump the month, etc,
125
+		// which would be bad because we don't always want to round up,
126
+		// but when we do we can easily achieve that by simply adding the desired offset,
127
+		$minutes = '00';
128
+		$hours = 'H';
129
+		switch ($cleanup_frequency) {
130
+			case '5-minutes' :
131
+				$minutes = floor((int)date('i', $timestamp) / 5) * 5;
132
+				$minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
133
+				$offset = MINUTE_IN_SECONDS * 5;
134
+				break;
135
+			case '15-minutes' :
136
+				$minutes = floor((int)date('i', $timestamp) / 15) * 15;
137
+				$minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
138
+				$offset = MINUTE_IN_SECONDS * 15;
139
+				break;
140
+			case '12-hours' :
141
+				$hours = floor((int)date('H', $timestamp) / 12) * 12;
142
+				$hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
143
+				$offset = HOUR_IN_SECONDS * 12;
144
+				break;
145
+			case 'day' :
146
+				$hours = '03'; // run cleanup at 3:00 am (or first site hit after that)
147
+				$offset = DAY_IN_SECONDS;
148
+				break;
149
+			case 'hour' :
150
+			default :
151
+				$offset = HOUR_IN_SECONDS;
152
+				break;
153
+		}
154
+		$rounded_timestamp = (int) strtotime(date("Y-m-d {$hours}:{$minutes}:00", $timestamp));
155
+		$rounded_timestamp += $round_up ? $offset : 0;
156
+		return apply_filters(
157
+			'FHEE__TransientCacheStorage__roundTimestamp__timestamp',
158
+			$rounded_timestamp,
159
+			$timestamp,
160
+			$cleanup_frequency,
161
+			$round_up
162
+		);
163
+	}
164
+
165
+
166
+
167
+	/**
168
+	 * Saves supplied data to a transient
169
+	 * if an expiration is set, then it automatically schedules the transient for cleanup
170
+	 *
171
+	 * @param string $transient_key [required]
172
+	 * @param string $data          [required]
173
+	 * @param int    $expiration    number of seconds until the cache expires
174
+	 * @return bool
175
+	 */
176
+	public function add($transient_key, $data, $expiration = 0)
177
+	{
178
+		$expiration = (int)abs($expiration);
179
+		$saved = set_transient($transient_key, $data, $expiration);
180
+		if ($saved && $expiration) {
181
+			$this->scheduleTransientCleanup($transient_key, $expiration);
182
+		}
183
+		return $saved;
184
+	}
185
+
186
+
187
+
188
+	/**
189
+	 * retrieves transient data
190
+	 * automatically triggers early cache refresh for standard cache items
191
+	 * in order to avoid cache stampedes on busy sites.
192
+	 * For non-standard cache items like PHP Session data where early refreshing is not wanted,
193
+	 * the $standard_cache parameter should be set to false when retrieving data
194
+	 *
195
+	 * @param string $transient_key [required]
196
+	 * @param bool   $standard_cache
197
+	 * @return mixed|null
198
+	 */
199
+	public function get($transient_key, $standard_cache = true)
200
+	{
201
+		if (isset($this->transients[ $transient_key ])) {
202
+			// to avoid cache stampedes (AKA:dogpiles) for standard cache items,
203
+			// check if known cache expires within the next minute,
204
+			// and if so, remove it from our tracking and and return nothing.
205
+			// this should trigger the cache content to be regenerated during this request,
206
+			// while allowing any following requests to still access the existing cache
207
+			// until it gets replaced with the refreshed content
208
+			if (
209
+				$standard_cache
210
+				&& $this->transients[$transient_key] - time() <= MINUTE_IN_SECONDS
211
+			) {
212
+				unset($this->transients[$transient_key]);
213
+				$this->updateTransients();
214
+				return null;
215
+			}
216
+
217
+			// for non standard cache items, remove the key from our tracking,
218
+			// but proceed to retrieve the transient so that it also gets removed from the db
219
+			if ($this->transients[$transient_key] <= time()) {
220
+				unset($this->transients[$transient_key]);
221
+				$this->updateTransients();
222
+			}
223
+		}
224
+
225
+		$content = get_transient($transient_key);
226
+		return $content !== false ? $content : null;
227
+	}
228
+
229
+
230
+
231
+	/**
232
+	 * delete a single transient and remove tracking
233
+	 *
234
+	 * @param string $transient_key [required] full or partial transient key to be deleted
235
+	 */
236
+	public function delete($transient_key)
237
+	{
238
+		$this->deleteMany(array($transient_key));
239
+	}
240
+
241
+
242
+
243
+	/**
244
+	 * delete multiple transients and remove tracking
245
+	 *
246
+	 * @param array $transient_keys [required] array of full or partial transient keys to be deleted
247
+	 * @param bool  $force_delete   [optional] if true, then will not check incoming keys against those being tracked
248
+	 *                              and proceed directly to deleting those entries from the cache storage
249
+	 */
250
+	public function deleteMany(array $transient_keys, $force_delete = false)
251
+	{
252
+		$full_transient_keys = $force_delete ? $transient_keys : array();
253
+		if(empty($full_transient_keys)){
254
+			foreach ($this->transients as $transient_key => $expiration) {
255
+				foreach ($transient_keys as $transient_key_to_delete) {
256
+					if (strpos($transient_key, $transient_key_to_delete) !== false) {
257
+						$full_transient_keys[] = $transient_key;
258
+					}
259
+				}
260
+			}
261
+		}
262
+		if ($this->deleteTransientKeys($full_transient_keys)) {
263
+			$this->updateTransients();
264
+		}
265
+	}
266
+
267
+
268
+
269
+	/**
270
+	 * sorts transients numerically by timestamp
271
+	 * then saves the transient schedule to a WP option
272
+	 */
273
+	private function updateTransients()
274
+	{
275
+		asort($this->transients, SORT_NUMERIC);
276
+		update_option(
277
+			TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY,
278
+			$this->transients
279
+		);
280
+	}
281
+
282
+
283
+
284
+	/**
285
+	 * schedules a transient for cleanup by adding it to the transient tracking
286
+	 *
287
+	 * @param string $transient_key [required]
288
+	 * @param int    $expiration    [required]
289
+	 */
290
+	private function scheduleTransientCleanup($transient_key, $expiration)
291
+	{
292
+		// make sure a valid future timestamp is set
293
+		$expiration += $expiration < time() ? time() : 0;
294
+		// and round to the closest 15 minutes
295
+		$expiration = $this->roundTimestamp($expiration);
296
+		// save transients to clear using their ID as the key to avoid duplicates
297
+		$this->transients[$transient_key] = $expiration;
298
+		$this->updateTransients();
299
+	}
300
+
301
+
302
+
303
+	/**
304
+	 * Since our tracked transients are sorted by their timestamps
305
+	 * we can grab the first transient and see when it is scheduled for cleanup.
306
+	 * If that timestamp is less than or equal to the current time,
307
+	 * then cleanup is triggered
308
+	 */
309
+	public function checkTransientCleanupSchedule()
310
+	{
311
+		if (empty($this->transients)) {
312
+			return;
313
+		}
314
+		// when do we run the next cleanup job?
315
+		reset($this->transients);
316
+		$next_scheduled_cleanup = current($this->transients);
317
+		// if the next cleanup job is scheduled for the current hour
318
+		if ($next_scheduled_cleanup <= $this->current_time) {
319
+			if ($this->cleanupExpiredTransients()) {
320
+				$this->updateTransients();
321
+			}
322
+		}
323
+	}
324
+
325
+
326
+
327
+	/**
328
+	 * loops through the array of tracked transients,
329
+	 * compiles a list of those that have expired, and sends that list off for deletion.
330
+	 * Also removes any bad records from the transients array
331
+	 *
332
+	 * @return bool
333
+	 */
334
+	private function cleanupExpiredTransients()
335
+	{
336
+		$update = false;
337
+		// filter the query limit. Set to 0 to turn off garbage collection
338
+		$limit = (int)abs(
339
+			apply_filters(
340
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
341
+				50
342
+			)
343
+		);
344
+		// non-zero LIMIT means take out the trash
345
+		if ($limit) {
346
+			$transient_keys = array();
347
+			foreach ($this->transients as $transient_key => $expiration) {
348
+				if ($expiration > $this->current_time) {
349
+					continue;
350
+				}
351
+				if ( ! $expiration || ! $transient_key) {
352
+					unset($this->transients[$transient_key]);
353
+					$update = true;
354
+					continue;
355
+				}
356
+				$transient_keys[] = $transient_key;
357
+			}
358
+			// delete expired keys, but maintain value of $update if nothing is deleted
359
+			$update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
360
+			do_action( 'FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
361
+		}
362
+		return $update;
363
+	}
364
+
365
+
366
+
367
+	/**
368
+	 * calls delete_transient() on each transient key provided, up to the specified limit
369
+	 *
370
+	 * @param array $transient_keys [required]
371
+	 * @param int   $limit
372
+	 * @return bool
373
+	 */
374
+	private function deleteTransientKeys(array $transient_keys, $limit = 50)
375
+	{
376
+		if (empty($transient_keys)) {
377
+			return false;
378
+		}
379
+		$counter = 0;
380
+		foreach ($transient_keys as $transient_key) {
381
+			if($counter === $limit){
382
+				break;
383
+			}
384
+			// remove any transient prefixes
385
+			$transient_key = strpos($transient_key,  '_transient_timeout_') === 0
386
+				? str_replace('_transient_timeout_', '', $transient_key)
387
+				: $transient_key;
388
+			$transient_key = strpos($transient_key,  '_transient_') === 0
389
+				? str_replace('_transient_', '', $transient_key)
390
+				: $transient_key;
391
+			delete_transient($transient_key);
392
+			unset($this->transients[$transient_key]);
393
+			$counter++;
394
+		}
395
+		return $counter > 0;
396
+	}
397 397
 
398 398
 
399 399
 
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -60,7 +60,7 @@  discard block
 block discarded – undo
60 60
         $this->transient_cleanup_frequency = $this->setTransientCleanupFrequency();
61 61
         // round current time down to closest 5 minutes to simplify scheduling
62 62
         $this->current_time = $this->roundTimestamp(time(), '5-minutes', false);
63
-        $this->transients = (array)get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
63
+        $this->transients = (array) get_option(TransientCacheStorage::TRANSIENT_SCHEDULE_OPTIONS_KEY, array());
64 64
         if ( ! (defined('DOING_AJAX') && DOING_AJAX) && $this->transient_cleanup_frequency !== 'off') {
65 65
             add_action('shutdown', array($this, 'checkTransientCleanupSchedule'), 999);
66 66
         }
@@ -128,17 +128,17 @@  discard block
 block discarded – undo
128 128
         $hours = 'H';
129 129
         switch ($cleanup_frequency) {
130 130
             case '5-minutes' :
131
-                $minutes = floor((int)date('i', $timestamp) / 5) * 5;
131
+                $minutes = floor((int) date('i', $timestamp) / 5) * 5;
132 132
                 $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
133 133
                 $offset = MINUTE_IN_SECONDS * 5;
134 134
                 break;
135 135
             case '15-minutes' :
136
-                $minutes = floor((int)date('i', $timestamp) / 15) * 15;
136
+                $minutes = floor((int) date('i', $timestamp) / 15) * 15;
137 137
                 $minutes = str_pad($minutes, 2, '0', STR_PAD_LEFT);
138 138
                 $offset = MINUTE_IN_SECONDS * 15;
139 139
                 break;
140 140
             case '12-hours' :
141
-                $hours = floor((int)date('H', $timestamp) / 12) * 12;
141
+                $hours = floor((int) date('H', $timestamp) / 12) * 12;
142 142
                 $hours = str_pad($hours, 2, '0', STR_PAD_LEFT);
143 143
                 $offset = HOUR_IN_SECONDS * 12;
144 144
                 break;
@@ -175,7 +175,7 @@  discard block
 block discarded – undo
175 175
      */
176 176
     public function add($transient_key, $data, $expiration = 0)
177 177
     {
178
-        $expiration = (int)abs($expiration);
178
+        $expiration = (int) abs($expiration);
179 179
         $saved = set_transient($transient_key, $data, $expiration);
180 180
         if ($saved && $expiration) {
181 181
             $this->scheduleTransientCleanup($transient_key, $expiration);
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
      */
199 199
     public function get($transient_key, $standard_cache = true)
200 200
     {
201
-        if (isset($this->transients[ $transient_key ])) {
201
+        if (isset($this->transients[$transient_key])) {
202 202
             // to avoid cache stampedes (AKA:dogpiles) for standard cache items,
203 203
             // check if known cache expires within the next minute,
204 204
             // and if so, remove it from our tracking and and return nothing.
@@ -250,7 +250,7 @@  discard block
 block discarded – undo
250 250
     public function deleteMany(array $transient_keys, $force_delete = false)
251 251
     {
252 252
         $full_transient_keys = $force_delete ? $transient_keys : array();
253
-        if(empty($full_transient_keys)){
253
+        if (empty($full_transient_keys)) {
254 254
             foreach ($this->transients as $transient_key => $expiration) {
255 255
                 foreach ($transient_keys as $transient_key_to_delete) {
256 256
                     if (strpos($transient_key, $transient_key_to_delete) !== false) {
@@ -335,7 +335,7 @@  discard block
 block discarded – undo
335 335
     {
336 336
         $update = false;
337 337
         // filter the query limit. Set to 0 to turn off garbage collection
338
-        $limit = (int)abs(
338
+        $limit = (int) abs(
339 339
             apply_filters(
340 340
                 'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
341 341
                 50
@@ -357,7 +357,7 @@  discard block
 block discarded – undo
357 357
             }
358 358
             // delete expired keys, but maintain value of $update if nothing is deleted
359 359
             $update = $this->deleteTransientKeys($transient_keys, $limit) ? true : $update;
360
-            do_action( 'FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
360
+            do_action('FHEE__TransientCacheStorage__clearExpiredTransients__end', $this);
361 361
         }
362 362
         return $update;
363 363
     }
@@ -378,14 +378,14 @@  discard block
 block discarded – undo
378 378
         }
379 379
         $counter = 0;
380 380
         foreach ($transient_keys as $transient_key) {
381
-            if($counter === $limit){
381
+            if ($counter === $limit) {
382 382
                 break;
383 383
             }
384 384
             // remove any transient prefixes
385
-            $transient_key = strpos($transient_key,  '_transient_timeout_') === 0
385
+            $transient_key = strpos($transient_key, '_transient_timeout_') === 0
386 386
                 ? str_replace('_transient_timeout_', '', $transient_key)
387 387
                 : $transient_key;
388
-            $transient_key = strpos($transient_key,  '_transient_') === 0
388
+            $transient_key = strpos($transient_key, '_transient_') === 0
389 389
                 ? str_replace('_transient_', '', $transient_key)
390 390
                 : $transient_key;
391 391
             delete_transient($transient_key);
Please login to merge, or discard this patch.
core/libraries/plugin_api/EE_Register_Payment_Method.lib.php 2 patches
Indentation   +168 added lines, -168 removed lines patch added patch discarded remove patch
@@ -22,174 +22,174 @@
 block discarded – undo
22 22
 class EE_Register_Payment_Method implements EEI_Plugin_API
23 23
 {
24 24
 
25
-    /**
26
-     * Holds values for registered payment methods
27
-     *
28
-     * @var array
29
-     */
30
-    protected static $_settings = array();
31
-
32
-
33
-
34
-    /**
35
-     * Method for registering new EE_PMT_Base children
36
-     *
37
-     * @since    4.5.0
38
-     * @param string  $payment_method_id    a unique identifier for this set of modules Required.
39
-     * @param  array  $setup_args           an array of arguments provided for registering modules Required.{
40
-     * @type string[] $payment_method_paths each element is the folder containing the EE_PMT_Base child class
41
-     *                                      (eg, 'public_html/wp-content/plugins/my_plugin/Payomatic/' which contains
42
-     *                                      the files EE_PMT_Payomatic.pm.php)
43
-     *                                      }
44
-     * @throws EE_Error
45
-     * @type array payment_method_paths    an array of full server paths to folders containing any EE_PMT_Base
46
-     *                                      children, or to the EED_Module files themselves
47
-     * @return void
48
-     * @throws InvalidDataTypeException
49
-     * @throws DomainException
50
-     * @throws InvalidArgumentException
51
-     * @throws InvalidInterfaceException
52
-     * @throws InvalidDataTypeException
53
-     */
54
-    public static function register($payment_method_id = null, $setup_args = array())
55
-    {
56
-        //required fields MUST be present, so let's make sure they are.
57
-        if (empty($payment_method_id) || ! is_array($setup_args) || empty($setup_args['payment_method_paths'])) {
58
-            throw new EE_Error(
59
-                esc_html__(
60
-                    'In order to register Payment Methods with EE_Register_Payment_Method::register(), you must include a "payment_method_id" (a unique identifier for this set of modules), and an array containing the following keys: "payment_method_paths" (an array of full server paths to folders that contain modules, or to the module files themselves)',
61
-                    'event_espresso'
62
-                )
63
-            );
64
-        }
65
-        //make sure we don't register twice
66
-        if (isset(self::$_settings[$payment_method_id])) {
67
-            return;
68
-        }
69
-        //make sure this was called in the right place!
70
-        if (
71
-            ! did_action('AHEE__EE_System__load_espresso_addons')
72
-            || did_action('AHEE__EE_System__register_shortcodes_modules_and_widgets')
73
-        ) {
74
-            EE_Error::doing_it_wrong(
75
-                __METHOD__,
76
-                esc_html__(
77
-                    'An attempt to register modules has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__register_shortcodes_modules_and_widgets" hook to register modules.',
78
-                    'event_espresso'
79
-                ),
80
-                '4.3.0'
81
-            );
82
-        }
83
-        //setup $_settings array from incoming values.
84
-        self::$_settings[$payment_method_id] = array(
85
-            // array of full server paths to any EE_PMT_Base children used
86
-            'payment_method_paths' => isset($setup_args['payment_method_paths'])
87
-                ? (array)$setup_args['payment_method_paths']
88
-                : array(),
89
-        );
90
-        // add to list of modules to be registered
91
-        add_filter(
92
-            'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
93
-            array('EE_Register_Payment_Method', 'add_payment_methods')
94
-        );
95
-        // If EE_Payment_Method_Manager::register_payment_methods has already been called,
96
-        // then we need to add our caps for this payment method manually
97
-        if (did_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods')) {
98
-            $payment_method_manager = LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
99
-            // register payment methods directly
100
-            foreach (self::$_settings[$payment_method_id]['payment_method_paths'] as $payment_method_path) {
101
-                $payment_method_manager->register_payment_method($payment_method_path);
102
-            }
103
-            $capabilities = LoaderFactory::getLoader()->getShared('EE_Capabilities');
104
-            $capabilities->addCaps(
105
-                self::getPaymentMethodCapabilities(self::$_settings[$payment_method_id])
106
-            );
107
-        }
108
-    }
109
-
110
-
111
-
112
-    /**
113
-     * Filters the list of payment methods to add ours.
114
-     * and they're just full filepaths to FOLDERS containing a payment method class file. Eg.
115
-     *
116
-     * @param array $payment_method_folders array of paths to all payment methods that require registering
117
-     * @return array
118
-     */
119
-    public static function add_payment_methods($payment_method_folders)
120
-    {
121
-        foreach (self::$_settings as $settings) {
122
-            foreach ($settings['payment_method_paths'] as $payment_method_path) {
123
-                $payment_method_folders[] = $payment_method_path;
124
-            }
125
-        }
126
-        return $payment_method_folders;
127
-    }
128
-
129
-
130
-
131
-    /**
132
-     * This deregisters a module that was previously registered with a specific $module_id.
133
-     *
134
-     * @since    4.3.0
135
-     *
136
-     * @param string $module_id the name for the module that was previously registered
137
-     * @return void
138
-     * @throws DomainException
139
-     * @throws EE_Error
140
-     * @throws InvalidArgumentException
141
-     * @throws InvalidInterfaceException
142
-     * @throws InvalidDataTypeException
143
-     */
144
-    public static function deregister($module_id = null)
145
-    {
146
-        if (isset(self::$_settings[$module_id])) {
147
-
148
-            //set action for just this module id to delay deregistration until core is loaded and ready.
149
-            $module_settings = self::$_settings[$module_id];
150
-            unset(self::$_settings[$module_id]);
151
-            add_action(
152
-                'AHEE__EE_System__core_loaded_and_ready',
153
-                function () use ($module_settings) {
154
-                    $capabilities = LoaderFactory::getLoader()->getShared('EE_Capabilities');
155
-                    $capabilities->removeCaps(
156
-                        EE_Register_Payment_Method::getPaymentMethodCapabilities($module_settings)
157
-                    );
158
-                }
159
-            );
160
-        }
161
-    }
162
-
163
-
164
-
165
-    /**
166
-     * returns an array of the caps that get added when a Payment Method is registered
167
-     *
168
-     * @param array $settings
169
-     * @return array
170
-     * @throws DomainException
171
-     * @throws EE_Error
172
-     * @throws InvalidArgumentException
173
-     * @throws InvalidInterfaceException
174
-     * @throws InvalidDataTypeException
175
-     * @access private  Developers do NOT use this method.  It's only public for PHP5.3 closure support (see deregister)
176
-     *                  When we drop support for PHP5.3 this will be made private again.  You have been warned.
177
-     *
178
-     */
179
-    public static function getPaymentMethodCapabilities(array $settings)
180
-    {
181
-        $payment_method_manager = LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
182
-        $payment_method_caps = array('administrator' => array());
183
-        if (isset($settings['payment_method_paths'])) {
184
-            foreach ($settings['payment_method_paths'] as $payment_method_path) {
185
-                $payment_method_caps = $payment_method_manager->addPaymentMethodCap(
186
-                    strtolower(basename($payment_method_path)),
187
-                    $payment_method_caps
188
-                );
189
-            }
190
-        }
191
-        return $payment_method_caps;
192
-    }
25
+	/**
26
+	 * Holds values for registered payment methods
27
+	 *
28
+	 * @var array
29
+	 */
30
+	protected static $_settings = array();
31
+
32
+
33
+
34
+	/**
35
+	 * Method for registering new EE_PMT_Base children
36
+	 *
37
+	 * @since    4.5.0
38
+	 * @param string  $payment_method_id    a unique identifier for this set of modules Required.
39
+	 * @param  array  $setup_args           an array of arguments provided for registering modules Required.{
40
+	 * @type string[] $payment_method_paths each element is the folder containing the EE_PMT_Base child class
41
+	 *                                      (eg, 'public_html/wp-content/plugins/my_plugin/Payomatic/' which contains
42
+	 *                                      the files EE_PMT_Payomatic.pm.php)
43
+	 *                                      }
44
+	 * @throws EE_Error
45
+	 * @type array payment_method_paths    an array of full server paths to folders containing any EE_PMT_Base
46
+	 *                                      children, or to the EED_Module files themselves
47
+	 * @return void
48
+	 * @throws InvalidDataTypeException
49
+	 * @throws DomainException
50
+	 * @throws InvalidArgumentException
51
+	 * @throws InvalidInterfaceException
52
+	 * @throws InvalidDataTypeException
53
+	 */
54
+	public static function register($payment_method_id = null, $setup_args = array())
55
+	{
56
+		//required fields MUST be present, so let's make sure they are.
57
+		if (empty($payment_method_id) || ! is_array($setup_args) || empty($setup_args['payment_method_paths'])) {
58
+			throw new EE_Error(
59
+				esc_html__(
60
+					'In order to register Payment Methods with EE_Register_Payment_Method::register(), you must include a "payment_method_id" (a unique identifier for this set of modules), and an array containing the following keys: "payment_method_paths" (an array of full server paths to folders that contain modules, or to the module files themselves)',
61
+					'event_espresso'
62
+				)
63
+			);
64
+		}
65
+		//make sure we don't register twice
66
+		if (isset(self::$_settings[$payment_method_id])) {
67
+			return;
68
+		}
69
+		//make sure this was called in the right place!
70
+		if (
71
+			! did_action('AHEE__EE_System__load_espresso_addons')
72
+			|| did_action('AHEE__EE_System__register_shortcodes_modules_and_widgets')
73
+		) {
74
+			EE_Error::doing_it_wrong(
75
+				__METHOD__,
76
+				esc_html__(
77
+					'An attempt to register modules has failed because it was not registered at the correct time.  Please use the "AHEE__EE_System__register_shortcodes_modules_and_widgets" hook to register modules.',
78
+					'event_espresso'
79
+				),
80
+				'4.3.0'
81
+			);
82
+		}
83
+		//setup $_settings array from incoming values.
84
+		self::$_settings[$payment_method_id] = array(
85
+			// array of full server paths to any EE_PMT_Base children used
86
+			'payment_method_paths' => isset($setup_args['payment_method_paths'])
87
+				? (array)$setup_args['payment_method_paths']
88
+				: array(),
89
+		);
90
+		// add to list of modules to be registered
91
+		add_filter(
92
+			'FHEE__EE_Payment_Method_Manager__register_payment_methods__payment_methods_to_register',
93
+			array('EE_Register_Payment_Method', 'add_payment_methods')
94
+		);
95
+		// If EE_Payment_Method_Manager::register_payment_methods has already been called,
96
+		// then we need to add our caps for this payment method manually
97
+		if (did_action('FHEE__EE_Payment_Method_Manager__register_payment_methods__registered_payment_methods')) {
98
+			$payment_method_manager = LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
99
+			// register payment methods directly
100
+			foreach (self::$_settings[$payment_method_id]['payment_method_paths'] as $payment_method_path) {
101
+				$payment_method_manager->register_payment_method($payment_method_path);
102
+			}
103
+			$capabilities = LoaderFactory::getLoader()->getShared('EE_Capabilities');
104
+			$capabilities->addCaps(
105
+				self::getPaymentMethodCapabilities(self::$_settings[$payment_method_id])
106
+			);
107
+		}
108
+	}
109
+
110
+
111
+
112
+	/**
113
+	 * Filters the list of payment methods to add ours.
114
+	 * and they're just full filepaths to FOLDERS containing a payment method class file. Eg.
115
+	 *
116
+	 * @param array $payment_method_folders array of paths to all payment methods that require registering
117
+	 * @return array
118
+	 */
119
+	public static function add_payment_methods($payment_method_folders)
120
+	{
121
+		foreach (self::$_settings as $settings) {
122
+			foreach ($settings['payment_method_paths'] as $payment_method_path) {
123
+				$payment_method_folders[] = $payment_method_path;
124
+			}
125
+		}
126
+		return $payment_method_folders;
127
+	}
128
+
129
+
130
+
131
+	/**
132
+	 * This deregisters a module that was previously registered with a specific $module_id.
133
+	 *
134
+	 * @since    4.3.0
135
+	 *
136
+	 * @param string $module_id the name for the module that was previously registered
137
+	 * @return void
138
+	 * @throws DomainException
139
+	 * @throws EE_Error
140
+	 * @throws InvalidArgumentException
141
+	 * @throws InvalidInterfaceException
142
+	 * @throws InvalidDataTypeException
143
+	 */
144
+	public static function deregister($module_id = null)
145
+	{
146
+		if (isset(self::$_settings[$module_id])) {
147
+
148
+			//set action for just this module id to delay deregistration until core is loaded and ready.
149
+			$module_settings = self::$_settings[$module_id];
150
+			unset(self::$_settings[$module_id]);
151
+			add_action(
152
+				'AHEE__EE_System__core_loaded_and_ready',
153
+				function () use ($module_settings) {
154
+					$capabilities = LoaderFactory::getLoader()->getShared('EE_Capabilities');
155
+					$capabilities->removeCaps(
156
+						EE_Register_Payment_Method::getPaymentMethodCapabilities($module_settings)
157
+					);
158
+				}
159
+			);
160
+		}
161
+	}
162
+
163
+
164
+
165
+	/**
166
+	 * returns an array of the caps that get added when a Payment Method is registered
167
+	 *
168
+	 * @param array $settings
169
+	 * @return array
170
+	 * @throws DomainException
171
+	 * @throws EE_Error
172
+	 * @throws InvalidArgumentException
173
+	 * @throws InvalidInterfaceException
174
+	 * @throws InvalidDataTypeException
175
+	 * @access private  Developers do NOT use this method.  It's only public for PHP5.3 closure support (see deregister)
176
+	 *                  When we drop support for PHP5.3 this will be made private again.  You have been warned.
177
+	 *
178
+	 */
179
+	public static function getPaymentMethodCapabilities(array $settings)
180
+	{
181
+		$payment_method_manager = LoaderFactory::getLoader()->getShared('EE_Payment_Method_Manager');
182
+		$payment_method_caps = array('administrator' => array());
183
+		if (isset($settings['payment_method_paths'])) {
184
+			foreach ($settings['payment_method_paths'] as $payment_method_path) {
185
+				$payment_method_caps = $payment_method_manager->addPaymentMethodCap(
186
+					strtolower(basename($payment_method_path)),
187
+					$payment_method_caps
188
+				);
189
+			}
190
+		}
191
+		return $payment_method_caps;
192
+	}
193 193
 
194 194
 }
195 195
 // End of file EE_Register_Payment_Method.lib.php
Please login to merge, or discard this patch.
Spacing   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -84,7 +84,7 @@  discard block
 block discarded – undo
84 84
         self::$_settings[$payment_method_id] = array(
85 85
             // array of full server paths to any EE_PMT_Base children used
86 86
             'payment_method_paths' => isset($setup_args['payment_method_paths'])
87
-                ? (array)$setup_args['payment_method_paths']
87
+                ? (array) $setup_args['payment_method_paths']
88 88
                 : array(),
89 89
         );
90 90
         // add to list of modules to be registered
@@ -150,7 +150,7 @@  discard block
 block discarded – undo
150 150
             unset(self::$_settings[$module_id]);
151 151
             add_action(
152 152
                 'AHEE__EE_System__core_loaded_and_ready',
153
-                function () use ($module_settings) {
153
+                function() use ($module_settings) {
154 154
                     $capabilities = LoaderFactory::getLoader()->getShared('EE_Capabilities');
155 155
                     $capabilities->removeCaps(
156 156
                         EE_Register_Payment_Method::getPaymentMethodCapabilities($module_settings)
Please login to merge, or discard this patch.
admin_pages/maintenance/Maintenance_Admin_Page.core.php 1 patch
Indentation   +827 added lines, -827 removed lines patch added patch discarded remove patch
@@ -29,843 +29,843 @@
 block discarded – undo
29 29
 {
30 30
 
31 31
 
32
-    /**
33
-     * @var EE_Datetime_Offset_Fix_Form
34
-     */
35
-    protected $datetime_fix_offset_form;
36
-
37
-
38
-
39
-    protected function _init_page_props()
40
-    {
41
-        $this->page_slug = EE_MAINTENANCE_PG_SLUG;
42
-        $this->page_label = EE_MAINTENANCE_LABEL;
43
-        $this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL;
44
-        $this->_admin_base_path = EE_MAINTENANCE_ADMIN;
45
-    }
46
-
47
-
48
-
49
-    protected function _ajax_hooks()
50
-    {
51
-        add_action('wp_ajax_migration_step', array($this, 'migration_step'));
52
-        add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran'));
53
-    }
54
-
55
-
56
-
57
-    protected function _define_page_props()
58
-    {
59
-        $this->_admin_page_title = EE_MAINTENANCE_LABEL;
60
-        $this->_labels = array(
61
-            'buttons' => array(
62
-                'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
63
-                'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
64
-            ),
65
-        );
66
-    }
67
-
68
-
69
-
70
-    protected function _set_page_routes()
71
-    {
72
-        $this->_page_routes = array(
73
-            'default'                             => array(
74
-                'func'       => '_maintenance',
75
-                'capability' => 'manage_options',
76
-            ),
77
-            'change_maintenance_level'            => array(
78
-                'func'       => '_change_maintenance_level',
79
-                'capability' => 'manage_options',
80
-                'noheader'   => true,
81
-            ),
82
-            'system_status'                       => array(
83
-                'func'       => '_system_status',
84
-                'capability' => 'manage_options',
85
-            ),
86
-            'download_system_status' => array(
87
-                'func'       => '_download_system_status',
88
-                'capability' => 'manage_options',
89
-                'noheader'   => true,
90
-            ),
91
-            'send_migration_crash_report'         => array(
92
-                'func'       => '_send_migration_crash_report',
93
-                'capability' => 'manage_options',
94
-                'noheader'   => true,
95
-            ),
96
-            'confirm_migration_crash_report_sent' => array(
97
-                'func'       => '_confirm_migration_crash_report_sent',
98
-                'capability' => 'manage_options',
99
-            ),
100
-            'data_reset'                          => array(
101
-                'func'       => '_data_reset_and_delete',
102
-                'capability' => 'manage_options',
103
-            ),
104
-            'reset_db'                            => array(
105
-                'func'       => '_reset_db',
106
-                'capability' => 'manage_options',
107
-                'noheader'   => true,
108
-                'args'       => array('nuke_old_ee4_data' => true),
109
-            ),
110
-            'start_with_fresh_ee4_db'             => array(
111
-                'func'       => '_reset_db',
112
-                'capability' => 'manage_options',
113
-                'noheader'   => true,
114
-                'args'       => array('nuke_old_ee4_data' => false),
115
-            ),
116
-            'delete_db'                           => array(
117
-                'func'       => '_delete_db',
118
-                'capability' => 'manage_options',
119
-                'noheader'   => true,
120
-            ),
121
-            'rerun_migration_from_ee3'            => array(
122
-                'func'       => '_rerun_migration_from_ee3',
123
-                'capability' => 'manage_options',
124
-                'noheader'   => true,
125
-            ),
126
-            'reset_reservations'                  => array(
127
-                'func'       => '_reset_reservations',
128
-                'capability' => 'manage_options',
129
-                'noheader'   => true,
130
-            ),
131
-            'reset_capabilities'                  => array(
132
-                'func'       => '_reset_capabilities',
133
-                'capability' => 'manage_options',
134
-                'noheader'   => true,
135
-            ),
136
-            'reattempt_migration'                 => array(
137
-                'func'       => '_reattempt_migration',
138
-                'capability' => 'manage_options',
139
-                'noheader'   => true,
140
-            ),
141
-            'datetime_tools' => array(
142
-                'func' => '_datetime_tools',
143
-                'capability' => 'manage_options'
144
-            ),
145
-            'run_datetime_offset_fix' => array(
146
-                'func' => '_apply_datetime_offset',
147
-                'noheader' => true,
148
-                'headers_sent_route' => 'datetime_tools',
149
-                'capability' => 'manage_options'
150
-            )
151
-        );
152
-    }
153
-
154
-
155
-
156
-    protected function _set_page_config()
157
-    {
158
-        $this->_page_config = array(
159
-            'default'       => array(
160
-                'nav'           => array(
161
-                    'label' => esc_html__('Maintenance', 'event_espresso'),
162
-                    'order' => 10,
163
-                ),
164
-                'require_nonce' => false,
165
-            ),
166
-            'data_reset'    => array(
167
-                'nav'           => array(
168
-                    'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
169
-                    'order' => 20,
170
-                ),
171
-                'require_nonce' => false,
172
-            ),
173
-            'datetime_tools' => array(
174
-                'nav' => array(
175
-                    'label' => esc_html__('Datetime Utilities', 'event_espresso'),
176
-                    'order' => 25
177
-                ),
178
-                'require_nonce' => false,
179
-            ),
180
-            'system_status' => array(
181
-                'nav'           => array(
182
-                    'label' => esc_html__("System Information", "event_espresso"),
183
-                    'order' => 30,
184
-                ),
185
-                'require_nonce' => false,
186
-            ),
187
-        );
188
-    }
189
-
190
-
191
-
192
-    /**
193
-     * default maintenance page. If we're in maintenance mode level 2, then we need to show
194
-     * the migration scripts and all that UI.
195
-     */
196
-    public function _maintenance()
197
-    {
198
-        //it all depends if we're in maintenance model level 1 (frontend-only) or
199
-        //level 2 (everything except maintenance page)
200
-        try {
201
-            //get the current maintenance level and check if
202
-            //we are removed
203
-            $mm = EE_Maintenance_Mode::instance()->level();
204
-            $placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
205
-            if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
206
-                //we just took the site out of maintenance mode, so notify the user.
207
-                //unfortunately this message appears to be echoed on the NEXT page load...
208
-                //oh well, we should really be checking for this on addon deactivation anyways
209
-                EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required',
210
-                    'event_espresso'));
211
-                $this->_process_notices(array('page' => 'espresso_maintenance_settings'), false);
212
-            }
213
-            //in case an exception is thrown while trying to handle migrations
214
-            switch (EE_Maintenance_Mode::instance()->level()) {
215
-                case EE_Maintenance_Mode::level_0_not_in_maintenance:
216
-                case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
217
-                    $show_maintenance_switch = true;
218
-                    $show_backup_db_text = false;
219
-                    $show_migration_progress = false;
220
-                    $script_names = array();
221
-                    $addons_should_be_upgraded_first = false;
222
-                    break;
223
-                case EE_Maintenance_Mode::level_2_complete_maintenance:
224
-                    $show_maintenance_switch = false;
225
-                    $show_migration_progress = true;
226
-                    if (isset($this->_req_data['continue_migration'])) {
227
-                        $show_backup_db_text = false;
228
-                    } else {
229
-                        $show_backup_db_text = true;
230
-                    }
231
-                    $scripts_needing_to_run = EE_Data_Migration_Manager::instance()
232
-                                                                       ->check_for_applicable_data_migration_scripts();
233
-                    $addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating();
234
-                    $script_names = array();
235
-                    $current_script = null;
236
-                    foreach ($scripts_needing_to_run as $script) {
237
-                        if ($script instanceof EE_Data_Migration_Script_Base) {
238
-                            if ( ! $current_script) {
239
-                                $current_script = $script;
240
-                                $current_script->migration_page_hooks();
241
-                            }
242
-                            $script_names[] = $script->pretty_name();
243
-                        }
244
-                    }
245
-                    break;
246
-            }
247
-            $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
248
-            $exception_thrown = false;
249
-        } catch (EE_Error $e) {
250
-            EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
251
-            //now, just so we can display the page correctly, make a error migration script stage object
252
-            //and also put the error on it. It only persists for the duration of this request
253
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
254
-            $most_recent_migration->add_error($e->getMessage());
255
-            $exception_thrown = true;
256
-        }
257
-        $current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set();
258
-        $current_db_state = str_replace('.decaf', '', $current_db_state);
259
-        if ($exception_thrown
260
-            || ($most_recent_migration
261
-                && $most_recent_migration instanceof EE_Data_Migration_Script_Base
262
-                && $most_recent_migration->is_broken()
263
-            )
264
-        ) {
265
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
266
-            $this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267
-            $this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268
-                                                                                        'success' => '0',
269
-            ), EE_MAINTENANCE_ADMIN_URL);
270
-        } elseif ($addons_should_be_upgraded_first) {
271
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
272
-        } else {
273
-            if ($most_recent_migration
274
-                && $most_recent_migration instanceof EE_Data_Migration_Script_Base
275
-                && $most_recent_migration->can_continue()
276
-            ) {
277
-                $show_backup_db_text = false;
278
-                $show_continue_current_migration_script = true;
279
-                $show_most_recent_migration = true;
280
-            } elseif (isset($this->_req_data['continue_migration'])) {
281
-                $show_most_recent_migration = true;
282
-                $show_continue_current_migration_script = false;
283
-            } else {
284
-                $show_most_recent_migration = false;
285
-                $show_continue_current_migration_script = false;
286
-            }
287
-            if (isset($current_script)) {
288
-                $migrates_to = $current_script->migrates_to_version();
289
-                $plugin_slug = $migrates_to['slug'];
290
-                $new_version = $migrates_to['version'];
291
-                $this->_template_args = array_merge($this->_template_args, array(
292
-                    'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"),
293
-                        isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug),
294
-                    'next_db_state'    => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'),
295
-                        $new_version, $plugin_slug) : null,
296
-                ));
297
-            } else {
298
-                $this->_template_args['current_db_state'] = null;
299
-                $this->_template_args['next_db_state'] = null;
300
-            }
301
-            $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
302
-            $this->_template_args = array_merge(
303
-                $this->_template_args,
304
-                array(
305
-                    'show_most_recent_migration'             => $show_most_recent_migration,
306
-                    //flag for showing the most recent migration's status and/or errors
307
-                    'show_migration_progress'                => $show_migration_progress,
308
-                    //flag for showing the option to run migrations and see their progress
309
-                    'show_backup_db_text'                    => $show_backup_db_text,
310
-                    //flag for showing text telling the user to backup their DB
311
-                    'show_maintenance_switch'                => $show_maintenance_switch,
312
-                    //flag for showing the option to change maintenance mode between levels 0 and 1
313
-                    'script_names'                           => $script_names,
314
-                    //array of names of scripts that have run
315
-                    'show_continue_current_migration_script' => $show_continue_current_migration_script,
316
-                    //flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
317
-                    'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
318
-                        EE_MAINTENANCE_ADMIN_URL),
319
-                    'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
320
-                        EE_MAINTENANCE_ADMIN_URL),
321
-                    'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'),
322
-                        EE_MAINTENANCE_ADMIN_URL),
323
-                    'ultimate_db_state'                      => sprintf(__("EE%s", 'event_espresso'),
324
-                        espresso_version()),
325
-                )
326
-            );
327
-            //make sure we have the form fields helper available. It usually is, but sometimes it isn't
328
-        }
329
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
330
-        //now render the migration options part, and put it in a variable
331
-        $migration_options_template_file = apply_filters(
332
-            'FHEE__ee_migration_page__migration_options_template',
333
-            EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
334
-        );
335
-        $migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
336
-        $this->_template_args['migration_options_html'] = $migration_options_html;
337
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338
-            $this->_template_args, true);
339
-        $this->display_admin_page_with_sidebar();
340
-    }
341
-
342
-
343
-
344
-    /**
345
-     * returns JSON and executes another step of the currently-executing data migration (called via ajax)
346
-     */
347
-    public function migration_step()
348
-    {
349
-        $this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request();
350
-        $this->_return_json();
351
-    }
352
-
353
-
354
-
355
-    /**
356
-     * Can be used by js when it notices a response with HTML in it in order
357
-     * to log the malformed response
358
-     */
359
-    public function add_error_to_migrations_ran()
360
-    {
361
-        EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']);
362
-        $this->_template_args['data'] = array('ok' => true);
363
-        $this->_return_json();
364
-    }
365
-
366
-
367
-
368
-    /**
369
-     * changes the maintenance level, provided there are still no migration scripts that should run
370
-     */
371
-    public function _change_maintenance_level()
372
-    {
373
-        $new_level = absint($this->_req_data['maintenance_mode_level']);
374
-        if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) {
375
-            EE_Maintenance_Mode::instance()->set_maintenance_level($new_level);
376
-            $success = true;
377
-        } else {
378
-            EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
379
-            $success = false;
380
-        }
381
-        $this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
382
-    }
383
-
384
-
385
-
386
-    /**
387
-     * a tab with options for resetting and/or deleting EE data
388
-     *
389
-     * @throws \EE_Error
390
-     * @throws \DomainException
391
-     */
392
-    public function _data_reset_and_delete()
393
-    {
394
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
395
-        $this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396
-            'reset_reservations',
397
-            'reset_reservations',
398
-            array(),
399
-            'button button-primary ee-confirm',
400
-            '',
401
-            false
402
-        );
403
-        $this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
404
-            'reset_capabilities',
405
-            'reset_capabilities',
406
-            array(),
407
-            'button button-primary ee-confirm',
408
-            '',
409
-            false
410
-        );
411
-        $this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
412
-            array('action' => 'delete_db'),
413
-            EE_MAINTENANCE_ADMIN_URL
414
-        );
415
-        $this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
416
-            array('action' => 'reset_db'),
417
-            EE_MAINTENANCE_ADMIN_URL
418
-        );
419
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template(
420
-            $this->_template_path,
421
-            $this->_template_args,
422
-            true
423
-        );
424
-        $this->display_admin_page_with_sidebar();
425
-    }
426
-
427
-
428
-
429
-    protected function _reset_reservations()
430
-    {
431
-        if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432
-            EE_Error::add_success(
433
-                __(
434
-                    'Ticket and datetime reserved counts have been successfully reset.',
435
-                    'event_espresso'
436
-                )
437
-            );
438
-        } else {
439
-            EE_Error::add_success(
440
-                __(
441
-                    'Ticket and datetime reserved counts were correct and did not need resetting.',
442
-                    'event_espresso'
443
-                )
444
-            );
445
-        }
446
-        $this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true);
447
-    }
448
-
449
-
450
-
451
-    protected function _reset_capabilities()
452
-    {
453
-        EE_Registry::instance()->CAP->init_caps(true);
454
-        EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.',
455
-            'event_espresso'));
456
-        $this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true);
457
-    }
458
-
459
-
460
-
461
-    /**
462
-     * resets the DMSs so we can attempt to continue migrating after a fatal error
463
-     * (only a good idea when someone has somehow tried ot fix whatever caused
464
-     * the fatal error in teh first place)
465
-     */
466
-    protected function _reattempt_migration()
467
-    {
468
-        EE_Data_Migration_Manager::instance()->reattempt();
469
-        $this->_redirect_after_action(false, '', '', array('action' => 'default'), true);
470
-    }
471
-
472
-
473
-
474
-    /**
475
-     * shows the big ol' System Information page
476
-     */
477
-    public function _system_status()
478
-    {
479
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
480
-        $this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481
-        $this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482
-            array(
483
-                'action' => 'download_system_status',
484
-            ),
485
-            EE_MAINTENANCE_ADMIN_URL
486
-        );
487
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
488
-            $this->_template_args, true);
489
-        $this->display_admin_page_with_sidebar();
490
-    }
491
-
492
-    /**
493
-     * Downloads an HTML file of the system status that can be easily stored or emailed
494
-     */
495
-    public function _download_system_status()
496
-    {
497
-        $status_info = EEM_System_Status::instance()->get_system_stati();
498
-        header( 'Content-Disposition: attachment' );
499
-        header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
500
-        echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
-        echo "<h1>System Information for " . site_url() . "</h1>";
502
-        echo EEH_Template::layout_array_as_table( $status_info );
503
-        die;
504
-    }
505
-
506
-
507
-
508
-    public function _send_migration_crash_report()
509
-    {
510
-        $from = $this->_req_data['from'];
511
-        $from_name = $this->_req_data['from_name'];
512
-        $body = $this->_req_data['body'];
513
-        try {
514
-            $success = wp_mail(EE_SUPPORT_EMAIL,
515
-                'Migration Crash Report',
516
-                $body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
517
-                array(
518
-                    "from:$from_name<$from>",
519
-                    //					'content-type:text/html charset=UTF-8'
520
-                ));
521
-        } catch (Exception $e) {
522
-            $success = false;
523
-        }
524
-        $this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"),
525
-            esc_html__("sent", "event_espresso"),
526
-            array('success' => $success, 'action' => 'confirm_migration_crash_report_sent'));
527
-    }
528
-
529
-
530
-
531
-    public function _confirm_migration_crash_report_sent()
532
-    {
533
-        try {
534
-            $most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
535
-        } catch (EE_Error $e) {
536
-            EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
537
-            //now, just so we can display the page correctly, make a error migration script stage object
538
-            //and also put the error on it. It only persists for the duration of this request
539
-            $most_recent_migration = new EE_DMS_Unknown_1_0_0();
540
-            $most_recent_migration->add_error($e->getMessage());
541
-        }
542
-        $success = $this->_req_data['success'] == '1' ? true : false;
543
-        $this->_template_args['success'] = $success;
544
-        $this->_template_args['most_recent_migration'] = $most_recent_migration;
545
-        $this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
546
-            EE_MAINTENANCE_ADMIN_URL);
547
-        $this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
548
-            EE_MAINTENANCE_ADMIN_URL);
549
-        $this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550
-            EE_MAINTENANCE_ADMIN_URL);
551
-        $this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
552
-        $this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553
-            $this->_template_args, true);
554
-        $this->display_admin_page_with_sidebar();
555
-    }
556
-
557
-
558
-
559
-    /**
560
-     * Resets the entire EE4 database.
561
-     * Currently basically only sets up ee4 database for a fresh install- doesn't
562
-     * actually clean out the old wp options, or cpts (although does erase old ee table data)
563
-     *
564
-     * @param boolean $nuke_old_ee4_data controls whether or not we
565
-     *                                   destroy the old ee4 data, or just try initializing ee4 default data
566
-     */
567
-    public function _reset_db($nuke_old_ee4_data = true)
568
-    {
569
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
570
-        if ($nuke_old_ee4_data) {
571
-            EEH_Activation::delete_all_espresso_cpt_data();
572
-            EEH_Activation::delete_all_espresso_tables_and_data(false);
573
-            EEH_Activation::remove_cron_tasks();
574
-        }
575
-        //make sure when we reset the registry's config that it
576
-        //switches to using the new singleton
577
-        EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
578
-        EE_System::instance()->initialize_db_if_no_migrations_required(true);
579
-        EE_System::instance()->redirect_to_about_ee();
580
-    }
581
-
582
-
583
-
584
-    /**
585
-     * Deletes ALL EE tables, Records, and Options from the database.
586
-     */
587
-    public function _delete_db()
588
-    {
589
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
590
-        EEH_Activation::delete_all_espresso_cpt_data();
591
-        EEH_Activation::delete_all_espresso_tables_and_data();
592
-        EEH_Activation::remove_cron_tasks();
593
-        EEH_Activation::deactivate_event_espresso();
594
-        wp_safe_redirect(admin_url('plugins.php'));
595
-        exit;
596
-    }
597
-
598
-
599
-
600
-    /**
601
-     * sets up EE4 to rerun the migrations from ee3 to ee4
602
-     */
603
-    public function _rerun_migration_from_ee3()
604
-    {
605
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
606
-        EEH_Activation::delete_all_espresso_cpt_data();
607
-        EEH_Activation::delete_all_espresso_tables_and_data(false);
608
-        //set the db state to something that will require migrations
609
-        update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
610
-        EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
611
-        $this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso'));
612
-    }
613
-
614
-
615
-
616
-    //none of the below group are currently used for Gateway Settings
617
-    protected function _add_screen_options()
618
-    {
619
-    }
620
-
621
-
622
-
623
-    protected function _add_feature_pointers()
624
-    {
625
-    }
626
-
32
+	/**
33
+	 * @var EE_Datetime_Offset_Fix_Form
34
+	 */
35
+	protected $datetime_fix_offset_form;
36
+
37
+
38
+
39
+	protected function _init_page_props()
40
+	{
41
+		$this->page_slug = EE_MAINTENANCE_PG_SLUG;
42
+		$this->page_label = EE_MAINTENANCE_LABEL;
43
+		$this->_admin_base_url = EE_MAINTENANCE_ADMIN_URL;
44
+		$this->_admin_base_path = EE_MAINTENANCE_ADMIN;
45
+	}
46
+
47
+
48
+
49
+	protected function _ajax_hooks()
50
+	{
51
+		add_action('wp_ajax_migration_step', array($this, 'migration_step'));
52
+		add_action('wp_ajax_add_error_to_migrations_ran', array($this, 'add_error_to_migrations_ran'));
53
+	}
54
+
55
+
56
+
57
+	protected function _define_page_props()
58
+	{
59
+		$this->_admin_page_title = EE_MAINTENANCE_LABEL;
60
+		$this->_labels = array(
61
+			'buttons' => array(
62
+				'reset_reservations' => esc_html__('Reset Ticket and Datetime Reserved Counts', 'event_espresso'),
63
+				'reset_capabilities' => esc_html__('Reset Event Espresso Capabilities', 'event_espresso'),
64
+			),
65
+		);
66
+	}
67
+
68
+
69
+
70
+	protected function _set_page_routes()
71
+	{
72
+		$this->_page_routes = array(
73
+			'default'                             => array(
74
+				'func'       => '_maintenance',
75
+				'capability' => 'manage_options',
76
+			),
77
+			'change_maintenance_level'            => array(
78
+				'func'       => '_change_maintenance_level',
79
+				'capability' => 'manage_options',
80
+				'noheader'   => true,
81
+			),
82
+			'system_status'                       => array(
83
+				'func'       => '_system_status',
84
+				'capability' => 'manage_options',
85
+			),
86
+			'download_system_status' => array(
87
+				'func'       => '_download_system_status',
88
+				'capability' => 'manage_options',
89
+				'noheader'   => true,
90
+			),
91
+			'send_migration_crash_report'         => array(
92
+				'func'       => '_send_migration_crash_report',
93
+				'capability' => 'manage_options',
94
+				'noheader'   => true,
95
+			),
96
+			'confirm_migration_crash_report_sent' => array(
97
+				'func'       => '_confirm_migration_crash_report_sent',
98
+				'capability' => 'manage_options',
99
+			),
100
+			'data_reset'                          => array(
101
+				'func'       => '_data_reset_and_delete',
102
+				'capability' => 'manage_options',
103
+			),
104
+			'reset_db'                            => array(
105
+				'func'       => '_reset_db',
106
+				'capability' => 'manage_options',
107
+				'noheader'   => true,
108
+				'args'       => array('nuke_old_ee4_data' => true),
109
+			),
110
+			'start_with_fresh_ee4_db'             => array(
111
+				'func'       => '_reset_db',
112
+				'capability' => 'manage_options',
113
+				'noheader'   => true,
114
+				'args'       => array('nuke_old_ee4_data' => false),
115
+			),
116
+			'delete_db'                           => array(
117
+				'func'       => '_delete_db',
118
+				'capability' => 'manage_options',
119
+				'noheader'   => true,
120
+			),
121
+			'rerun_migration_from_ee3'            => array(
122
+				'func'       => '_rerun_migration_from_ee3',
123
+				'capability' => 'manage_options',
124
+				'noheader'   => true,
125
+			),
126
+			'reset_reservations'                  => array(
127
+				'func'       => '_reset_reservations',
128
+				'capability' => 'manage_options',
129
+				'noheader'   => true,
130
+			),
131
+			'reset_capabilities'                  => array(
132
+				'func'       => '_reset_capabilities',
133
+				'capability' => 'manage_options',
134
+				'noheader'   => true,
135
+			),
136
+			'reattempt_migration'                 => array(
137
+				'func'       => '_reattempt_migration',
138
+				'capability' => 'manage_options',
139
+				'noheader'   => true,
140
+			),
141
+			'datetime_tools' => array(
142
+				'func' => '_datetime_tools',
143
+				'capability' => 'manage_options'
144
+			),
145
+			'run_datetime_offset_fix' => array(
146
+				'func' => '_apply_datetime_offset',
147
+				'noheader' => true,
148
+				'headers_sent_route' => 'datetime_tools',
149
+				'capability' => 'manage_options'
150
+			)
151
+		);
152
+	}
153
+
154
+
155
+
156
+	protected function _set_page_config()
157
+	{
158
+		$this->_page_config = array(
159
+			'default'       => array(
160
+				'nav'           => array(
161
+					'label' => esc_html__('Maintenance', 'event_espresso'),
162
+					'order' => 10,
163
+				),
164
+				'require_nonce' => false,
165
+			),
166
+			'data_reset'    => array(
167
+				'nav'           => array(
168
+					'label' => esc_html__('Reset/Delete Data', 'event_espresso'),
169
+					'order' => 20,
170
+				),
171
+				'require_nonce' => false,
172
+			),
173
+			'datetime_tools' => array(
174
+				'nav' => array(
175
+					'label' => esc_html__('Datetime Utilities', 'event_espresso'),
176
+					'order' => 25
177
+				),
178
+				'require_nonce' => false,
179
+			),
180
+			'system_status' => array(
181
+				'nav'           => array(
182
+					'label' => esc_html__("System Information", "event_espresso"),
183
+					'order' => 30,
184
+				),
185
+				'require_nonce' => false,
186
+			),
187
+		);
188
+	}
189
+
190
+
191
+
192
+	/**
193
+	 * default maintenance page. If we're in maintenance mode level 2, then we need to show
194
+	 * the migration scripts and all that UI.
195
+	 */
196
+	public function _maintenance()
197
+	{
198
+		//it all depends if we're in maintenance model level 1 (frontend-only) or
199
+		//level 2 (everything except maintenance page)
200
+		try {
201
+			//get the current maintenance level and check if
202
+			//we are removed
203
+			$mm = EE_Maintenance_Mode::instance()->level();
204
+			$placed_in_mm = EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
205
+			if ($mm == EE_Maintenance_Mode::level_2_complete_maintenance && ! $placed_in_mm) {
206
+				//we just took the site out of maintenance mode, so notify the user.
207
+				//unfortunately this message appears to be echoed on the NEXT page load...
208
+				//oh well, we should really be checking for this on addon deactivation anyways
209
+				EE_Error::add_attention(__('Site taken out of maintenance mode because no data migration scripts are required',
210
+					'event_espresso'));
211
+				$this->_process_notices(array('page' => 'espresso_maintenance_settings'), false);
212
+			}
213
+			//in case an exception is thrown while trying to handle migrations
214
+			switch (EE_Maintenance_Mode::instance()->level()) {
215
+				case EE_Maintenance_Mode::level_0_not_in_maintenance:
216
+				case EE_Maintenance_Mode::level_1_frontend_only_maintenance:
217
+					$show_maintenance_switch = true;
218
+					$show_backup_db_text = false;
219
+					$show_migration_progress = false;
220
+					$script_names = array();
221
+					$addons_should_be_upgraded_first = false;
222
+					break;
223
+				case EE_Maintenance_Mode::level_2_complete_maintenance:
224
+					$show_maintenance_switch = false;
225
+					$show_migration_progress = true;
226
+					if (isset($this->_req_data['continue_migration'])) {
227
+						$show_backup_db_text = false;
228
+					} else {
229
+						$show_backup_db_text = true;
230
+					}
231
+					$scripts_needing_to_run = EE_Data_Migration_Manager::instance()
232
+																	   ->check_for_applicable_data_migration_scripts();
233
+					$addons_should_be_upgraded_first = EE_Data_Migration_Manager::instance()->addons_need_updating();
234
+					$script_names = array();
235
+					$current_script = null;
236
+					foreach ($scripts_needing_to_run as $script) {
237
+						if ($script instanceof EE_Data_Migration_Script_Base) {
238
+							if ( ! $current_script) {
239
+								$current_script = $script;
240
+								$current_script->migration_page_hooks();
241
+							}
242
+							$script_names[] = $script->pretty_name();
243
+						}
244
+					}
245
+					break;
246
+			}
247
+			$most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
248
+			$exception_thrown = false;
249
+		} catch (EE_Error $e) {
250
+			EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
251
+			//now, just so we can display the page correctly, make a error migration script stage object
252
+			//and also put the error on it. It only persists for the duration of this request
253
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
254
+			$most_recent_migration->add_error($e->getMessage());
255
+			$exception_thrown = true;
256
+		}
257
+		$current_db_state = EE_Data_Migration_Manager::instance()->ensure_current_database_state_is_set();
258
+		$current_db_state = str_replace('.decaf', '', $current_db_state);
259
+		if ($exception_thrown
260
+			|| ($most_recent_migration
261
+				&& $most_recent_migration instanceof EE_Data_Migration_Script_Base
262
+				&& $most_recent_migration->is_broken()
263
+			)
264
+		) {
265
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_was_borked_page.template.php';
266
+			$this->_template_args['support_url'] = 'http://eventespresso.com/support/forums/';
267
+			$this->_template_args['next_url'] = EEH_URL::add_query_args_and_nonce(array('action'  => 'confirm_migration_crash_report_sent',
268
+																						'success' => '0',
269
+			), EE_MAINTENANCE_ADMIN_URL);
270
+		} elseif ($addons_should_be_upgraded_first) {
271
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_upgrade_addons_before_migrating.template.php';
272
+		} else {
273
+			if ($most_recent_migration
274
+				&& $most_recent_migration instanceof EE_Data_Migration_Script_Base
275
+				&& $most_recent_migration->can_continue()
276
+			) {
277
+				$show_backup_db_text = false;
278
+				$show_continue_current_migration_script = true;
279
+				$show_most_recent_migration = true;
280
+			} elseif (isset($this->_req_data['continue_migration'])) {
281
+				$show_most_recent_migration = true;
282
+				$show_continue_current_migration_script = false;
283
+			} else {
284
+				$show_most_recent_migration = false;
285
+				$show_continue_current_migration_script = false;
286
+			}
287
+			if (isset($current_script)) {
288
+				$migrates_to = $current_script->migrates_to_version();
289
+				$plugin_slug = $migrates_to['slug'];
290
+				$new_version = $migrates_to['version'];
291
+				$this->_template_args = array_merge($this->_template_args, array(
292
+					'current_db_state' => sprintf(__("EE%s (%s)", "event_espresso"),
293
+						isset($current_db_state[$plugin_slug]) ? $current_db_state[$plugin_slug] : 3, $plugin_slug),
294
+					'next_db_state'    => isset($current_script) ? sprintf(__("EE%s (%s)", 'event_espresso'),
295
+						$new_version, $plugin_slug) : null,
296
+				));
297
+			} else {
298
+				$this->_template_args['current_db_state'] = null;
299
+				$this->_template_args['next_db_state'] = null;
300
+			}
301
+			$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_migration_page.template.php';
302
+			$this->_template_args = array_merge(
303
+				$this->_template_args,
304
+				array(
305
+					'show_most_recent_migration'             => $show_most_recent_migration,
306
+					//flag for showing the most recent migration's status and/or errors
307
+					'show_migration_progress'                => $show_migration_progress,
308
+					//flag for showing the option to run migrations and see their progress
309
+					'show_backup_db_text'                    => $show_backup_db_text,
310
+					//flag for showing text telling the user to backup their DB
311
+					'show_maintenance_switch'                => $show_maintenance_switch,
312
+					//flag for showing the option to change maintenance mode between levels 0 and 1
313
+					'script_names'                           => $script_names,
314
+					//array of names of scripts that have run
315
+					'show_continue_current_migration_script' => $show_continue_current_migration_script,
316
+					//flag to change wording to indicating that we're only CONTINUING a migration script (somehow it got interrupted0
317
+					'reset_db_page_link'                     => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
318
+						EE_MAINTENANCE_ADMIN_URL),
319
+					'data_reset_page'                        => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
320
+						EE_MAINTENANCE_ADMIN_URL),
321
+					'update_migration_script_page_link'      => EE_Admin_Page::add_query_args_and_nonce(array('action' => 'change_maintenance_level'),
322
+						EE_MAINTENANCE_ADMIN_URL),
323
+					'ultimate_db_state'                      => sprintf(__("EE%s", 'event_espresso'),
324
+						espresso_version()),
325
+				)
326
+			);
327
+			//make sure we have the form fields helper available. It usually is, but sometimes it isn't
328
+		}
329
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;//the actual most recently ran migration
330
+		//now render the migration options part, and put it in a variable
331
+		$migration_options_template_file = apply_filters(
332
+			'FHEE__ee_migration_page__migration_options_template',
333
+			EE_MAINTENANCE_TEMPLATE_PATH . 'migration_options_from_ee4.template.php'
334
+		);
335
+		$migration_options_html = EEH_Template::display_template($migration_options_template_file, $this->_template_args,true);
336
+		$this->_template_args['migration_options_html'] = $migration_options_html;
337
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
338
+			$this->_template_args, true);
339
+		$this->display_admin_page_with_sidebar();
340
+	}
341
+
342
+
343
+
344
+	/**
345
+	 * returns JSON and executes another step of the currently-executing data migration (called via ajax)
346
+	 */
347
+	public function migration_step()
348
+	{
349
+		$this->_template_args['data'] = EE_Data_Migration_Manager::instance()->response_to_migration_ajax_request();
350
+		$this->_return_json();
351
+	}
352
+
353
+
354
+
355
+	/**
356
+	 * Can be used by js when it notices a response with HTML in it in order
357
+	 * to log the malformed response
358
+	 */
359
+	public function add_error_to_migrations_ran()
360
+	{
361
+		EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($this->_req_data['message']);
362
+		$this->_template_args['data'] = array('ok' => true);
363
+		$this->_return_json();
364
+	}
365
+
366
+
367
+
368
+	/**
369
+	 * changes the maintenance level, provided there are still no migration scripts that should run
370
+	 */
371
+	public function _change_maintenance_level()
372
+	{
373
+		$new_level = absint($this->_req_data['maintenance_mode_level']);
374
+		if ( ! EE_Data_Migration_Manager::instance()->check_for_applicable_data_migration_scripts()) {
375
+			EE_Maintenance_Mode::instance()->set_maintenance_level($new_level);
376
+			$success = true;
377
+		} else {
378
+			EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
379
+			$success = false;
380
+		}
381
+		$this->_redirect_after_action($success, 'Maintenance Mode', esc_html__("Updated", "event_espresso"));
382
+	}
383
+
384
+
385
+
386
+	/**
387
+	 * a tab with options for resetting and/or deleting EE data
388
+	 *
389
+	 * @throws \EE_Error
390
+	 * @throws \DomainException
391
+	 */
392
+	public function _data_reset_and_delete()
393
+	{
394
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_data_reset_and_delete.template.php';
395
+		$this->_template_args['reset_reservations_button'] = $this->get_action_link_or_button(
396
+			'reset_reservations',
397
+			'reset_reservations',
398
+			array(),
399
+			'button button-primary ee-confirm',
400
+			'',
401
+			false
402
+		);
403
+		$this->_template_args['reset_capabilities_button'] = $this->get_action_link_or_button(
404
+			'reset_capabilities',
405
+			'reset_capabilities',
406
+			array(),
407
+			'button button-primary ee-confirm',
408
+			'',
409
+			false
410
+		);
411
+		$this->_template_args['delete_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
412
+			array('action' => 'delete_db'),
413
+			EE_MAINTENANCE_ADMIN_URL
414
+		);
415
+		$this->_template_args['reset_db_url'] = EE_Admin_Page::add_query_args_and_nonce(
416
+			array('action' => 'reset_db'),
417
+			EE_MAINTENANCE_ADMIN_URL
418
+		);
419
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template(
420
+			$this->_template_path,
421
+			$this->_template_args,
422
+			true
423
+		);
424
+		$this->display_admin_page_with_sidebar();
425
+	}
426
+
427
+
428
+
429
+	protected function _reset_reservations()
430
+	{
431
+		if(\EED_Ticket_Sales_Monitor::reset_reservation_counts()) {
432
+			EE_Error::add_success(
433
+				__(
434
+					'Ticket and datetime reserved counts have been successfully reset.',
435
+					'event_espresso'
436
+				)
437
+			);
438
+		} else {
439
+			EE_Error::add_success(
440
+				__(
441
+					'Ticket and datetime reserved counts were correct and did not need resetting.',
442
+					'event_espresso'
443
+				)
444
+			);
445
+		}
446
+		$this->_redirect_after_action(true, '', '', array('action' => 'data_reset'), true);
447
+	}
448
+
449
+
450
+
451
+	protected function _reset_capabilities()
452
+	{
453
+		EE_Registry::instance()->CAP->init_caps(true);
454
+		EE_Error::add_success(__('Default Event Espresso capabilities have been restored for all current roles.',
455
+			'event_espresso'));
456
+		$this->_redirect_after_action(false, '', '', array('action' => 'data_reset'), true);
457
+	}
458
+
459
+
460
+
461
+	/**
462
+	 * resets the DMSs so we can attempt to continue migrating after a fatal error
463
+	 * (only a good idea when someone has somehow tried ot fix whatever caused
464
+	 * the fatal error in teh first place)
465
+	 */
466
+	protected function _reattempt_migration()
467
+	{
468
+		EE_Data_Migration_Manager::instance()->reattempt();
469
+		$this->_redirect_after_action(false, '', '', array('action' => 'default'), true);
470
+	}
471
+
472
+
473
+
474
+	/**
475
+	 * shows the big ol' System Information page
476
+	 */
477
+	public function _system_status()
478
+	{
479
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_system_stati_page.template.php';
480
+		$this->_template_args['system_stati'] = EEM_System_Status::instance()->get_system_stati();
481
+		$this->_template_args['download_system_status_url'] = EE_Admin_Page::add_query_args_and_nonce(
482
+			array(
483
+				'action' => 'download_system_status',
484
+			),
485
+			EE_MAINTENANCE_ADMIN_URL
486
+		);
487
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
488
+			$this->_template_args, true);
489
+		$this->display_admin_page_with_sidebar();
490
+	}
491
+
492
+	/**
493
+	 * Downloads an HTML file of the system status that can be easily stored or emailed
494
+	 */
495
+	public function _download_system_status()
496
+	{
497
+		$status_info = EEM_System_Status::instance()->get_system_stati();
498
+		header( 'Content-Disposition: attachment' );
499
+		header( "Content-Disposition: attachment; filename=system_status_" . sanitize_key( site_url() ) . ".html" );
500
+		echo "<style>table{border:1px solid darkgrey;}td{vertical-align:top}</style>";
501
+		echo "<h1>System Information for " . site_url() . "</h1>";
502
+		echo EEH_Template::layout_array_as_table( $status_info );
503
+		die;
504
+	}
505
+
506
+
507
+
508
+	public function _send_migration_crash_report()
509
+	{
510
+		$from = $this->_req_data['from'];
511
+		$from_name = $this->_req_data['from_name'];
512
+		$body = $this->_req_data['body'];
513
+		try {
514
+			$success = wp_mail(EE_SUPPORT_EMAIL,
515
+				'Migration Crash Report',
516
+				$body . "/r/n<br>" . print_r(EEM_System_Status::instance()->get_system_stati(), true),
517
+				array(
518
+					"from:$from_name<$from>",
519
+					//					'content-type:text/html charset=UTF-8'
520
+				));
521
+		} catch (Exception $e) {
522
+			$success = false;
523
+		}
524
+		$this->_redirect_after_action($success, esc_html__("Migration Crash Report", "event_espresso"),
525
+			esc_html__("sent", "event_espresso"),
526
+			array('success' => $success, 'action' => 'confirm_migration_crash_report_sent'));
527
+	}
528
+
529
+
530
+
531
+	public function _confirm_migration_crash_report_sent()
532
+	{
533
+		try {
534
+			$most_recent_migration = EE_Data_Migration_Manager::instance()->get_last_ran_script(true);
535
+		} catch (EE_Error $e) {
536
+			EE_Data_Migration_Manager::instance()->add_error_to_migrations_ran($e->getMessage());
537
+			//now, just so we can display the page correctly, make a error migration script stage object
538
+			//and also put the error on it. It only persists for the duration of this request
539
+			$most_recent_migration = new EE_DMS_Unknown_1_0_0();
540
+			$most_recent_migration->add_error($e->getMessage());
541
+		}
542
+		$success = $this->_req_data['success'] == '1' ? true : false;
543
+		$this->_template_args['success'] = $success;
544
+		$this->_template_args['most_recent_migration'] = $most_recent_migration;
545
+		$this->_template_args['reset_db_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reset_db'),
546
+			EE_MAINTENANCE_ADMIN_URL);
547
+		$this->_template_args['reset_db_page_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'data_reset'),
548
+			EE_MAINTENANCE_ADMIN_URL);
549
+		$this->_template_args['reattempt_action_url'] = EE_Admin_Page::add_query_args_and_nonce(array('action' => 'reattempt_migration'),
550
+			EE_MAINTENANCE_ADMIN_URL);
551
+		$this->_template_path = EE_MAINTENANCE_TEMPLATE_PATH . 'ee_confirm_migration_crash_report_sent.template.php';
552
+		$this->_template_args['admin_page_content'] = EEH_Template::display_template($this->_template_path,
553
+			$this->_template_args, true);
554
+		$this->display_admin_page_with_sidebar();
555
+	}
556
+
557
+
558
+
559
+	/**
560
+	 * Resets the entire EE4 database.
561
+	 * Currently basically only sets up ee4 database for a fresh install- doesn't
562
+	 * actually clean out the old wp options, or cpts (although does erase old ee table data)
563
+	 *
564
+	 * @param boolean $nuke_old_ee4_data controls whether or not we
565
+	 *                                   destroy the old ee4 data, or just try initializing ee4 default data
566
+	 */
567
+	public function _reset_db($nuke_old_ee4_data = true)
568
+	{
569
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
570
+		if ($nuke_old_ee4_data) {
571
+			EEH_Activation::delete_all_espresso_cpt_data();
572
+			EEH_Activation::delete_all_espresso_tables_and_data(false);
573
+			EEH_Activation::remove_cron_tasks();
574
+		}
575
+		//make sure when we reset the registry's config that it
576
+		//switches to using the new singleton
577
+		EE_Registry::instance()->CFG = EE_Registry::instance()->CFG->reset(true);
578
+		EE_System::instance()->initialize_db_if_no_migrations_required(true);
579
+		EE_System::instance()->redirect_to_about_ee();
580
+	}
581
+
582
+
583
+
584
+	/**
585
+	 * Deletes ALL EE tables, Records, and Options from the database.
586
+	 */
587
+	public function _delete_db()
588
+	{
589
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
590
+		EEH_Activation::delete_all_espresso_cpt_data();
591
+		EEH_Activation::delete_all_espresso_tables_and_data();
592
+		EEH_Activation::remove_cron_tasks();
593
+		EEH_Activation::deactivate_event_espresso();
594
+		wp_safe_redirect(admin_url('plugins.php'));
595
+		exit;
596
+	}
597
+
598
+
599
+
600
+	/**
601
+	 * sets up EE4 to rerun the migrations from ee3 to ee4
602
+	 */
603
+	public function _rerun_migration_from_ee3()
604
+	{
605
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_0_not_in_maintenance);
606
+		EEH_Activation::delete_all_espresso_cpt_data();
607
+		EEH_Activation::delete_all_espresso_tables_and_data(false);
608
+		//set the db state to something that will require migrations
609
+		update_option(EE_Data_Migration_Manager::current_database_state, '3.1.36.0');
610
+		EE_Maintenance_Mode::instance()->set_maintenance_level(EE_Maintenance_Mode::level_2_complete_maintenance);
611
+		$this->_redirect_after_action(true, esc_html__("Database", 'event_espresso'), esc_html__("reset", 'event_espresso'));
612
+	}
613
+
614
+
615
+
616
+	//none of the below group are currently used for Gateway Settings
617
+	protected function _add_screen_options()
618
+	{
619
+	}
620
+
621
+
622
+
623
+	protected function _add_feature_pointers()
624
+	{
625
+	}
626
+
627 627
 
628 628
 
629
-    public function admin_init()
630
-    {
631
-    }
632
-
633
-
634
-
635
-    public function admin_notices()
636
-    {
637
-    }
638
-
629
+	public function admin_init()
630
+	{
631
+	}
632
+
633
+
634
+
635
+	public function admin_notices()
636
+	{
637
+	}
638
+
639 639
 
640 640
 
641
-    public function admin_footer_scripts()
642
-    {
643
-    }
641
+	public function admin_footer_scripts()
642
+	{
643
+	}
644 644
 
645 645
 
646 646
 
647
-    public function load_scripts_styles()
648
-    {
649
-        wp_enqueue_script('ee_admin_js');
647
+	public function load_scripts_styles()
648
+	{
649
+		wp_enqueue_script('ee_admin_js');
650 650
 //		wp_enqueue_media();
651 651
 //		wp_enqueue_script('media-upload');
652
-        wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
653
-            EVENT_ESPRESSO_VERSION, true);
654
-        wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
655
-            EVENT_ESPRESSO_VERSION);
656
-        wp_enqueue_style('espresso_maintenance');
657
-        //localize script stuff
658
-        wp_localize_script('ee-maintenance', 'ee_maintenance', array(
659
-            'migrating'                        => esc_html__("Updating Database...", "event_espresso"),
660
-            'next'                             => esc_html__("Next", "event_espresso"),
661
-            'fatal_error'                      => esc_html__("A Fatal Error Has Occurred", "event_espresso"),
662
-            'click_next_when_ready'            => esc_html__(
663
-                "The current Database Update has ended. Click 'next' when ready to proceed",
664
-                "event_espresso"
665
-            ),
666
-            'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
667
-            'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
668
-            'status_completed'                 => EE_Data_Migration_Manager::status_completed,
669
-            'confirm'                          => esc_html__(
670
-                'Are you sure you want to do this? It CANNOT be undone!',
671
-                'event_espresso'
672
-            ),
673
-            'confirm_skip_migration' => esc_html__(
674
-                'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
675
-                'event_espresso'
676
-            )
677
-        ));
678
-    }
679
-
680
-
681
-
682
-    public function load_scripts_styles_default()
683
-    {
684
-        //styles
652
+		wp_enqueue_script('ee-maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.js', array('jquery'),
653
+			EVENT_ESPRESSO_VERSION, true);
654
+		wp_register_style('espresso_maintenance', EE_MAINTENANCE_ASSETS_URL . 'ee-maintenance.css', array(),
655
+			EVENT_ESPRESSO_VERSION);
656
+		wp_enqueue_style('espresso_maintenance');
657
+		//localize script stuff
658
+		wp_localize_script('ee-maintenance', 'ee_maintenance', array(
659
+			'migrating'                        => esc_html__("Updating Database...", "event_espresso"),
660
+			'next'                             => esc_html__("Next", "event_espresso"),
661
+			'fatal_error'                      => esc_html__("A Fatal Error Has Occurred", "event_espresso"),
662
+			'click_next_when_ready'            => esc_html__(
663
+				"The current Database Update has ended. Click 'next' when ready to proceed",
664
+				"event_espresso"
665
+			),
666
+			'status_no_more_migration_scripts' => EE_Data_Migration_Manager::status_no_more_migration_scripts,
667
+			'status_fatal_error'               => EE_Data_Migration_Manager::status_fatal_error,
668
+			'status_completed'                 => EE_Data_Migration_Manager::status_completed,
669
+			'confirm'                          => esc_html__(
670
+				'Are you sure you want to do this? It CANNOT be undone!',
671
+				'event_espresso'
672
+			),
673
+			'confirm_skip_migration' => esc_html__(
674
+				'You have chosen to NOT migrate your existing data. Are you sure you want to continue?',
675
+				'event_espresso'
676
+			)
677
+		));
678
+	}
679
+
680
+
681
+
682
+	public function load_scripts_styles_default()
683
+	{
684
+		//styles
685 685
 //		wp_enqueue_style('ee-text-links');
686 686
 //		//scripts
687 687
 //		wp_enqueue_script('ee-text-links');
688
-    }
689
-
690
-
691
-    /**
692
-     * Enqueue scripts and styles for the datetime tools page.
693
-     */
694
-    public function load_scripts_styles_datetime_tools()
695
-    {
696
-        EE_Datepicker_Input::enqueue_styles_and_scripts();
697
-    }
698
-
699
-
700
-    protected function _datetime_tools()
701
-    {
702
-        $form_action = EE_Admin_Page::add_query_args_and_nonce(
703
-            array(
704
-                'action' => 'run_datetime_offset_fix',
705
-                'return_action' => $this->_req_action
706
-            ),
707
-            EE_MAINTENANCE_ADMIN_URL
708
-        );
709
-        $form = $this->_get_datetime_offset_fix_form();
710
-        $this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso');
711
-        $this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
712
-                                                      . $form->get_html_and_js()
713
-                                                      . $form->form_close();
714
-        $this->display_admin_page_with_no_sidebar();
715
-    }
716
-
717
-
718
-
719
-    protected function _get_datetime_offset_fix_form()
720
-    {
721
-        if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
-            $this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
723
-                array(
724
-                    'name' => 'datetime_offset_fix_option',
725
-                    'layout_strategy' => new EE_Admin_Two_Column_Layout(),
726
-                    'subsections' => array(
727
-                        'title' => new EE_Form_Section_HTML(
728
-                            EEH_HTML::h2(
729
-                                esc_html__('Datetime Offset Tool', 'event_espresso')
730
-                            )
731
-                        ),
732
-                        'explanation' => new EE_Form_Section_HTML(
733
-                            EEH_HTML::p(
734
-                                esc_html__(
735
-                                    'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
736
-                                    'event_espresso'
737
-                                )
738
-                            )
739
-                            . EEH_HTML::p(
740
-                                esc_html__(
741
-                                    'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
742
-                                    'event_espresso'
743
-                                )
744
-                            )
745
-                        ),
746
-                        'offset_input' => new EE_Float_Input(
747
-                            array(
748
-                                'html_name' => 'offset_for_datetimes',
749
-                                'html_label_text' => esc_html__(
750
-                                    'Offset to apply (in hours):',
751
-                                    'event_espresso'
752
-                                ),
753
-                                'min_value' => '-12',
754
-                                'max_value' => '14',
755
-                                'step_value' => '.25',
756
-                                'default' => DatetimeOffsetFix::getOffset()
757
-                            )
758
-                        ),
759
-                        'date_range_explanation' => new EE_Form_Section_HTML(
760
-                            EEH_HTML::p(
761
-                                esc_html__(
762
-                                    'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
763
-                                    'event_espresso'
764
-                                )
765
-                            )
766
-                            . EEH_HTML::p(
767
-                                EEH_HTML::strong(
768
-                                    sprintf(
769
-                                        esc_html__(
770
-                                            'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
771
-                                            'event_espresso'
772
-                                        ),
773
-                                        '<a href="https://www.timeanddate.com/worldclock/converter.html">',
774
-                                        '</a>'
775
-                                    )
776
-                                )
777
-                            )
778
-                        ),
779
-                        'date_range_start_date' => new EE_Datepicker_Input(
780
-                            array(
781
-                                'html_name' => 'offset_date_start_range',
782
-                                'html_label_text' => esc_html__(
783
-                                    'Start Date for dates the offset applied to:',
784
-                                    'event_espresso'
785
-                                )
786
-                            )
787
-                        ),
788
-                        'date_range_end_date' => new EE_Datepicker_Input(
789
-                            array(
790
-                                'html_name' => 'offset_date_end_range',
791
-                                'html_label_text' => esc_html(
792
-                                    'End Date for dates the offset is applied to:',
793
-                                    'event_espresso'
794
-                                )
795
-                            )
796
-                        ),
797
-                        'submit' => new EE_Submit_Input(
798
-                            array(
799
-                                'html_label_text' => '',
800
-                                'default' => esc_html__('Apply Offset', 'event_espresso')
801
-                            )
802
-                        ),
803
-                    )
804
-                )
805
-            );
806
-        }
807
-        return $this->datetime_fix_offset_form;
808
-    }
809
-
810
-
811
-    /**
812
-     * Callback for the run_datetime_offset_fix route.
813
-     * @throws EE_Error
814
-     */
815
-    protected function _apply_datetime_offset()
816
-    {
817
-        if ($_SERVER['REQUEST_METHOD'] === 'POST') {
818
-            $form = $this->_get_datetime_offset_fix_form();
819
-            $form->receive_form_submission($this->_req_data);
820
-            if ($form->is_valid()) {
821
-                //save offset data so batch processor can get it.
822
-                DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
823
-                $utc_timezone = new DateTimeZone('UTC');
824
-                $date_range_start_date = DateTime::createFromFormat(
825
-                    'm/d/Y H:i:s',
826
-                    $form->get_input_value('date_range_start_date') . ' 00:00:00',
827
-                    $utc_timezone
828
-                );
829
-                $date_range_end_date = DateTime::createFromFormat(
830
-                        'm/d/Y H:i:s',
831
-                        $form->get_input_value('date_range_end_date') . ' 23:59:59',
832
-                        $utc_timezone
833
-                );
834
-                if ($date_range_start_date instanceof DateTime) {
835
-                    DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
836
-                }
837
-                if ($date_range_end_date instanceof DateTime) {
838
-                    DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
839
-                }
840
-                //redirect to batch tool
841
-                wp_redirect(
842
-                    EE_Admin_Page::add_query_args_and_nonce(
843
-                        array(
844
-                            'page' => 'espresso_batch',
845
-                            'batch' => 'job',
846
-                            'label' => esc_html__('Applying Offset', 'event_espresso'),
847
-                            'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
848
-                            'return_url' => urlencode(
849
-                                add_query_arg(
850
-                                    array(
851
-                                        'action' => 'datetime_tools',
852
-                                    ),
853
-                                    EEH_URL::current_url_without_query_paramaters(
854
-                                        array(
855
-                                            'return_action',
856
-                                            'run_datetime_offset_fix_nonce',
857
-                                            'return',
858
-                                            'datetime_tools_nonce'
859
-                                        )
860
-                                    )
861
-                                )
862
-                            )
863
-                        ),
864
-                        admin_url()
865
-                    )
866
-                );
867
-                exit;
868
-            }
869
-        }
870
-    }
688
+	}
689
+
690
+
691
+	/**
692
+	 * Enqueue scripts and styles for the datetime tools page.
693
+	 */
694
+	public function load_scripts_styles_datetime_tools()
695
+	{
696
+		EE_Datepicker_Input::enqueue_styles_and_scripts();
697
+	}
698
+
699
+
700
+	protected function _datetime_tools()
701
+	{
702
+		$form_action = EE_Admin_Page::add_query_args_and_nonce(
703
+			array(
704
+				'action' => 'run_datetime_offset_fix',
705
+				'return_action' => $this->_req_action
706
+			),
707
+			EE_MAINTENANCE_ADMIN_URL
708
+		);
709
+		$form = $this->_get_datetime_offset_fix_form();
710
+		$this->_admin_page_title = esc_html__('Datetime Utilities', 'event_espresso');
711
+		$this->_template_args['admin_page_content'] = $form->form_open($form_action, 'post')
712
+													  . $form->get_html_and_js()
713
+													  . $form->form_close();
714
+		$this->display_admin_page_with_no_sidebar();
715
+	}
716
+
717
+
718
+
719
+	protected function _get_datetime_offset_fix_form()
720
+	{
721
+		if (! $this->datetime_fix_offset_form instanceof EE_Form_Section_Proper) {
722
+			$this->datetime_fix_offset_form =  new EE_Form_Section_Proper(
723
+				array(
724
+					'name' => 'datetime_offset_fix_option',
725
+					'layout_strategy' => new EE_Admin_Two_Column_Layout(),
726
+					'subsections' => array(
727
+						'title' => new EE_Form_Section_HTML(
728
+							EEH_HTML::h2(
729
+								esc_html__('Datetime Offset Tool', 'event_espresso')
730
+							)
731
+						),
732
+						'explanation' => new EE_Form_Section_HTML(
733
+							EEH_HTML::p(
734
+								esc_html__(
735
+									'Use this tool to automatically apply the provided offset to all Event Espresso records in your database that involve dates and times.',
736
+									'event_espresso'
737
+								)
738
+							)
739
+							. EEH_HTML::p(
740
+								esc_html__(
741
+									'Note: If you enter 1.25, that will result in the offset of 1 hour 15 minutes being applied.  Decimals represent the fraction of hours, not minutes.',
742
+									'event_espresso'
743
+								)
744
+							)
745
+						),
746
+						'offset_input' => new EE_Float_Input(
747
+							array(
748
+								'html_name' => 'offset_for_datetimes',
749
+								'html_label_text' => esc_html__(
750
+									'Offset to apply (in hours):',
751
+									'event_espresso'
752
+								),
753
+								'min_value' => '-12',
754
+								'max_value' => '14',
755
+								'step_value' => '.25',
756
+								'default' => DatetimeOffsetFix::getOffset()
757
+							)
758
+						),
759
+						'date_range_explanation' => new EE_Form_Section_HTML(
760
+							EEH_HTML::p(
761
+								esc_html__(
762
+									'Leave the following fields blank if you want the offset to be applied to all dates. If however, you want to just apply the offset to a specific range of dates you can restrict the offset application using these fields.',
763
+									'event_espresso'
764
+								)
765
+							)
766
+							. EEH_HTML::p(
767
+								EEH_HTML::strong(
768
+									sprintf(
769
+										esc_html__(
770
+											'Note: please enter the dates in UTC (You can use %1$sthis online tool%2$s to assist with conversions).',
771
+											'event_espresso'
772
+										),
773
+										'<a href="https://www.timeanddate.com/worldclock/converter.html">',
774
+										'</a>'
775
+									)
776
+								)
777
+							)
778
+						),
779
+						'date_range_start_date' => new EE_Datepicker_Input(
780
+							array(
781
+								'html_name' => 'offset_date_start_range',
782
+								'html_label_text' => esc_html__(
783
+									'Start Date for dates the offset applied to:',
784
+									'event_espresso'
785
+								)
786
+							)
787
+						),
788
+						'date_range_end_date' => new EE_Datepicker_Input(
789
+							array(
790
+								'html_name' => 'offset_date_end_range',
791
+								'html_label_text' => esc_html(
792
+									'End Date for dates the offset is applied to:',
793
+									'event_espresso'
794
+								)
795
+							)
796
+						),
797
+						'submit' => new EE_Submit_Input(
798
+							array(
799
+								'html_label_text' => '',
800
+								'default' => esc_html__('Apply Offset', 'event_espresso')
801
+							)
802
+						),
803
+					)
804
+				)
805
+			);
806
+		}
807
+		return $this->datetime_fix_offset_form;
808
+	}
809
+
810
+
811
+	/**
812
+	 * Callback for the run_datetime_offset_fix route.
813
+	 * @throws EE_Error
814
+	 */
815
+	protected function _apply_datetime_offset()
816
+	{
817
+		if ($_SERVER['REQUEST_METHOD'] === 'POST') {
818
+			$form = $this->_get_datetime_offset_fix_form();
819
+			$form->receive_form_submission($this->_req_data);
820
+			if ($form->is_valid()) {
821
+				//save offset data so batch processor can get it.
822
+				DatetimeOffsetFix::updateOffset($form->get_input_value('offset_input'));
823
+				$utc_timezone = new DateTimeZone('UTC');
824
+				$date_range_start_date = DateTime::createFromFormat(
825
+					'm/d/Y H:i:s',
826
+					$form->get_input_value('date_range_start_date') . ' 00:00:00',
827
+					$utc_timezone
828
+				);
829
+				$date_range_end_date = DateTime::createFromFormat(
830
+						'm/d/Y H:i:s',
831
+						$form->get_input_value('date_range_end_date') . ' 23:59:59',
832
+						$utc_timezone
833
+				);
834
+				if ($date_range_start_date instanceof DateTime) {
835
+					DatetimeOffsetFix::updateStartDateRange(DbSafeDateTime::createFromDateTime($date_range_start_date));
836
+				}
837
+				if ($date_range_end_date instanceof DateTime) {
838
+					DatetimeOffsetFix::updateEndDateRange(DbSafeDateTime::createFromDateTime($date_range_end_date));
839
+				}
840
+				//redirect to batch tool
841
+				wp_redirect(
842
+					EE_Admin_Page::add_query_args_and_nonce(
843
+						array(
844
+							'page' => 'espresso_batch',
845
+							'batch' => 'job',
846
+							'label' => esc_html__('Applying Offset', 'event_espresso'),
847
+							'job_handler' => urlencode('EventEspressoBatchRequest\JobHandlers\DatetimeOffsetFix'),
848
+							'return_url' => urlencode(
849
+								add_query_arg(
850
+									array(
851
+										'action' => 'datetime_tools',
852
+									),
853
+									EEH_URL::current_url_without_query_paramaters(
854
+										array(
855
+											'return_action',
856
+											'run_datetime_offset_fix_nonce',
857
+											'return',
858
+											'datetime_tools_nonce'
859
+										)
860
+									)
861
+								)
862
+							)
863
+						),
864
+						admin_url()
865
+					)
866
+				);
867
+				exit;
868
+			}
869
+		}
870
+	}
871 871
 } //end Maintenance_Admin_Page class
Please login to merge, or discard this patch.
core/EE_Addon.core.php 2 patches
Indentation   +814 added lines, -814 removed lines patch added patch discarded remove patch
@@ -18,786 +18,786 @@  discard block
 block discarded – undo
18 18
 {
19 19
 
20 20
 
21
-    /**
22
-     * prefix to be added onto an addon's plugin slug to make a wp option name
23
-     * which will be used to store the plugin's activation history
24
-     */
25
-    const ee_addon_version_history_option_prefix = 'ee_version_history_';
26
-
27
-    /**
28
-     * @var $_version
29
-     * @type string
30
-     */
31
-    protected $_version = '';
32
-
33
-    /**
34
-     * @var $_min_core_version
35
-     * @type string
36
-     */
37
-    protected $_min_core_version = '';
38
-
39
-    /**
40
-     * derived from plugin 'main_file_path using plugin_basename()
41
-     *
42
-     * @type string $_plugin_basename
43
-     */
44
-    protected $_plugin_basename = '';
45
-
46
-    /**
47
-     * A non-internationalized name to identify this addon for use in URLs, etc
48
-     *
49
-     * @type string $_plugin_slug
50
-     */
51
-    protected $_plugin_slug = '';
52
-
53
-    /**
54
-     * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
55
-     *
56
-     * @type string _addon_name
57
-     */
58
-    protected $_addon_name = '';
59
-
60
-    /**
61
-     * one of the EE_System::req_type_* constants
62
-     *
63
-     * @type int $_req_type
64
-     */
65
-    protected $_req_type;
66
-
67
-    /**
68
-     * page slug to be used when generating the "Settings" link on the WP plugin page
69
-     *
70
-     * @type string $_plugin_action_slug
71
-     */
72
-    protected $_plugin_action_slug = '';
73
-
74
-    /**
75
-     * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
76
-     * that can be used for adding upgrading/marketing info
77
-     *
78
-     * @type array $_plugins_page_row
79
-     */
80
-    protected $_plugins_page_row = array();
81
-
82
-
83
-
84
-    /**
85
-     *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
-     *
87
-     * @type string
88
-     */
89
-    protected $_main_plugin_file;
90
-
91
-
92
-    /**
93
-     * @var EE_Dependency_Map $dependency_map
94
-     */
95
-    private $dependency_map;
96
-
97
-
98
-    /**
99
-     * @var DomainInterface $domain
100
-     */
101
-    private $domain;
102
-
103
-
104
-    /**
105
-     * @param EE_Dependency_Map $dependency_map [optional]
106
-     * @param DomainInterface   $domain         [optional]
107
-     */
108
-    public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
109
-    {
110
-        if($dependency_map instanceof EE_Dependency_Map) {
111
-            $this->setDependencyMap($dependency_map);
112
-        }
113
-        if ($domain instanceof DomainInterface) {
114
-            $this->setDomain($domain);
115
-        }
116
-        add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
117
-    }
118
-
119
-
120
-    /**
121
-     * @param EE_Dependency_Map $dependency_map
122
-     */
123
-    public function setDependencyMap($dependency_map)
124
-    {
125
-        $this->dependency_map = $dependency_map;
126
-    }
127
-
128
-
129
-    /**
130
-     * @return EE_Dependency_Map
131
-     */
132
-    public function dependencyMap()
133
-    {
134
-        return $this->dependency_map;
135
-    }
136
-
137
-
138
-    /**
139
-     * @param DomainInterface $domain
140
-     */
141
-    public function setDomain(DomainInterface $domain)
142
-    {
143
-        $this->domain = $domain;
144
-    }
145
-
146
-    /**
147
-     * @return DomainInterface
148
-     */
149
-    public function domain()
150
-    {
151
-        return $this->domain;
152
-    }
153
-
154
-
155
-    /**
156
-     * @param mixed $version
157
-     */
158
-    public function set_version($version = null)
159
-    {
160
-        $this->_version = $version;
161
-    }
162
-
163
-
164
-    /**
165
-     * get__version
166
-     *
167
-     * @return string
168
-     */
169
-    public function version()
170
-    {
171
-        return $this->_version;
172
-    }
173
-
174
-
175
-    /**
176
-     * @param mixed $min_core_version
177
-     */
178
-    public function set_min_core_version($min_core_version = null)
179
-    {
180
-        $this->_min_core_version = $min_core_version;
181
-    }
182
-
183
-
184
-    /**
185
-     * get__min_core_version
186
-     *
187
-     * @return string
188
-     */
189
-    public function min_core_version()
190
-    {
191
-        return $this->_min_core_version;
192
-    }
193
-
194
-
195
-    /**
196
-     * Sets addon_name
197
-     *
198
-     * @param string $addon_name
199
-     * @return boolean
200
-     */
201
-    public function set_name($addon_name)
202
-    {
203
-        return $this->_addon_name = $addon_name;
204
-    }
205
-
206
-
207
-    /**
208
-     * Gets addon_name
209
-     *
210
-     * @return string
211
-     */
212
-    public function name()
213
-    {
214
-        return $this->_addon_name;
215
-    }
216
-
217
-
218
-    /**
219
-     * @return string
220
-     */
221
-    public function plugin_basename()
222
-    {
223
-
224
-        return $this->_plugin_basename;
225
-    }
226
-
227
-
228
-    /**
229
-     * @param string $plugin_basename
230
-     */
231
-    public function set_plugin_basename($plugin_basename)
232
-    {
233
-
234
-        $this->_plugin_basename = $plugin_basename;
235
-    }
236
-
237
-
238
-    /**
239
-     * @return string
240
-     */
241
-    public function plugin_slug()
242
-    {
243
-
244
-        return $this->_plugin_slug;
245
-    }
246
-
247
-
248
-    /**
249
-     * @param string $plugin_slug
250
-     */
251
-    public function set_plugin_slug($plugin_slug)
252
-    {
253
-
254
-        $this->_plugin_slug = $plugin_slug;
255
-    }
256
-
257
-
258
-    /**
259
-     * @return string
260
-     */
261
-    public function plugin_action_slug()
262
-    {
263
-
264
-        return $this->_plugin_action_slug;
265
-    }
266
-
267
-
268
-    /**
269
-     * @param string $plugin_action_slug
270
-     */
271
-    public function set_plugin_action_slug($plugin_action_slug)
272
-    {
273
-
274
-        $this->_plugin_action_slug = $plugin_action_slug;
275
-    }
276
-
277
-
278
-    /**
279
-     * @return array
280
-     */
281
-    public function get_plugins_page_row()
282
-    {
283
-
284
-        return $this->_plugins_page_row;
285
-    }
286
-
287
-
288
-    /**
289
-     * @param array $plugins_page_row
290
-     */
291
-    public function set_plugins_page_row($plugins_page_row = array())
292
-    {
293
-        // sigh.... check for example content that I stupidly merged to master and remove it if found
294
-        if (! is_array($plugins_page_row)
295
-            && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
296
-        ) {
297
-            $plugins_page_row = array();
298
-        }
299
-        $this->_plugins_page_row = (array) $plugins_page_row;
300
-    }
301
-
302
-
303
-    /**
304
-     * Called when EE core detects this addon has been activated for the first time.
305
-     * If the site isn't in maintenance mode, should setup the addon's database
306
-     *
307
-     * @return void
308
-     */
309
-    public function new_install()
310
-    {
311
-        $classname = get_class($this);
312
-        do_action("AHEE__{$classname}__new_install");
313
-        do_action('AHEE__EE_Addon__new_install', $this);
314
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
315
-        add_action(
316
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
317
-            array($this, 'initialize_db_if_no_migrations_required')
318
-        );
319
-    }
320
-
321
-
322
-    /**
323
-     * Called when EE core detects this addon has been reactivated. When this happens,
324
-     * it's good to just check that your data is still intact
325
-     *
326
-     * @return void
327
-     */
328
-    public function reactivation()
329
-    {
330
-        $classname = get_class($this);
331
-        do_action("AHEE__{$classname}__reactivation");
332
-        do_action('AHEE__EE_Addon__reactivation', $this);
333
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
334
-        add_action(
335
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
336
-            array($this, 'initialize_db_if_no_migrations_required')
337
-        );
338
-    }
339
-
340
-
341
-    /**
342
-     * Called when the registered deactivation hook for this addon fires.
343
-     * @throws EE_Error
344
-     */
345
-    public function deactivation()
346
-    {
347
-        $classname = get_class($this);
348
-        do_action("AHEE__{$classname}__deactivation");
349
-        do_action('AHEE__EE_Addon__deactivation', $this);
350
-        //check if the site no longer needs to be in maintenance mode
351
-        EE_Register_Addon::deregister($this->name());
352
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
353
-    }
354
-
355
-
356
-    /**
357
-     * Takes care of double-checking that we're not in maintenance mode, and then
358
-     * initializing this addon's necessary initial data. This is called by default on new activations
359
-     * and reactivations.
360
-     *
361
-     * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
362
-     *                               This is a resource-intensive job so we prefer to only do it when necessary
363
-     * @return void
364
-     * @throws \EE_Error
365
-     */
366
-    public function initialize_db_if_no_migrations_required($verify_schema = true)
367
-    {
368
-        if ($verify_schema === '') {
369
-            //wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
370
-            //(ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
371
-            //calls them with an argument of an empty string (ie ""), which evaluates to false
372
-            //so we need to treat the empty string as if nothing had been passed, and should instead use the default
373
-            $verify_schema = true;
374
-        }
375
-        if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
376
-            if ($verify_schema) {
377
-                $this->initialize_db();
378
-            }
379
-            $this->initialize_default_data();
380
-            //@todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
381
-            EE_Data_Migration_Manager::instance()->update_current_database_state_to(
382
-                array(
383
-                    'slug'    => $this->name(),
384
-                    'version' => $this->version(),
385
-                )
386
-            );
387
-            /* make sure core's data is a-ok
21
+	/**
22
+	 * prefix to be added onto an addon's plugin slug to make a wp option name
23
+	 * which will be used to store the plugin's activation history
24
+	 */
25
+	const ee_addon_version_history_option_prefix = 'ee_version_history_';
26
+
27
+	/**
28
+	 * @var $_version
29
+	 * @type string
30
+	 */
31
+	protected $_version = '';
32
+
33
+	/**
34
+	 * @var $_min_core_version
35
+	 * @type string
36
+	 */
37
+	protected $_min_core_version = '';
38
+
39
+	/**
40
+	 * derived from plugin 'main_file_path using plugin_basename()
41
+	 *
42
+	 * @type string $_plugin_basename
43
+	 */
44
+	protected $_plugin_basename = '';
45
+
46
+	/**
47
+	 * A non-internationalized name to identify this addon for use in URLs, etc
48
+	 *
49
+	 * @type string $_plugin_slug
50
+	 */
51
+	protected $_plugin_slug = '';
52
+
53
+	/**
54
+	 * A non-internationalized name to identify this addon. Eg 'Calendar','MailChimp',etc/
55
+	 *
56
+	 * @type string _addon_name
57
+	 */
58
+	protected $_addon_name = '';
59
+
60
+	/**
61
+	 * one of the EE_System::req_type_* constants
62
+	 *
63
+	 * @type int $_req_type
64
+	 */
65
+	protected $_req_type;
66
+
67
+	/**
68
+	 * page slug to be used when generating the "Settings" link on the WP plugin page
69
+	 *
70
+	 * @type string $_plugin_action_slug
71
+	 */
72
+	protected $_plugin_action_slug = '';
73
+
74
+	/**
75
+	 * if not empty, inserts a new table row after this plugin's row on the WP Plugins page
76
+	 * that can be used for adding upgrading/marketing info
77
+	 *
78
+	 * @type array $_plugins_page_row
79
+	 */
80
+	protected $_plugins_page_row = array();
81
+
82
+
83
+
84
+	/**
85
+	 *    filepath to the main file, which can be used for register_activation_hook, register_deactivation_hook, etc.
86
+	 *
87
+	 * @type string
88
+	 */
89
+	protected $_main_plugin_file;
90
+
91
+
92
+	/**
93
+	 * @var EE_Dependency_Map $dependency_map
94
+	 */
95
+	private $dependency_map;
96
+
97
+
98
+	/**
99
+	 * @var DomainInterface $domain
100
+	 */
101
+	private $domain;
102
+
103
+
104
+	/**
105
+	 * @param EE_Dependency_Map $dependency_map [optional]
106
+	 * @param DomainInterface   $domain         [optional]
107
+	 */
108
+	public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
109
+	{
110
+		if($dependency_map instanceof EE_Dependency_Map) {
111
+			$this->setDependencyMap($dependency_map);
112
+		}
113
+		if ($domain instanceof DomainInterface) {
114
+			$this->setDomain($domain);
115
+		}
116
+		add_action('AHEE__EE_System__load_controllers__load_admin_controllers', array($this, 'admin_init'));
117
+	}
118
+
119
+
120
+	/**
121
+	 * @param EE_Dependency_Map $dependency_map
122
+	 */
123
+	public function setDependencyMap($dependency_map)
124
+	{
125
+		$this->dependency_map = $dependency_map;
126
+	}
127
+
128
+
129
+	/**
130
+	 * @return EE_Dependency_Map
131
+	 */
132
+	public function dependencyMap()
133
+	{
134
+		return $this->dependency_map;
135
+	}
136
+
137
+
138
+	/**
139
+	 * @param DomainInterface $domain
140
+	 */
141
+	public function setDomain(DomainInterface $domain)
142
+	{
143
+		$this->domain = $domain;
144
+	}
145
+
146
+	/**
147
+	 * @return DomainInterface
148
+	 */
149
+	public function domain()
150
+	{
151
+		return $this->domain;
152
+	}
153
+
154
+
155
+	/**
156
+	 * @param mixed $version
157
+	 */
158
+	public function set_version($version = null)
159
+	{
160
+		$this->_version = $version;
161
+	}
162
+
163
+
164
+	/**
165
+	 * get__version
166
+	 *
167
+	 * @return string
168
+	 */
169
+	public function version()
170
+	{
171
+		return $this->_version;
172
+	}
173
+
174
+
175
+	/**
176
+	 * @param mixed $min_core_version
177
+	 */
178
+	public function set_min_core_version($min_core_version = null)
179
+	{
180
+		$this->_min_core_version = $min_core_version;
181
+	}
182
+
183
+
184
+	/**
185
+	 * get__min_core_version
186
+	 *
187
+	 * @return string
188
+	 */
189
+	public function min_core_version()
190
+	{
191
+		return $this->_min_core_version;
192
+	}
193
+
194
+
195
+	/**
196
+	 * Sets addon_name
197
+	 *
198
+	 * @param string $addon_name
199
+	 * @return boolean
200
+	 */
201
+	public function set_name($addon_name)
202
+	{
203
+		return $this->_addon_name = $addon_name;
204
+	}
205
+
206
+
207
+	/**
208
+	 * Gets addon_name
209
+	 *
210
+	 * @return string
211
+	 */
212
+	public function name()
213
+	{
214
+		return $this->_addon_name;
215
+	}
216
+
217
+
218
+	/**
219
+	 * @return string
220
+	 */
221
+	public function plugin_basename()
222
+	{
223
+
224
+		return $this->_plugin_basename;
225
+	}
226
+
227
+
228
+	/**
229
+	 * @param string $plugin_basename
230
+	 */
231
+	public function set_plugin_basename($plugin_basename)
232
+	{
233
+
234
+		$this->_plugin_basename = $plugin_basename;
235
+	}
236
+
237
+
238
+	/**
239
+	 * @return string
240
+	 */
241
+	public function plugin_slug()
242
+	{
243
+
244
+		return $this->_plugin_slug;
245
+	}
246
+
247
+
248
+	/**
249
+	 * @param string $plugin_slug
250
+	 */
251
+	public function set_plugin_slug($plugin_slug)
252
+	{
253
+
254
+		$this->_plugin_slug = $plugin_slug;
255
+	}
256
+
257
+
258
+	/**
259
+	 * @return string
260
+	 */
261
+	public function plugin_action_slug()
262
+	{
263
+
264
+		return $this->_plugin_action_slug;
265
+	}
266
+
267
+
268
+	/**
269
+	 * @param string $plugin_action_slug
270
+	 */
271
+	public function set_plugin_action_slug($plugin_action_slug)
272
+	{
273
+
274
+		$this->_plugin_action_slug = $plugin_action_slug;
275
+	}
276
+
277
+
278
+	/**
279
+	 * @return array
280
+	 */
281
+	public function get_plugins_page_row()
282
+	{
283
+
284
+		return $this->_plugins_page_row;
285
+	}
286
+
287
+
288
+	/**
289
+	 * @param array $plugins_page_row
290
+	 */
291
+	public function set_plugins_page_row($plugins_page_row = array())
292
+	{
293
+		// sigh.... check for example content that I stupidly merged to master and remove it if found
294
+		if (! is_array($plugins_page_row)
295
+			&& strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
296
+		) {
297
+			$plugins_page_row = array();
298
+		}
299
+		$this->_plugins_page_row = (array) $plugins_page_row;
300
+	}
301
+
302
+
303
+	/**
304
+	 * Called when EE core detects this addon has been activated for the first time.
305
+	 * If the site isn't in maintenance mode, should setup the addon's database
306
+	 *
307
+	 * @return void
308
+	 */
309
+	public function new_install()
310
+	{
311
+		$classname = get_class($this);
312
+		do_action("AHEE__{$classname}__new_install");
313
+		do_action('AHEE__EE_Addon__new_install', $this);
314
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
315
+		add_action(
316
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
317
+			array($this, 'initialize_db_if_no_migrations_required')
318
+		);
319
+	}
320
+
321
+
322
+	/**
323
+	 * Called when EE core detects this addon has been reactivated. When this happens,
324
+	 * it's good to just check that your data is still intact
325
+	 *
326
+	 * @return void
327
+	 */
328
+	public function reactivation()
329
+	{
330
+		$classname = get_class($this);
331
+		do_action("AHEE__{$classname}__reactivation");
332
+		do_action('AHEE__EE_Addon__reactivation', $this);
333
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
334
+		add_action(
335
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
336
+			array($this, 'initialize_db_if_no_migrations_required')
337
+		);
338
+	}
339
+
340
+
341
+	/**
342
+	 * Called when the registered deactivation hook for this addon fires.
343
+	 * @throws EE_Error
344
+	 */
345
+	public function deactivation()
346
+	{
347
+		$classname = get_class($this);
348
+		do_action("AHEE__{$classname}__deactivation");
349
+		do_action('AHEE__EE_Addon__deactivation', $this);
350
+		//check if the site no longer needs to be in maintenance mode
351
+		EE_Register_Addon::deregister($this->name());
352
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
353
+	}
354
+
355
+
356
+	/**
357
+	 * Takes care of double-checking that we're not in maintenance mode, and then
358
+	 * initializing this addon's necessary initial data. This is called by default on new activations
359
+	 * and reactivations.
360
+	 *
361
+	 * @param boolean $verify_schema whether to verify the database's schema for this addon, or just its data.
362
+	 *                               This is a resource-intensive job so we prefer to only do it when necessary
363
+	 * @return void
364
+	 * @throws \EE_Error
365
+	 */
366
+	public function initialize_db_if_no_migrations_required($verify_schema = true)
367
+	{
368
+		if ($verify_schema === '') {
369
+			//wp core bug imo: if no args are passed to `do_action('some_hook_name')` besides the hook's name
370
+			//(ie, no 2nd or 3rd arguments), instead of calling the registered callbacks with no arguments, it
371
+			//calls them with an argument of an empty string (ie ""), which evaluates to false
372
+			//so we need to treat the empty string as if nothing had been passed, and should instead use the default
373
+			$verify_schema = true;
374
+		}
375
+		if (EE_Maintenance_Mode::instance()->level() !== EE_Maintenance_Mode::level_2_complete_maintenance) {
376
+			if ($verify_schema) {
377
+				$this->initialize_db();
378
+			}
379
+			$this->initialize_default_data();
380
+			//@todo: this will probably need to be adjusted in 4.4 as the array changed formats I believe
381
+			EE_Data_Migration_Manager::instance()->update_current_database_state_to(
382
+				array(
383
+					'slug'    => $this->name(),
384
+					'version' => $this->version(),
385
+				)
386
+			);
387
+			/* make sure core's data is a-ok
388 388
              * (at the time of writing, we especially want to verify all the caps are present
389 389
              * because payment method type capabilities are added dynamically, and it's
390 390
              * possible this addon added a payment method. But it's also possible
391 391
              * other data needs to be verified)
392 392
              */
393
-            EEH_Activation::initialize_db_content();
394
-            update_option('ee_flush_rewrite_rules', true);
395
-            //in case there are lots of addons being activated at once, let's force garbage collection
396
-            //to help avoid memory limit errors
397
-            //EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
398
-            gc_collect_cycles();
399
-        } else {
400
-            //ask the data migration manager to init this addon's data
401
-            //when migrations are finished because we can't do it now
402
-            EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
403
-        }
404
-    }
405
-
406
-
407
-    /**
408
-     * Used to setup this addon's database tables, but not necessarily any default
409
-     * data in them. The default is to actually use the most up-to-date data migration script
410
-     * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
411
-     * methods to setup the db.
412
-     */
413
-    public function initialize_db()
414
-    {
415
-        //find the migration script that sets the database to be compatible with the code
416
-        $current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
417
-        if ($current_dms_name) {
418
-            $current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
419
-            $current_data_migration_script->set_migrating(false);
420
-            $current_data_migration_script->schema_changes_before_migration();
421
-            $current_data_migration_script->schema_changes_after_migration();
422
-            if ($current_data_migration_script->get_errors()) {
423
-                foreach ($current_data_migration_script->get_errors() as $error) {
424
-                    EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
425
-                }
426
-            }
427
-        }
428
-        //if not DMS was found that should be ok. This addon just doesn't require any database changes
429
-        EE_Data_Migration_Manager::instance()->update_current_database_state_to(
430
-            array(
431
-                'slug'    => $this->name(),
432
-                'version' => $this->version(),
433
-            )
434
-        );
435
-    }
436
-
437
-
438
-    /**
439
-     * If you want to setup default data for the addon, override this method, and call
440
-     * parent::initialize_default_data() from within it. This is normally called
441
-     * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
442
-     * and should verify default data is present (but this is also called
443
-     * on reactivations and just after migrations, so please verify you actually want
444
-     * to ADD default data, because it may already be present).
445
-     * However, please call this parent (currently it just fires a hook which other
446
-     * addons may be depending on)
447
-     */
448
-    public function initialize_default_data()
449
-    {
450
-        /**
451
-         * Called when an addon is ensuring its default data is set (possibly called
452
-         * on a reactivation, so first check for the absence of other data before setting
453
-         * default data)
454
-         *
455
-         * @param EE_Addon $addon the addon that called this
456
-         */
457
-        do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
458
-        //override to insert default data. It is safe to use the models here
459
-        //because the site should not be in maintenance mode
460
-    }
461
-
462
-
463
-    /**
464
-     * EE Core detected that this addon has been upgraded. We should check if there
465
-     * are any new migration scripts, and if so put the site into maintenance mode until
466
-     * they're ran
467
-     *
468
-     * @return void
469
-     */
470
-    public function upgrade()
471
-    {
472
-        $classname = get_class($this);
473
-        do_action("AHEE__{$classname}__upgrade");
474
-        do_action('AHEE__EE_Addon__upgrade', $this);
475
-        EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
476
-        //also it's possible there is new default data that needs to be added
477
-        add_action(
478
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
479
-            array($this, 'initialize_db_if_no_migrations_required')
480
-        );
481
-    }
482
-
483
-
484
-    /**
485
-     * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
486
-     */
487
-    public function downgrade()
488
-    {
489
-        $classname = get_class($this);
490
-        do_action("AHEE__{$classname}__downgrade");
491
-        do_action('AHEE__EE_Addon__downgrade', $this);
492
-        //it's possible there's old default data that needs to be double-checked
493
-        add_action(
494
-            'AHEE__EE_System__perform_activations_upgrades_and_migrations',
495
-            array($this, 'initialize_db_if_no_migrations_required')
496
-        );
497
-    }
498
-
499
-
500
-    /**
501
-     * set_db_update_option_name
502
-     * Until we do something better, we'll just check for migration scripts upon
503
-     * plugin activation only. In the future, we'll want to do it on plugin updates too
504
-     *
505
-     * @return bool
506
-     */
507
-    public function set_db_update_option_name()
508
-    {
509
-        EE_Error::doing_it_wrong(
510
-            __FUNCTION__,
511
-            esc_html__(
512
-                'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
513
-                'event_espresso'
514
-            ),
515
-            '4.3.0.alpha.016'
516
-        );
517
-        //let's just handle this on the next request, ok? right now we're just not really ready
518
-        return $this->set_activation_indicator_option();
519
-    }
520
-
521
-
522
-    /**
523
-     * Returns the name of the activation indicator option
524
-     * (an option which is set temporarily to indicate that this addon was just activated)
525
-     *
526
-     * @deprecated since version 4.3.0.alpha.016
527
-     * @return string
528
-     */
529
-    public function get_db_update_option_name()
530
-    {
531
-        EE_Error::doing_it_wrong(
532
-            __FUNCTION__,
533
-            esc_html__(
534
-                'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
535
-                'event_espresso'
536
-            ),
537
-            '4.3.0.alpha.016'
538
-        );
539
-        return $this->get_activation_indicator_option_name();
540
-    }
541
-
542
-
543
-    /**
544
-     * When the addon is activated, this should be called to set a wordpress option that
545
-     * indicates it was activated. This is especially useful for detecting reactivations.
546
-     *
547
-     * @return bool
548
-     */
549
-    public function set_activation_indicator_option()
550
-    {
551
-        // let's just handle this on the next request, ok? right now we're just not really ready
552
-        return update_option($this->get_activation_indicator_option_name(), true);
553
-    }
554
-
555
-
556
-    /**
557
-     * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
558
-     *
559
-     * @return string
560
-     */
561
-    public function get_activation_indicator_option_name()
562
-    {
563
-        return 'ee_activation_' . $this->name();
564
-    }
565
-
566
-
567
-    /**
568
-     * Used by EE_System to set the request type of this addon. Should not be used by addon developers
569
-     *
570
-     * @param int $req_type
571
-     */
572
-    public function set_req_type($req_type)
573
-    {
574
-        $this->_req_type = $req_type;
575
-    }
576
-
577
-
578
-    /**
579
-     * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
580
-     * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
581
-     * EE_System when it is checking for new install or upgrades of addons
582
-     */
583
-    public function detect_req_type()
584
-    {
585
-        if (! $this->_req_type) {
586
-            $this->detect_activation_or_upgrade();
587
-        }
588
-        return $this->_req_type;
589
-    }
590
-
591
-
592
-    /**
593
-     * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
594
-     * Should only be called once per request
595
-     *
596
-     * @return void
597
-     */
598
-    public function detect_activation_or_upgrade()
599
-    {
600
-        $activation_history_for_addon = $this->get_activation_history();
393
+			EEH_Activation::initialize_db_content();
394
+			update_option('ee_flush_rewrite_rules', true);
395
+			//in case there are lots of addons being activated at once, let's force garbage collection
396
+			//to help avoid memory limit errors
397
+			//EEH_Debug_Tools::instance()->measure_memory( 'db content initialized for ' . get_class( $this), true );
398
+			gc_collect_cycles();
399
+		} else {
400
+			//ask the data migration manager to init this addon's data
401
+			//when migrations are finished because we can't do it now
402
+			EE_Data_Migration_Manager::instance()->enqueue_db_initialization_for($this->name());
403
+		}
404
+	}
405
+
406
+
407
+	/**
408
+	 * Used to setup this addon's database tables, but not necessarily any default
409
+	 * data in them. The default is to actually use the most up-to-date data migration script
410
+	 * for this addon, and just use its schema_changes_before_migration() and schema_changes_after_migration()
411
+	 * methods to setup the db.
412
+	 */
413
+	public function initialize_db()
414
+	{
415
+		//find the migration script that sets the database to be compatible with the code
416
+		$current_dms_name = EE_Data_Migration_Manager::instance()->get_most_up_to_date_dms($this->name());
417
+		if ($current_dms_name) {
418
+			$current_data_migration_script = EE_Registry::instance()->load_dms($current_dms_name);
419
+			$current_data_migration_script->set_migrating(false);
420
+			$current_data_migration_script->schema_changes_before_migration();
421
+			$current_data_migration_script->schema_changes_after_migration();
422
+			if ($current_data_migration_script->get_errors()) {
423
+				foreach ($current_data_migration_script->get_errors() as $error) {
424
+					EE_Error::add_error($error, __FILE__, __FUNCTION__, __LINE__);
425
+				}
426
+			}
427
+		}
428
+		//if not DMS was found that should be ok. This addon just doesn't require any database changes
429
+		EE_Data_Migration_Manager::instance()->update_current_database_state_to(
430
+			array(
431
+				'slug'    => $this->name(),
432
+				'version' => $this->version(),
433
+			)
434
+		);
435
+	}
436
+
437
+
438
+	/**
439
+	 * If you want to setup default data for the addon, override this method, and call
440
+	 * parent::initialize_default_data() from within it. This is normally called
441
+	 * from EE_Addon::initialize_db_if_no_migrations_required(), just after EE_Addon::initialize_db()
442
+	 * and should verify default data is present (but this is also called
443
+	 * on reactivations and just after migrations, so please verify you actually want
444
+	 * to ADD default data, because it may already be present).
445
+	 * However, please call this parent (currently it just fires a hook which other
446
+	 * addons may be depending on)
447
+	 */
448
+	public function initialize_default_data()
449
+	{
450
+		/**
451
+		 * Called when an addon is ensuring its default data is set (possibly called
452
+		 * on a reactivation, so first check for the absence of other data before setting
453
+		 * default data)
454
+		 *
455
+		 * @param EE_Addon $addon the addon that called this
456
+		 */
457
+		do_action('AHEE__EE_Addon__initialize_default_data__begin', $this);
458
+		//override to insert default data. It is safe to use the models here
459
+		//because the site should not be in maintenance mode
460
+	}
461
+
462
+
463
+	/**
464
+	 * EE Core detected that this addon has been upgraded. We should check if there
465
+	 * are any new migration scripts, and if so put the site into maintenance mode until
466
+	 * they're ran
467
+	 *
468
+	 * @return void
469
+	 */
470
+	public function upgrade()
471
+	{
472
+		$classname = get_class($this);
473
+		do_action("AHEE__{$classname}__upgrade");
474
+		do_action('AHEE__EE_Addon__upgrade', $this);
475
+		EE_Maintenance_Mode::instance()->set_maintenance_mode_if_db_old();
476
+		//also it's possible there is new default data that needs to be added
477
+		add_action(
478
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
479
+			array($this, 'initialize_db_if_no_migrations_required')
480
+		);
481
+	}
482
+
483
+
484
+	/**
485
+	 * If Core detects this addon has been downgraded, you may want to invoke some special logic here.
486
+	 */
487
+	public function downgrade()
488
+	{
489
+		$classname = get_class($this);
490
+		do_action("AHEE__{$classname}__downgrade");
491
+		do_action('AHEE__EE_Addon__downgrade', $this);
492
+		//it's possible there's old default data that needs to be double-checked
493
+		add_action(
494
+			'AHEE__EE_System__perform_activations_upgrades_and_migrations',
495
+			array($this, 'initialize_db_if_no_migrations_required')
496
+		);
497
+	}
498
+
499
+
500
+	/**
501
+	 * set_db_update_option_name
502
+	 * Until we do something better, we'll just check for migration scripts upon
503
+	 * plugin activation only. In the future, we'll want to do it on plugin updates too
504
+	 *
505
+	 * @return bool
506
+	 */
507
+	public function set_db_update_option_name()
508
+	{
509
+		EE_Error::doing_it_wrong(
510
+			__FUNCTION__,
511
+			esc_html__(
512
+				'EE_Addon::set_db_update_option_name was renamed to EE_Addon::set_activation_indicator_option',
513
+				'event_espresso'
514
+			),
515
+			'4.3.0.alpha.016'
516
+		);
517
+		//let's just handle this on the next request, ok? right now we're just not really ready
518
+		return $this->set_activation_indicator_option();
519
+	}
520
+
521
+
522
+	/**
523
+	 * Returns the name of the activation indicator option
524
+	 * (an option which is set temporarily to indicate that this addon was just activated)
525
+	 *
526
+	 * @deprecated since version 4.3.0.alpha.016
527
+	 * @return string
528
+	 */
529
+	public function get_db_update_option_name()
530
+	{
531
+		EE_Error::doing_it_wrong(
532
+			__FUNCTION__,
533
+			esc_html__(
534
+				'EE_Addon::get_db_update_option was renamed to EE_Addon::get_activation_indicator_option_name',
535
+				'event_espresso'
536
+			),
537
+			'4.3.0.alpha.016'
538
+		);
539
+		return $this->get_activation_indicator_option_name();
540
+	}
541
+
542
+
543
+	/**
544
+	 * When the addon is activated, this should be called to set a wordpress option that
545
+	 * indicates it was activated. This is especially useful for detecting reactivations.
546
+	 *
547
+	 * @return bool
548
+	 */
549
+	public function set_activation_indicator_option()
550
+	{
551
+		// let's just handle this on the next request, ok? right now we're just not really ready
552
+		return update_option($this->get_activation_indicator_option_name(), true);
553
+	}
554
+
555
+
556
+	/**
557
+	 * Gets the name of the wp option which is used to temporarily indicate that this addon was activated
558
+	 *
559
+	 * @return string
560
+	 */
561
+	public function get_activation_indicator_option_name()
562
+	{
563
+		return 'ee_activation_' . $this->name();
564
+	}
565
+
566
+
567
+	/**
568
+	 * Used by EE_System to set the request type of this addon. Should not be used by addon developers
569
+	 *
570
+	 * @param int $req_type
571
+	 */
572
+	public function set_req_type($req_type)
573
+	{
574
+		$this->_req_type = $req_type;
575
+	}
576
+
577
+
578
+	/**
579
+	 * Returns the request type of this addon (ie, EE_System::req_type_normal, EE_System::req_type_new_activation,
580
+	 * EE_System::req_type_reactivation, EE_System::req_type_upgrade, or EE_System::req_type_downgrade). This is set by
581
+	 * EE_System when it is checking for new install or upgrades of addons
582
+	 */
583
+	public function detect_req_type()
584
+	{
585
+		if (! $this->_req_type) {
586
+			$this->detect_activation_or_upgrade();
587
+		}
588
+		return $this->_req_type;
589
+	}
590
+
591
+
592
+	/**
593
+	 * Detects the request type for this addon (whether it was just activated, upgrades, a normal request, etc.)
594
+	 * Should only be called once per request
595
+	 *
596
+	 * @return void
597
+	 */
598
+	public function detect_activation_or_upgrade()
599
+	{
600
+		$activation_history_for_addon = $this->get_activation_history();
601 601
 //		d($activation_history_for_addon);
602
-        $request_type = EE_System::detect_req_type_given_activation_history(
603
-            $activation_history_for_addon,
604
-            $this->get_activation_indicator_option_name(),
605
-            $this->version()
606
-        );
607
-        $this->set_req_type($request_type);
608
-        $classname = get_class($this);
609
-        switch ($request_type) {
610
-            case EE_System::req_type_new_activation:
611
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
612
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
613
-                $this->new_install();
614
-                $this->update_list_of_installed_versions($activation_history_for_addon);
615
-                break;
616
-            case EE_System::req_type_reactivation:
617
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
618
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
619
-                $this->reactivation();
620
-                $this->update_list_of_installed_versions($activation_history_for_addon);
621
-                break;
622
-            case EE_System::req_type_upgrade:
623
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
624
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
625
-                $this->upgrade();
626
-                $this->update_list_of_installed_versions($activation_history_for_addon);
627
-                break;
628
-            case EE_System::req_type_downgrade:
629
-                do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
630
-                do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
631
-                $this->downgrade();
632
-                $this->update_list_of_installed_versions($activation_history_for_addon);
633
-                break;
634
-            case EE_System::req_type_normal:
635
-            default:
602
+		$request_type = EE_System::detect_req_type_given_activation_history(
603
+			$activation_history_for_addon,
604
+			$this->get_activation_indicator_option_name(),
605
+			$this->version()
606
+		);
607
+		$this->set_req_type($request_type);
608
+		$classname = get_class($this);
609
+		switch ($request_type) {
610
+			case EE_System::req_type_new_activation:
611
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__new_activation");
612
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__new_activation', $this);
613
+				$this->new_install();
614
+				$this->update_list_of_installed_versions($activation_history_for_addon);
615
+				break;
616
+			case EE_System::req_type_reactivation:
617
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__reactivation");
618
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__reactivation', $this);
619
+				$this->reactivation();
620
+				$this->update_list_of_installed_versions($activation_history_for_addon);
621
+				break;
622
+			case EE_System::req_type_upgrade:
623
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__upgrade");
624
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__upgrade', $this);
625
+				$this->upgrade();
626
+				$this->update_list_of_installed_versions($activation_history_for_addon);
627
+				break;
628
+			case EE_System::req_type_downgrade:
629
+				do_action("AHEE__{$classname}__detect_activations_or_upgrades__downgrade");
630
+				do_action('AHEE__EE_Addon__detect_activations_or_upgrades__downgrade', $this);
631
+				$this->downgrade();
632
+				$this->update_list_of_installed_versions($activation_history_for_addon);
633
+				break;
634
+			case EE_System::req_type_normal:
635
+			default:
636 636
 //				$this->_maybe_redirect_to_ee_about();
637
-                break;
638
-        }
639
-
640
-        do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
641
-    }
642
-
643
-    /**
644
-     * Updates the version history for this addon
645
-     *
646
-     * @param array  $version_history
647
-     * @param string $current_version_to_add
648
-     * @return boolean success
649
-     */
650
-    public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
651
-    {
652
-        if (! $version_history) {
653
-            $version_history = $this->get_activation_history();
654
-        }
655
-        if ($current_version_to_add === null) {
656
-            $current_version_to_add = $this->version();
657
-        }
658
-        $version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
659
-        // resave
637
+				break;
638
+		}
639
+
640
+		do_action("AHEE__{$classname}__detect_if_activation_or_upgrade__complete");
641
+	}
642
+
643
+	/**
644
+	 * Updates the version history for this addon
645
+	 *
646
+	 * @param array  $version_history
647
+	 * @param string $current_version_to_add
648
+	 * @return boolean success
649
+	 */
650
+	public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
651
+	{
652
+		if (! $version_history) {
653
+			$version_history = $this->get_activation_history();
654
+		}
655
+		if ($current_version_to_add === null) {
656
+			$current_version_to_add = $this->version();
657
+		}
658
+		$version_history[$current_version_to_add][] = date('Y-m-d H:i:s', time());
659
+		// resave
660 660
 //		echo "updating list of installed versions:".$this->get_activation_history_option_name();d($version_history);
661
-        return update_option($this->get_activation_history_option_name(), $version_history);
662
-    }
663
-
664
-    /**
665
-     * Gets the name of the wp option that stores the activation history
666
-     * of this addon
667
-     *
668
-     * @return string
669
-     */
670
-    public function get_activation_history_option_name()
671
-    {
672
-        return self::ee_addon_version_history_option_prefix . $this->name();
673
-    }
674
-
675
-
676
-    /**
677
-     * Gets the wp option which stores the activation history for this addon
678
-     *
679
-     * @return array
680
-     */
681
-    public function get_activation_history()
682
-    {
683
-        return get_option($this->get_activation_history_option_name(), null);
684
-    }
685
-
686
-
687
-    /**
688
-     * @param string $config_section
689
-     */
690
-    public function set_config_section($config_section = '')
691
-    {
692
-        $this->_config_section = ! empty($config_section) ? $config_section : 'addons';
693
-    }
694
-
695
-    /**
696
-     * Sets the filepath to the main plugin file
697
-     *
698
-     * @param string $filepath
699
-     */
700
-    public function set_main_plugin_file($filepath)
701
-    {
702
-        $this->_main_plugin_file = $filepath;
703
-    }
704
-
705
-    /**
706
-     * gets the filepath to teh main file
707
-     *
708
-     * @return string
709
-     */
710
-    public function get_main_plugin_file()
711
-    {
712
-        return $this->_main_plugin_file;
713
-    }
714
-
715
-    /**
716
-     * Gets the filename (no path) of the main file (the main file loaded
717
-     * by WP)
718
-     *
719
-     * @return string
720
-     */
721
-    public function get_main_plugin_file_basename()
722
-    {
723
-        return plugin_basename($this->get_main_plugin_file());
724
-    }
725
-
726
-    /**
727
-     * Gets the folder name which contains the main plugin file
728
-     *
729
-     * @return string
730
-     */
731
-    public function get_main_plugin_file_dirname()
732
-    {
733
-        return dirname($this->get_main_plugin_file());
734
-    }
735
-
736
-
737
-    /**
738
-     * sets hooks used in the admin
739
-     *
740
-     * @return void
741
-     */
742
-    public function admin_init()
743
-    {
744
-        // is admin and not in M-Mode ?
745
-        if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
746
-            add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
747
-            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
748
-        }
749
-    }
750
-
751
-
752
-    /**
753
-     * plugin_actions
754
-     * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
755
-     *
756
-     * @param $links
757
-     * @param $file
758
-     * @return array
759
-     */
760
-    public function plugin_action_links($links, $file)
761
-    {
762
-        if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
763
-            // before other links
764
-            array_unshift(
765
-                $links,
766
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
767
-                . esc_html__('Settings', 'event_espresso')
768
-                . '</a>'
769
-            );
770
-        }
771
-        return $links;
772
-    }
773
-
774
-
775
-    /**
776
-     * after_plugin_row
777
-     * Add additional content to the plugins page plugin row
778
-     * Inserts another row
779
-     *
780
-     * @param $plugin_file
781
-     * @param $plugin_data
782
-     * @param $status
783
-     * @return void
784
-     */
785
-    public function after_plugin_row($plugin_file, $plugin_data, $status)
786
-    {
787
-        $after_plugin_row = '';
788
-        $plugins_page_row = $this->get_plugins_page_row();
789
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
790
-            $class            = $status ? 'active' : 'inactive';
791
-            $link_text        = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
792
-            $link_url         = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
793
-            $description      = isset($plugins_page_row['description'])
794
-                ? $plugins_page_row['description']
795
-                : '';
796
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
797
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
798
-                $after_plugin_row .= '<th class="check-column" scope="row"></th>';
799
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
800
-                $after_plugin_row .= '<style>
661
+		return update_option($this->get_activation_history_option_name(), $version_history);
662
+	}
663
+
664
+	/**
665
+	 * Gets the name of the wp option that stores the activation history
666
+	 * of this addon
667
+	 *
668
+	 * @return string
669
+	 */
670
+	public function get_activation_history_option_name()
671
+	{
672
+		return self::ee_addon_version_history_option_prefix . $this->name();
673
+	}
674
+
675
+
676
+	/**
677
+	 * Gets the wp option which stores the activation history for this addon
678
+	 *
679
+	 * @return array
680
+	 */
681
+	public function get_activation_history()
682
+	{
683
+		return get_option($this->get_activation_history_option_name(), null);
684
+	}
685
+
686
+
687
+	/**
688
+	 * @param string $config_section
689
+	 */
690
+	public function set_config_section($config_section = '')
691
+	{
692
+		$this->_config_section = ! empty($config_section) ? $config_section : 'addons';
693
+	}
694
+
695
+	/**
696
+	 * Sets the filepath to the main plugin file
697
+	 *
698
+	 * @param string $filepath
699
+	 */
700
+	public function set_main_plugin_file($filepath)
701
+	{
702
+		$this->_main_plugin_file = $filepath;
703
+	}
704
+
705
+	/**
706
+	 * gets the filepath to teh main file
707
+	 *
708
+	 * @return string
709
+	 */
710
+	public function get_main_plugin_file()
711
+	{
712
+		return $this->_main_plugin_file;
713
+	}
714
+
715
+	/**
716
+	 * Gets the filename (no path) of the main file (the main file loaded
717
+	 * by WP)
718
+	 *
719
+	 * @return string
720
+	 */
721
+	public function get_main_plugin_file_basename()
722
+	{
723
+		return plugin_basename($this->get_main_plugin_file());
724
+	}
725
+
726
+	/**
727
+	 * Gets the folder name which contains the main plugin file
728
+	 *
729
+	 * @return string
730
+	 */
731
+	public function get_main_plugin_file_dirname()
732
+	{
733
+		return dirname($this->get_main_plugin_file());
734
+	}
735
+
736
+
737
+	/**
738
+	 * sets hooks used in the admin
739
+	 *
740
+	 * @return void
741
+	 */
742
+	public function admin_init()
743
+	{
744
+		// is admin and not in M-Mode ?
745
+		if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
746
+			add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
747
+			add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
748
+		}
749
+	}
750
+
751
+
752
+	/**
753
+	 * plugin_actions
754
+	 * Add a settings link to the Plugins page, so people can go straight from the plugin page to the settings page.
755
+	 *
756
+	 * @param $links
757
+	 * @param $file
758
+	 * @return array
759
+	 */
760
+	public function plugin_action_links($links, $file)
761
+	{
762
+		if ($file === $this->plugin_basename() && $this->plugin_action_slug() !== '') {
763
+			// before other links
764
+			array_unshift(
765
+				$links,
766
+				'<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
767
+				. esc_html__('Settings', 'event_espresso')
768
+				. '</a>'
769
+			);
770
+		}
771
+		return $links;
772
+	}
773
+
774
+
775
+	/**
776
+	 * after_plugin_row
777
+	 * Add additional content to the plugins page plugin row
778
+	 * Inserts another row
779
+	 *
780
+	 * @param $plugin_file
781
+	 * @param $plugin_data
782
+	 * @param $status
783
+	 * @return void
784
+	 */
785
+	public function after_plugin_row($plugin_file, $plugin_data, $status)
786
+	{
787
+		$after_plugin_row = '';
788
+		$plugins_page_row = $this->get_plugins_page_row();
789
+		if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
790
+			$class            = $status ? 'active' : 'inactive';
791
+			$link_text        = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
792
+			$link_url         = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
793
+			$description      = isset($plugins_page_row['description'])
794
+				? $plugins_page_row['description']
795
+				: '';
796
+			if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
797
+				$after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
798
+				$after_plugin_row .= '<th class="check-column" scope="row"></th>';
799
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
800
+				$after_plugin_row .= '<style>
801 801
 .ee-button,
802 802
 .ee-button:active,
803 803
 .ee-button:visited {
@@ -834,49 +834,49 @@  discard block
 block discarded – undo
834 834
 }
835 835
 .ee-button:active { top:0; }
836 836
 </style>';
837
-                $after_plugin_row .= '
837
+				$after_plugin_row .= '
838 838
 <p class="ee-addon-upsell-info-dv">
839 839
 	<a class="ee-button" href="' . $link_url . '">'
840
-                . $link_text
841
-                . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
842
-                . '</a>
840
+				. $link_text
841
+				. ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
842
+				. '</a>
843 843
 </p>';
844
-                $after_plugin_row .= '</td>';
845
-                $after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
846
-                $after_plugin_row .= $description;
847
-                $after_plugin_row .= '</td>';
848
-                $after_plugin_row .= '</tr>';
849
-            } else {
850
-                $after_plugin_row .= $description;
851
-            }
852
-        }
853
-
854
-        echo $after_plugin_row;
855
-    }
856
-
857
-
858
-    /**
859
-     * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
860
-     * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
861
-     * for back compat reasons.
862
-     *
863
-     * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
864
-     *
865
-     * It is recommended, if client code is `de-registering` an add-on, then do it on the
866
-     * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
867
-     * callback does not get run/set in that request.
868
-     *
869
-     * Also, keep in mind that if a registered add-on happens to be deactivated via
870
-     * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
871
-     * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
872
-     * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
873
-     * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
874
-     * to call `parent::deactivation`.
875
-     *
876
-     * @since 4.9.26
877
-     */
878
-    public function after_registration()
879
-    {
880
-        // cricket chirp... cricket chirp...
881
-    }
844
+				$after_plugin_row .= '</td>';
845
+				$after_plugin_row .= '<td class="ee-addon-upsell-info-desc-td column-description desc">';
846
+				$after_plugin_row .= $description;
847
+				$after_plugin_row .= '</td>';
848
+				$after_plugin_row .= '</tr>';
849
+			} else {
850
+				$after_plugin_row .= $description;
851
+			}
852
+		}
853
+
854
+		echo $after_plugin_row;
855
+	}
856
+
857
+
858
+	/**
859
+	 * A safe space for addons to add additional logic like setting hooks that need to be set early in the request.
860
+	 * Child classes that have logic like that to run can override this method declaration.  This was not made abstract
861
+	 * for back compat reasons.
862
+	 *
863
+	 * This will fire on the `AHEE__EE_System__load_espresso_addons__complete` hook at priority 999.
864
+	 *
865
+	 * It is recommended, if client code is `de-registering` an add-on, then do it on the
866
+	 * `AHEE__EE_System__load_espresso_addons__complete` hook before priority 999 so as to ensure any code logic in this
867
+	 * callback does not get run/set in that request.
868
+	 *
869
+	 * Also, keep in mind that if a registered add-on happens to be deactivated via
870
+	 * EE_System::_deactivate_incompatible_addons() because its incompatible, any code executed in this method
871
+	 * (including setting hooks etc) will have executed before the plugin was deactivated.  If you use
872
+	 * `after_registration` to set any filter and/or action hooks and want to ensure they are removed on this add-on's
873
+	 * deactivation, you can override `EE_Addon::deactivation` and unset your hooks and filters there.  Just remember
874
+	 * to call `parent::deactivation`.
875
+	 *
876
+	 * @since 4.9.26
877
+	 */
878
+	public function after_registration()
879
+	{
880
+		// cricket chirp... cricket chirp...
881
+	}
882 882
 }
Please login to merge, or discard this patch.
Spacing   +12 added lines, -12 removed lines patch added patch discarded remove patch
@@ -107,7 +107,7 @@  discard block
 block discarded – undo
107 107
      */
108 108
     public function __construct(EE_Dependency_Map $dependency_map = null, DomainInterface $domain = null)
109 109
     {
110
-        if($dependency_map instanceof EE_Dependency_Map) {
110
+        if ($dependency_map instanceof EE_Dependency_Map) {
111 111
             $this->setDependencyMap($dependency_map);
112 112
         }
113 113
         if ($domain instanceof DomainInterface) {
@@ -291,7 +291,7 @@  discard block
 block discarded – undo
291 291
     public function set_plugins_page_row($plugins_page_row = array())
292 292
     {
293 293
         // sigh.... check for example content that I stupidly merged to master and remove it if found
294
-        if (! is_array($plugins_page_row)
294
+        if ( ! is_array($plugins_page_row)
295 295
             && strpos($plugins_page_row, '<h3>Promotions Addon Upsell Info</h3>') !== false
296 296
         ) {
297 297
             $plugins_page_row = array();
@@ -560,7 +560,7 @@  discard block
 block discarded – undo
560 560
      */
561 561
     public function get_activation_indicator_option_name()
562 562
     {
563
-        return 'ee_activation_' . $this->name();
563
+        return 'ee_activation_'.$this->name();
564 564
     }
565 565
 
566 566
 
@@ -582,7 +582,7 @@  discard block
 block discarded – undo
582 582
      */
583 583
     public function detect_req_type()
584 584
     {
585
-        if (! $this->_req_type) {
585
+        if ( ! $this->_req_type) {
586 586
             $this->detect_activation_or_upgrade();
587 587
         }
588 588
         return $this->_req_type;
@@ -649,7 +649,7 @@  discard block
 block discarded – undo
649 649
      */
650 650
     public function update_list_of_installed_versions($version_history = null, $current_version_to_add = null)
651 651
     {
652
-        if (! $version_history) {
652
+        if ( ! $version_history) {
653 653
             $version_history = $this->get_activation_history();
654 654
         }
655 655
         if ($current_version_to_add === null) {
@@ -669,7 +669,7 @@  discard block
 block discarded – undo
669 669
      */
670 670
     public function get_activation_history_option_name()
671 671
     {
672
-        return self::ee_addon_version_history_option_prefix . $this->name();
672
+        return self::ee_addon_version_history_option_prefix.$this->name();
673 673
     }
674 674
 
675 675
 
@@ -744,7 +744,7 @@  discard block
 block discarded – undo
744 744
         // is admin and not in M-Mode ?
745 745
         if (is_admin() && ! EE_Maintenance_Mode::instance()->level()) {
746 746
             add_filter('plugin_action_links', array($this, 'plugin_action_links'), 10, 2);
747
-            add_filter('after_plugin_row_' . $this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
747
+            add_filter('after_plugin_row_'.$this->_plugin_basename, array($this, 'after_plugin_row'), 10, 3);
748 748
         }
749 749
     }
750 750
 
@@ -763,7 +763,7 @@  discard block
 block discarded – undo
763 763
             // before other links
764 764
             array_unshift(
765 765
                 $links,
766
-                '<a href="admin.php?page=' . $this->plugin_action_slug() . '">'
766
+                '<a href="admin.php?page='.$this->plugin_action_slug().'">'
767 767
                 . esc_html__('Settings', 'event_espresso')
768 768
                 . '</a>'
769 769
             );
@@ -786,15 +786,15 @@  discard block
 block discarded – undo
786 786
     {
787 787
         $after_plugin_row = '';
788 788
         $plugins_page_row = $this->get_plugins_page_row();
789
-        if (! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
789
+        if ( ! empty($plugins_page_row) && $plugin_file === $this->plugin_basename()) {
790 790
             $class            = $status ? 'active' : 'inactive';
791 791
             $link_text        = isset($plugins_page_row['link_text']) ? $plugins_page_row['link_text'] : '';
792 792
             $link_url         = isset($plugins_page_row['link_url']) ? $plugins_page_row['link_url'] : '';
793 793
             $description      = isset($plugins_page_row['description'])
794 794
                 ? $plugins_page_row['description']
795 795
                 : '';
796
-            if (! empty($link_text) && ! empty($link_url) && ! empty($description)) {
797
-                $after_plugin_row .= '<tr id="' . sanitize_title($plugin_file) . '-ee-addon" class="' . $class . '">';
796
+            if ( ! empty($link_text) && ! empty($link_url) && ! empty($description)) {
797
+                $after_plugin_row .= '<tr id="'.sanitize_title($plugin_file).'-ee-addon" class="'.$class.'">';
798 798
                 $after_plugin_row .= '<th class="check-column" scope="row"></th>';
799 799
                 $after_plugin_row .= '<td class="ee-addon-upsell-info-title-td plugin-title column-primary">';
800 800
                 $after_plugin_row .= '<style>
@@ -836,7 +836,7 @@  discard block
 block discarded – undo
836 836
 </style>';
837 837
                 $after_plugin_row .= '
838 838
 <p class="ee-addon-upsell-info-dv">
839
-	<a class="ee-button" href="' . $link_url . '">'
839
+	<a class="ee-button" href="' . $link_url.'">'
840 840
                 . $link_text
841 841
                 . ' &nbsp;<span class="dashicons dashicons-arrow-right-alt2" style="margin:0;"></span>'
842 842
                 . '</a>
Please login to merge, or discard this patch.
core/domain/RequiresDomainInterface.php 1 patch
Indentation   +8 added lines, -8 removed lines patch added patch discarded remove patch
@@ -18,16 +18,16 @@
 block discarded – undo
18 18
 interface RequiresDomainInterface
19 19
 {
20 20
 
21
-    /**
22
-     * @param DomainInterface $domain
23
-     */
24
-    public function setDomain(DomainInterface $domain);
21
+	/**
22
+	 * @param DomainInterface $domain
23
+	 */
24
+	public function setDomain(DomainInterface $domain);
25 25
 
26 26
 
27
-    /**
28
-     * @return DomainInterface
29
-     */
30
-    public function domain();
27
+	/**
28
+	 * @return DomainInterface
29
+	 */
30
+	public function domain();
31 31
 
32 32
 }
33 33
 // Location: RequiresDomainInterface.php
Please login to merge, or discard this patch.
core/EE_Session.core.php 3 patches
Doc Comments   +5 added lines, -5 removed lines patch added patch discarded remove patch
@@ -484,7 +484,7 @@  discard block
 block discarded – undo
484 484
      *
485 485
      * @access    public
486 486
      * @param    array $data
487
-     * @return    TRUE on success, FALSE on fail
487
+     * @return    boolean on success, FALSE on fail
488 488
      */
489 489
     public function set_session_data($data)
490 490
     {
@@ -511,7 +511,7 @@  discard block
 block discarded – undo
511 511
     /**
512 512
      * @initiate session
513 513
      * @access   private
514
-     * @return TRUE on success, FALSE on fail
514
+     * @return boolean on success, FALSE on fail
515 515
      * @throws EE_Error
516 516
      * @throws InvalidArgumentException
517 517
      * @throws InvalidDataTypeException
@@ -746,7 +746,7 @@  discard block
 block discarded – undo
746 746
      * @update session data  prior to saving to the db
747 747
      * @access public
748 748
      * @param bool $new_session
749
-     * @return TRUE on success, FALSE on fail
749
+     * @return boolean on success, FALSE on fail
750 750
      * @throws EE_Error
751 751
      * @throws InvalidArgumentException
752 752
      * @throws InvalidDataTypeException
@@ -847,7 +847,7 @@  discard block
 block discarded – undo
847 847
      * _save_session_to_db
848 848
      *
849 849
      * @param bool $clear_session
850
-     * @return string
850
+     * @return boolean
851 851
      * @throws EE_Error
852 852
      * @throws InvalidArgumentException
853 853
      * @throws InvalidDataTypeException
@@ -1008,7 +1008,7 @@  discard block
 block discarded – undo
1008 1008
      * @access public
1009 1009
      * @param array|mixed $data_to_reset
1010 1010
      * @param bool        $show_all_notices
1011
-     * @return TRUE on success, FALSE on fail
1011
+     * @return boolean on success, FALSE on fail
1012 1012
      */
1013 1013
     public function reset_data($data_to_reset = array(), $show_all_notices = false)
1014 1014
     {
Please login to merge, or discard this patch.
Indentation   +1204 added lines, -1204 removed lines patch added patch discarded remove patch
@@ -20,1210 +20,1210 @@  discard block
 block discarded – undo
20 20
 class EE_Session implements SessionIdentifierInterface
21 21
 {
22 22
 
23
-    const session_id_prefix    = 'ee_ssn_';
24
-
25
-    const hash_check_prefix    = 'ee_shc_';
26
-
27
-    const OPTION_NAME_SETTINGS = 'ee_session_settings';
28
-
29
-    /**
30
-     * instance of the EE_Session object
31
-     *
32
-     * @var EE_Session
33
-     */
34
-    private static $_instance;
35
-
36
-    /**
37
-     * @var CacheStorageInterface $cache_storage
38
-     */
39
-    protected $cache_storage;
40
-
41
-    /**
42
-     * EE_Encryption object
43
-     *
44
-     * @var EE_Encryption
45
-     */
46
-    protected $encryption;
47
-
48
-    /**
49
-     * the session id
50
-     *
51
-     * @var string
52
-     */
53
-    private $_sid;
54
-
55
-    /**
56
-     * session id salt
57
-     *
58
-     * @var string
59
-     */
60
-    private $_sid_salt;
61
-
62
-    /**
63
-     * session data
64
-     *
65
-     * @var array
66
-     */
67
-    private $_session_data = array();
68
-
69
-    /**
70
-     * how long an EE session lasts
71
-     * default session lifespan of 2 hours (for not so instant IPNs)
72
-     *
73
-     * @var int
74
-     */
75
-    private $_lifespan;
76
-
77
-    /**
78
-     * session expiration time as Unix timestamp in GMT
79
-     *
80
-     * @var int
81
-     */
82
-    private $_expiration;
83
-
84
-    /**
85
-     * whether or not session has expired at some point
86
-     *
87
-     * @var boolean
88
-     */
89
-    private $_expired = false;
90
-
91
-    /**
92
-     * current time as Unix timestamp in GMT
93
-     *
94
-     * @var int
95
-     */
96
-    private $_time;
97
-
98
-    /**
99
-     * whether to encrypt session data
100
-     *
101
-     * @var bool
102
-     */
103
-    private $_use_encryption;
104
-
105
-    /**
106
-     * well... according to the server...
107
-     *
108
-     * @var null
109
-     */
110
-    private $_user_agent;
111
-
112
-    /**
113
-     * do you really trust the server ?
114
-     *
115
-     * @var null
116
-     */
117
-    private $_ip_address;
118
-
119
-    /**
120
-     * current WP user_id
121
-     *
122
-     * @var null
123
-     */
124
-    private $_wp_user_id;
125
-
126
-    /**
127
-     * array for defining default session vars
128
-     *
129
-     * @var array
130
-     */
131
-    private $_default_session_vars = array(
132
-        'id'            => null,
133
-        'user_id'       => null,
134
-        'ip_address'    => null,
135
-        'user_agent'    => null,
136
-        'init_access'   => null,
137
-        'last_access'   => null,
138
-        'expiration'    => null,
139
-        'pages_visited' => array(),
140
-    );
141
-
142
-    /**
143
-     * timestamp for when last garbage collection cycle was performed
144
-     *
145
-     * @var int $_last_gc
146
-     */
147
-    private $_last_gc;
148
-
149
-
150
-
151
-    /**
152
-     * @singleton method used to instantiate class object
153
-     * @param CacheStorageInterface $cache_storage
154
-     * @param EE_Encryption         $encryption
155
-     * @return EE_Session
156
-     * @throws InvalidArgumentException
157
-     * @throws InvalidDataTypeException
158
-     * @throws InvalidInterfaceException
159
-     */
160
-    public static function instance(
161
-        CacheStorageInterface $cache_storage = null,
162
-        EE_Encryption $encryption = null
163
-    ) {
164
-        // check if class object is instantiated
165
-        // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
166
-        // add_filter( 'FHEE_load_EE_Session', '__return_false' );
167
-        if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
168
-            self::$_instance = new self($cache_storage, $encryption);
169
-        }
170
-        return self::$_instance;
171
-    }
172
-
173
-
174
-
175
-    /**
176
-     * protected constructor to prevent direct creation
177
-     *
178
-     * @param CacheStorageInterface $cache_storage
179
-     * @param EE_Encryption         $encryption
180
-     * @throws InvalidArgumentException
181
-     * @throws InvalidDataTypeException
182
-     * @throws InvalidInterfaceException
183
-     */
184
-    protected function __construct(CacheStorageInterface $cache_storage, EE_Encryption $encryption = null)
185
-    {
186
-
187
-        // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
188
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
189
-            return;
190
-        }
191
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
192
-        if (! defined('ESPRESSO_SESSION')) {
193
-            define('ESPRESSO_SESSION', true);
194
-        }
195
-        // default session lifespan in seconds
196
-        $this->_lifespan = apply_filters(
197
-                               'FHEE__EE_Session__construct___lifespan',
198
-                               60 * MINUTE_IN_SECONDS
199
-                           ) + 1;
200
-        /*
23
+	const session_id_prefix    = 'ee_ssn_';
24
+
25
+	const hash_check_prefix    = 'ee_shc_';
26
+
27
+	const OPTION_NAME_SETTINGS = 'ee_session_settings';
28
+
29
+	/**
30
+	 * instance of the EE_Session object
31
+	 *
32
+	 * @var EE_Session
33
+	 */
34
+	private static $_instance;
35
+
36
+	/**
37
+	 * @var CacheStorageInterface $cache_storage
38
+	 */
39
+	protected $cache_storage;
40
+
41
+	/**
42
+	 * EE_Encryption object
43
+	 *
44
+	 * @var EE_Encryption
45
+	 */
46
+	protected $encryption;
47
+
48
+	/**
49
+	 * the session id
50
+	 *
51
+	 * @var string
52
+	 */
53
+	private $_sid;
54
+
55
+	/**
56
+	 * session id salt
57
+	 *
58
+	 * @var string
59
+	 */
60
+	private $_sid_salt;
61
+
62
+	/**
63
+	 * session data
64
+	 *
65
+	 * @var array
66
+	 */
67
+	private $_session_data = array();
68
+
69
+	/**
70
+	 * how long an EE session lasts
71
+	 * default session lifespan of 2 hours (for not so instant IPNs)
72
+	 *
73
+	 * @var int
74
+	 */
75
+	private $_lifespan;
76
+
77
+	/**
78
+	 * session expiration time as Unix timestamp in GMT
79
+	 *
80
+	 * @var int
81
+	 */
82
+	private $_expiration;
83
+
84
+	/**
85
+	 * whether or not session has expired at some point
86
+	 *
87
+	 * @var boolean
88
+	 */
89
+	private $_expired = false;
90
+
91
+	/**
92
+	 * current time as Unix timestamp in GMT
93
+	 *
94
+	 * @var int
95
+	 */
96
+	private $_time;
97
+
98
+	/**
99
+	 * whether to encrypt session data
100
+	 *
101
+	 * @var bool
102
+	 */
103
+	private $_use_encryption;
104
+
105
+	/**
106
+	 * well... according to the server...
107
+	 *
108
+	 * @var null
109
+	 */
110
+	private $_user_agent;
111
+
112
+	/**
113
+	 * do you really trust the server ?
114
+	 *
115
+	 * @var null
116
+	 */
117
+	private $_ip_address;
118
+
119
+	/**
120
+	 * current WP user_id
121
+	 *
122
+	 * @var null
123
+	 */
124
+	private $_wp_user_id;
125
+
126
+	/**
127
+	 * array for defining default session vars
128
+	 *
129
+	 * @var array
130
+	 */
131
+	private $_default_session_vars = array(
132
+		'id'            => null,
133
+		'user_id'       => null,
134
+		'ip_address'    => null,
135
+		'user_agent'    => null,
136
+		'init_access'   => null,
137
+		'last_access'   => null,
138
+		'expiration'    => null,
139
+		'pages_visited' => array(),
140
+	);
141
+
142
+	/**
143
+	 * timestamp for when last garbage collection cycle was performed
144
+	 *
145
+	 * @var int $_last_gc
146
+	 */
147
+	private $_last_gc;
148
+
149
+
150
+
151
+	/**
152
+	 * @singleton method used to instantiate class object
153
+	 * @param CacheStorageInterface $cache_storage
154
+	 * @param EE_Encryption         $encryption
155
+	 * @return EE_Session
156
+	 * @throws InvalidArgumentException
157
+	 * @throws InvalidDataTypeException
158
+	 * @throws InvalidInterfaceException
159
+	 */
160
+	public static function instance(
161
+		CacheStorageInterface $cache_storage = null,
162
+		EE_Encryption $encryption = null
163
+	) {
164
+		// check if class object is instantiated
165
+		// session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
166
+		// add_filter( 'FHEE_load_EE_Session', '__return_false' );
167
+		if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
168
+			self::$_instance = new self($cache_storage, $encryption);
169
+		}
170
+		return self::$_instance;
171
+	}
172
+
173
+
174
+
175
+	/**
176
+	 * protected constructor to prevent direct creation
177
+	 *
178
+	 * @param CacheStorageInterface $cache_storage
179
+	 * @param EE_Encryption         $encryption
180
+	 * @throws InvalidArgumentException
181
+	 * @throws InvalidDataTypeException
182
+	 * @throws InvalidInterfaceException
183
+	 */
184
+	protected function __construct(CacheStorageInterface $cache_storage, EE_Encryption $encryption = null)
185
+	{
186
+
187
+		// session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
188
+		if (! apply_filters('FHEE_load_EE_Session', true)) {
189
+			return;
190
+		}
191
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
192
+		if (! defined('ESPRESSO_SESSION')) {
193
+			define('ESPRESSO_SESSION', true);
194
+		}
195
+		// default session lifespan in seconds
196
+		$this->_lifespan = apply_filters(
197
+							   'FHEE__EE_Session__construct___lifespan',
198
+							   60 * MINUTE_IN_SECONDS
199
+						   ) + 1;
200
+		/*
201 201
          * do something like the following to adjust the session lifespan:
202 202
          * 		public static function session_lifespan() {
203 203
          * 			return 15 * MINUTE_IN_SECONDS;
204 204
          * 		}
205 205
          */
206
-        // retrieve session options from db
207
-        $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
208
-        if (! empty($session_settings)) {
209
-            // cycle though existing session options
210
-            foreach ($session_settings as $var_name => $session_setting) {
211
-                // set values for class properties
212
-                $var_name          = '_' . $var_name;
213
-                $this->{$var_name} = $session_setting;
214
-            }
215
-        }
216
-        $this->cache_storage = $cache_storage;
217
-        // are we using encryption?
218
-        $this->_use_encryption = $encryption instanceof EE_Encryption
219
-                                 && EE_Registry::instance()->CFG->admin->encode_session_data();
220
-        // \EEH_Debug_Tools::printr($this->_use_encryption, '$this->_use_encryption', __FILE__, __LINE__);
221
-        // encrypt data via: $this->encryption->encrypt();
222
-        $this->encryption = $encryption;
223
-        // filter hook allows outside functions/classes/plugins to change default empty cart
224
-        $extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
225
-        array_merge($this->_default_session_vars, $extra_default_session_vars);
226
-        // apply default session vars
227
-        $this->_set_defaults();
228
-        add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
229
-        // check request for 'clear_session' param
230
-        add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
231
-        // once everything is all said and done,
232
-        add_action('shutdown', array($this, 'update'), 100);
233
-        add_action('shutdown', array($this, 'garbageCollection'), 1000);
234
-        $this->configure_garbage_collection_filters();
235
-    }
236
-
237
-
238
-
239
-    /**
240
-     * @return void
241
-     * @throws EE_Error
242
-     * @throws InvalidArgumentException
243
-     * @throws InvalidDataTypeException
244
-     * @throws InvalidInterfaceException
245
-     * @throws InvalidSessionDataException
246
-     */
247
-    public function open_session()
248
-    {
249
-        // check for existing session and retrieve it from db
250
-        if (! $this->_espresso_session()) {
251
-            // or just start a new one
252
-            $this->_create_espresso_session();
253
-        }
254
-    }
255
-
256
-
257
-
258
-    /**
259
-     * @return bool
260
-     */
261
-    public function expired()
262
-    {
263
-        return $this->_expired;
264
-    }
265
-
266
-
267
-
268
-    /**
269
-     * @return void
270
-     */
271
-    public function reset_expired()
272
-    {
273
-        $this->_expired = false;
274
-    }
275
-
276
-
277
-    /**
278
-     * @return int
279
-     */
280
-    public function expiration()
281
-    {
282
-        return $this->_expiration;
283
-    }
284
-
285
-
286
-
287
-    /**
288
-     * @return int
289
-     */
290
-    public function extension()
291
-    {
292
-        return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
293
-    }
294
-
295
-
296
-
297
-    /**
298
-     * @param int $time number of seconds to add to session expiration
299
-     */
300
-    public function extend_expiration($time = 0)
301
-    {
302
-        $time              = $time ? $time : $this->extension();
303
-        $this->_expiration += absint($time);
304
-    }
305
-
306
-
307
-
308
-    /**
309
-     * @return int
310
-     */
311
-    public function lifespan()
312
-    {
313
-        return $this->_lifespan;
314
-    }
315
-
316
-
317
-
318
-    /**
319
-     * This just sets some defaults for the _session data property
320
-     *
321
-     * @access private
322
-     * @return void
323
-     */
324
-    private function _set_defaults()
325
-    {
326
-        // set some defaults
327
-        foreach ($this->_default_session_vars as $key => $default_var) {
328
-            if (is_array($default_var)) {
329
-                $this->_session_data[ $key ] = array();
330
-            } else {
331
-                $this->_session_data[ $key ] = '';
332
-            }
333
-        }
334
-    }
206
+		// retrieve session options from db
207
+		$session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
208
+		if (! empty($session_settings)) {
209
+			// cycle though existing session options
210
+			foreach ($session_settings as $var_name => $session_setting) {
211
+				// set values for class properties
212
+				$var_name          = '_' . $var_name;
213
+				$this->{$var_name} = $session_setting;
214
+			}
215
+		}
216
+		$this->cache_storage = $cache_storage;
217
+		// are we using encryption?
218
+		$this->_use_encryption = $encryption instanceof EE_Encryption
219
+								 && EE_Registry::instance()->CFG->admin->encode_session_data();
220
+		// \EEH_Debug_Tools::printr($this->_use_encryption, '$this->_use_encryption', __FILE__, __LINE__);
221
+		// encrypt data via: $this->encryption->encrypt();
222
+		$this->encryption = $encryption;
223
+		// filter hook allows outside functions/classes/plugins to change default empty cart
224
+		$extra_default_session_vars = apply_filters('FHEE__EE_Session__construct__extra_default_session_vars', array());
225
+		array_merge($this->_default_session_vars, $extra_default_session_vars);
226
+		// apply default session vars
227
+		$this->_set_defaults();
228
+		add_action('AHEE__EE_System__initialize', array($this, 'open_session'));
229
+		// check request for 'clear_session' param
230
+		add_action('AHEE__EE_Request_Handler__construct__complete', array($this, 'wp_loaded'));
231
+		// once everything is all said and done,
232
+		add_action('shutdown', array($this, 'update'), 100);
233
+		add_action('shutdown', array($this, 'garbageCollection'), 1000);
234
+		$this->configure_garbage_collection_filters();
235
+	}
236
+
237
+
238
+
239
+	/**
240
+	 * @return void
241
+	 * @throws EE_Error
242
+	 * @throws InvalidArgumentException
243
+	 * @throws InvalidDataTypeException
244
+	 * @throws InvalidInterfaceException
245
+	 * @throws InvalidSessionDataException
246
+	 */
247
+	public function open_session()
248
+	{
249
+		// check for existing session and retrieve it from db
250
+		if (! $this->_espresso_session()) {
251
+			// or just start a new one
252
+			$this->_create_espresso_session();
253
+		}
254
+	}
255
+
256
+
257
+
258
+	/**
259
+	 * @return bool
260
+	 */
261
+	public function expired()
262
+	{
263
+		return $this->_expired;
264
+	}
265
+
266
+
267
+
268
+	/**
269
+	 * @return void
270
+	 */
271
+	public function reset_expired()
272
+	{
273
+		$this->_expired = false;
274
+	}
275
+
276
+
277
+	/**
278
+	 * @return int
279
+	 */
280
+	public function expiration()
281
+	{
282
+		return $this->_expiration;
283
+	}
284
+
285
+
286
+
287
+	/**
288
+	 * @return int
289
+	 */
290
+	public function extension()
291
+	{
292
+		return apply_filters('FHEE__EE_Session__extend_expiration__seconds_added', 10 * MINUTE_IN_SECONDS);
293
+	}
294
+
295
+
296
+
297
+	/**
298
+	 * @param int $time number of seconds to add to session expiration
299
+	 */
300
+	public function extend_expiration($time = 0)
301
+	{
302
+		$time              = $time ? $time : $this->extension();
303
+		$this->_expiration += absint($time);
304
+	}
305
+
306
+
307
+
308
+	/**
309
+	 * @return int
310
+	 */
311
+	public function lifespan()
312
+	{
313
+		return $this->_lifespan;
314
+	}
315
+
316
+
317
+
318
+	/**
319
+	 * This just sets some defaults for the _session data property
320
+	 *
321
+	 * @access private
322
+	 * @return void
323
+	 */
324
+	private function _set_defaults()
325
+	{
326
+		// set some defaults
327
+		foreach ($this->_default_session_vars as $key => $default_var) {
328
+			if (is_array($default_var)) {
329
+				$this->_session_data[ $key ] = array();
330
+			} else {
331
+				$this->_session_data[ $key ] = '';
332
+			}
333
+		}
334
+	}
335 335
 
336 336
 
337
-
338
-    /**
339
-     * @retrieve  session data
340
-     * @access    public
341
-     * @return    string
342
-     */
343
-    public function id()
344
-    {
345
-        return $this->_sid;
346
-    }
337
+
338
+	/**
339
+	 * @retrieve  session data
340
+	 * @access    public
341
+	 * @return    string
342
+	 */
343
+	public function id()
344
+	{
345
+		return $this->_sid;
346
+	}
347 347
 
348 348
 
349 349
 
350
-    /**
351
-     * @param \EE_Cart $cart
352
-     * @return bool
353
-     */
354
-    public function set_cart(EE_Cart $cart)
355
-    {
356
-        $this->_session_data['cart'] = $cart;
357
-        return true;
358
-    }
350
+	/**
351
+	 * @param \EE_Cart $cart
352
+	 * @return bool
353
+	 */
354
+	public function set_cart(EE_Cart $cart)
355
+	{
356
+		$this->_session_data['cart'] = $cart;
357
+		return true;
358
+	}
359 359
 
360 360
 
361 361
 
362
-    /**
363
-     * reset_cart
364
-     */
365
-    public function reset_cart()
366
-    {
367
-        do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
368
-        $this->_session_data['cart'] = null;
369
-    }
370
-
371
-
372
-
373
-    /**
374
-     * @return \EE_Cart
375
-     */
376
-    public function cart()
377
-    {
378
-        return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
379
-            ? $this->_session_data['cart']
380
-            : null;
381
-    }
382
-
383
-
384
-
385
-    /**
386
-     * @param \EE_Checkout $checkout
387
-     * @return bool
388
-     */
389
-    public function set_checkout(EE_Checkout $checkout)
390
-    {
391
-        $this->_session_data['checkout'] = $checkout;
392
-        return true;
393
-    }
394
-
395
-
396
-
397
-    /**
398
-     * reset_checkout
399
-     */
400
-    public function reset_checkout()
401
-    {
402
-        do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
403
-        $this->_session_data['checkout'] = null;
404
-    }
405
-
406
-
407
-
408
-    /**
409
-     * @return \EE_Checkout
410
-     */
411
-    public function checkout()
412
-    {
413
-        return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
414
-            ? $this->_session_data['checkout']
415
-            : null;
416
-    }
417
-
418
-
419
-
420
-    /**
421
-     * @param \EE_Transaction $transaction
422
-     * @return bool
423
-     * @throws EE_Error
424
-     */
425
-    public function set_transaction(EE_Transaction $transaction)
426
-    {
427
-        // first remove the session from the transaction before we save the transaction in the session
428
-        $transaction->set_txn_session_data(null);
429
-        $this->_session_data['transaction'] = $transaction;
430
-        return true;
431
-    }
432
-
433
-
434
-
435
-    /**
436
-     * reset_transaction
437
-     */
438
-    public function reset_transaction()
439
-    {
440
-        do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
441
-        $this->_session_data['transaction'] = null;
442
-    }
443
-
444
-
445
-
446
-    /**
447
-     * @return \EE_Transaction
448
-     */
449
-    public function transaction()
450
-    {
451
-        return isset($this->_session_data['transaction'])
452
-               && $this->_session_data['transaction'] instanceof EE_Transaction
453
-            ? $this->_session_data['transaction']
454
-            : null;
455
-    }
456
-
457
-
458
-
459
-    /**
460
-     * retrieve session data
461
-     *
462
-     * @access    public
463
-     * @param null $key
464
-     * @param bool $reset_cache
465
-     * @return    array
466
-     */
467
-    public function get_session_data($key = null, $reset_cache = false)
468
-    {
469
-        if ($reset_cache) {
470
-            $this->reset_cart();
471
-            $this->reset_checkout();
472
-            $this->reset_transaction();
473
-        }
474
-        if (! empty($key)) {
475
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
476
-        }
477
-        return $this->_session_data;
478
-    }
479
-
480
-
481
-
482
-    /**
483
-     * set session data
484
-     *
485
-     * @access    public
486
-     * @param    array $data
487
-     * @return    TRUE on success, FALSE on fail
488
-     */
489
-    public function set_session_data($data)
490
-    {
491
-
492
-        // nothing ??? bad data ??? go home!
493
-        if (empty($data) || ! is_array($data)) {
494
-            EE_Error::add_error(__('No session data or invalid session data was provided.', 'event_espresso'), __FILE__,
495
-                __FUNCTION__, __LINE__);
496
-            return false;
497
-        }
498
-        foreach ($data as $key => $value) {
499
-            if (isset($this->_default_session_vars[ $key ])) {
500
-                EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
501
-                    'event_espresso'), $key), __FILE__, __FUNCTION__, __LINE__);
502
-                return false;
503
-            }
504
-            $this->_session_data[ $key ] = $value;
505
-        }
506
-        return true;
507
-    }
508
-
509
-
510
-
511
-    /**
512
-     * @initiate session
513
-     * @access   private
514
-     * @return TRUE on success, FALSE on fail
515
-     * @throws EE_Error
516
-     * @throws InvalidArgumentException
517
-     * @throws InvalidDataTypeException
518
-     * @throws InvalidInterfaceException
519
-     * @throws InvalidSessionDataException
520
-     */
521
-    private function _espresso_session()
522
-    {
523
-        do_action('AHEE_log', __FILE__, __FUNCTION__, '');
524
-        // check that session has started
525
-        if (session_id() === '') {
526
-            //starts a new session if one doesn't already exist, or re-initiates an existing one
527
-            session_start();
528
-        }
529
-        // get our modified session ID
530
-        $this->_sid = $this->_generate_session_id();
531
-        // and the visitors IP
532
-        $this->_ip_address = $this->_visitor_ip();
533
-        // set the "user agent"
534
-        $this->_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? esc_attr($_SERVER['HTTP_USER_AGENT']) : false;
535
-        // now let's retrieve what's in the db
536
-        $session_data = $this->_retrieve_session_data();
537
-        if (! empty($session_data)) {
538
-            // get the current time in UTC
539
-            $this->_time = $this->_time !== null ? $this->_time : time();
540
-            // and reset the session expiration
541
-            $this->_expiration = isset($session_data['expiration'])
542
-                ? $session_data['expiration']
543
-                : $this->_time + $this->_lifespan;
544
-        } else {
545
-            // set initial site access time and the session expiration
546
-            $this->_set_init_access_and_expiration();
547
-            // set referer
548
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
549
-                ? esc_attr($_SERVER['HTTP_REFERER'])
550
-                : '';
551
-            // no previous session = go back and create one (on top of the data above)
552
-            return false;
553
-        }
554
-        // now the user agent
555
-        if ($session_data['user_agent'] !== $this->_user_agent) {
556
-            return false;
557
-        }
558
-        // wait a minute... how old are you?
559
-        if ($this->_time > $this->_expiration) {
560
-            // yer too old fer me!
561
-            $this->_expired = true;
562
-            // wipe out everything that isn't a default session datum
563
-            $this->clear_session(__CLASS__, __FUNCTION__);
564
-        }
565
-        // make event espresso session data available to plugin
566
-        $this->_session_data = array_merge($this->_session_data, $session_data);
567
-        return true;
568
-    }
569
-
570
-
571
-
572
-    /**
573
-     * _get_session_data
574
-     * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
575
-     * databases
576
-     *
577
-     * @return array
578
-     * @throws EE_Error
579
-     * @throws InvalidArgumentException
580
-     * @throws InvalidSessionDataException
581
-     * @throws InvalidDataTypeException
582
-     * @throws InvalidInterfaceException
583
-     */
584
-    protected function _retrieve_session_data()
585
-    {
586
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
587
-        try {
588
-            // we're using WP's Transient API to store session data using the PHP session ID as the option name
589
-            $session_data = $this->cache_storage->get($ssn_key, false);
590
-            if (empty($session_data)) {
591
-                return array();
592
-            }
593
-            if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
594
-                $hash_check = $this->cache_storage->get(
595
-                    EE_Session::hash_check_prefix . $this->_sid,
596
-                    false
597
-                );
598
-                if ($hash_check && $hash_check !== md5($session_data)) {
599
-                    EE_Error::add_error(
600
-                        sprintf(
601
-                            __(
602
-                                'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
603
-                                'event_espresso'
604
-                            ),
605
-                            EE_Session::session_id_prefix . $this->_sid
606
-                        ),
607
-                        __FILE__, __FUNCTION__, __LINE__
608
-                    );
609
-                }
610
-            }
611
-        } catch (Exception $e) {
612
-            // let's just eat that error for now and attempt to correct any corrupted data
613
-            global $wpdb;
614
-            $row          = $wpdb->get_row(
615
-                $wpdb->prepare(
616
-                    "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
617
-                    '_transient_' . $ssn_key
618
-                )
619
-            );
620
-            $session_data = is_object($row) ? $row->option_value : null;
621
-            if ($session_data) {
622
-                $session_data = preg_replace_callback(
623
-                    '!s:(d+):"(.*?)";!',
624
-                    function ($match)
625
-                    {
626
-                        return $match[1] === strlen($match[2])
627
-                            ? $match[0]
628
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
629
-                    },
630
-                    $session_data
631
-                );
632
-            }
633
-            $session_data = maybe_unserialize($session_data);
634
-        }
635
-        // in case the data is encoded... try to decode it
636
-        $session_data = $this->encryption instanceof EE_Encryption
637
-            ? $this->encryption->base64_string_decode($session_data)
638
-            : $session_data;
639
-        if (! is_array($session_data)) {
640
-            try {
641
-                $session_data = maybe_unserialize($session_data);
642
-            } catch (Exception $e) {
643
-                $msg = esc_html__(
644
-                    'An error occurred while attempting to unserialize the session data.',
645
-                    'event_espresso'
646
-                );
647
-                $msg .= WP_DEBUG
648
-                    ? '<br><pre>'
649
-                      . print_r($session_data, true)
650
-                      . '</pre><br>'
651
-                      . $this->find_serialize_error($session_data)
652
-                    : '';
653
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
654
-                throw new InvalidSessionDataException($msg, 0, $e);
655
-            }
656
-        }
657
-        // just a check to make sure the session array is indeed an array
658
-        if (! is_array($session_data)) {
659
-            // no?!?! then something is wrong
660
-            $msg = esc_html__(
661
-                'The session data is missing, invalid, or corrupted.',
662
-                'event_espresso'
663
-            );
664
-            $msg .= WP_DEBUG
665
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
666
-                : '';
667
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
668
-            throw new InvalidSessionDataException($msg);
669
-        }
670
-        if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
671
-            $session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
672
-                $session_data['transaction']
673
-            );
674
-        }
675
-        return $session_data;
676
-    }
677
-
678
-
679
-
680
-    /**
681
-     * _generate_session_id
682
-     * Retrieves the PHP session id either directly from the PHP session,
683
-     * or from the $_REQUEST array if it was passed in from an AJAX request.
684
-     * The session id is then salted and hashed (mmm sounds tasty)
685
-     * so that it can be safely used as a $_REQUEST param
686
-     *
687
-     * @return string
688
-     */
689
-    protected function _generate_session_id()
690
-    {
691
-        // check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
692
-        if (isset($_REQUEST['EESID'])) {
693
-            $session_id = sanitize_text_field($_REQUEST['EESID']);
694
-        } else {
695
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
696
-        }
697
-        return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
698
-    }
699
-
700
-
701
-
702
-    /**
703
-     * _get_sid_salt
704
-     *
705
-     * @return string
706
-     */
707
-    protected function _get_sid_salt()
708
-    {
709
-        // was session id salt already saved to db ?
710
-        if (empty($this->_sid_salt)) {
711
-            // no?  then maybe use WP defined constant
712
-            if (defined('AUTH_SALT')) {
713
-                $this->_sid_salt = AUTH_SALT;
714
-            }
715
-            // if salt doesn't exist or is too short
716
-            if (strlen($this->_sid_salt) < 32) {
717
-                // create a new one
718
-                $this->_sid_salt = wp_generate_password(64);
719
-            }
720
-            // and save it as a permanent session setting
721
-            $this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
722
-        }
723
-        return $this->_sid_salt;
724
-    }
725
-
726
-
727
-
728
-    /**
729
-     * _set_init_access_and_expiration
730
-     *
731
-     * @return void
732
-     */
733
-    protected function _set_init_access_and_expiration()
734
-    {
735
-        $this->_time       = time();
736
-        $this->_expiration = $this->_time + $this->_lifespan;
737
-        // set initial site access time
738
-        $this->_session_data['init_access'] = $this->_time;
739
-        // and the session expiration
740
-        $this->_session_data['expiration'] = $this->_expiration;
741
-    }
742
-
743
-
744
-
745
-    /**
746
-     * @update session data  prior to saving to the db
747
-     * @access public
748
-     * @param bool $new_session
749
-     * @return TRUE on success, FALSE on fail
750
-     * @throws EE_Error
751
-     * @throws InvalidArgumentException
752
-     * @throws InvalidDataTypeException
753
-     * @throws InvalidInterfaceException
754
-     */
755
-    public function update($new_session = false)
756
-    {
757
-        $this->_session_data = $this->_session_data !== null
758
-                               && is_array($this->_session_data)
759
-                               && isset($this->_session_data['id'])
760
-            ? $this->_session_data
761
-            : array();
762
-        if (empty($this->_session_data)) {
763
-            $this->_set_defaults();
764
-        }
765
-        $session_data = array();
766
-        foreach ($this->_session_data as $key => $value) {
767
-
768
-            switch ($key) {
769
-
770
-                case 'id' :
771
-                    // session ID
772
-                    $session_data['id'] = $this->_sid;
773
-                    break;
774
-                case 'ip_address' :
775
-                    // visitor ip address
776
-                    $session_data['ip_address'] = $this->_visitor_ip();
777
-                    break;
778
-                case 'user_agent' :
779
-                    // visitor user_agent
780
-                    $session_data['user_agent'] = $this->_user_agent;
781
-                    break;
782
-                case 'init_access' :
783
-                    $session_data['init_access'] = absint($value);
784
-                    break;
785
-                case 'last_access' :
786
-                    // current access time
787
-                    $session_data['last_access'] = $this->_time;
788
-                    break;
789
-                case 'expiration' :
790
-                    // when the session expires
791
-                    $session_data['expiration'] = ! empty($this->_expiration)
792
-                        ? $this->_expiration
793
-                        : $session_data['init_access'] + $this->_lifespan;
794
-                    break;
795
-                case 'user_id' :
796
-                    // current user if logged in
797
-                    $session_data['user_id'] = $this->_wp_user_id();
798
-                    break;
799
-                case 'pages_visited' :
800
-                    $page_visit = $this->_get_page_visit();
801
-                    if ($page_visit) {
802
-                        // set pages visited where the first will be the http referrer
803
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
804
-                        // we'll only save the last 10 page visits.
805
-                        $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
806
-                    }
807
-                    break;
808
-                default :
809
-                    // carry any other data over
810
-                    $session_data[ $key ] = $this->_session_data[ $key ];
811
-            }
812
-        }
813
-        $this->_session_data = $session_data;
814
-        // creating a new session does not require saving to the db just yet
815
-        if (! $new_session) {
816
-            // ready? let's save
817
-            if ($this->_save_session_to_db()) {
818
-                return true;
819
-            }
820
-            return false;
821
-        }
822
-        // meh, why not?
823
-        return true;
824
-    }
825
-
826
-
827
-
828
-    /**
829
-     * @create session data array
830
-     * @access public
831
-     * @return bool
832
-     * @throws EE_Error
833
-     * @throws InvalidArgumentException
834
-     * @throws InvalidDataTypeException
835
-     * @throws InvalidInterfaceException
836
-     */
837
-    private function _create_espresso_session()
838
-    {
839
-        do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
840
-        // use the update function for now with $new_session arg set to TRUE
841
-        return $this->update(true) ? true : false;
842
-    }
843
-
844
-
845
-
846
-    /**
847
-     * _save_session_to_db
848
-     *
849
-     * @param bool $clear_session
850
-     * @return string
851
-     * @throws EE_Error
852
-     * @throws InvalidArgumentException
853
-     * @throws InvalidDataTypeException
854
-     * @throws InvalidInterfaceException
855
-     */
856
-    private function _save_session_to_db($clear_session = false)
857
-    {
858
-        // unless we're deleting the session data, don't save anything if there isn't a cart
859
-        if (! $clear_session && ! $this->cart() instanceof EE_Cart) {
860
-            return false;
861
-        }
862
-        $transaction = $this->transaction();
863
-        if ($transaction instanceof EE_Transaction) {
864
-            if (! $transaction->ID()) {
865
-                $transaction->save();
866
-            }
867
-            $this->_session_data['transaction'] = $transaction->ID();
868
-        }
869
-        // then serialize all of our session data
870
-        $session_data = serialize($this->_session_data);
871
-        // do we need to also encode it to avoid corrupted data when saved to the db?
872
-        $session_data = $this->_use_encryption
873
-            ? $this->encryption->base64_string_encode($session_data)
874
-            : $session_data;
875
-        // maybe save hash check
876
-        if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
877
-            $this->cache_storage->add(
878
-                EE_Session::hash_check_prefix . $this->_sid,
879
-                md5($session_data),
880
-                $this->_lifespan
881
-            );
882
-        }
883
-        // we're using the Transient API for storing session data,
884
-        return $this->cache_storage->add(
885
-            EE_Session::session_id_prefix . $this->_sid,
886
-            $session_data,
887
-            $this->_lifespan
888
-        );
889
-    }
890
-
891
-
892
-
893
-    /**
894
-     * _visitor_ip
895
-     *    attempt to get IP address of current visitor from server
896
-     * plz see: http://stackoverflow.com/a/2031935/1475279
897
-     *
898
-     * @access public
899
-     * @return string
900
-     */
901
-    private function _visitor_ip()
902
-    {
903
-        $visitor_ip  = '0.0.0.0';
904
-        $server_keys = array(
905
-            'HTTP_CLIENT_IP',
906
-            'HTTP_X_FORWARDED_FOR',
907
-            'HTTP_X_FORWARDED',
908
-            'HTTP_X_CLUSTER_CLIENT_IP',
909
-            'HTTP_FORWARDED_FOR',
910
-            'HTTP_FORWARDED',
911
-            'REMOTE_ADDR',
912
-        );
913
-        foreach ($server_keys as $key) {
914
-            if (isset($_SERVER[ $key ])) {
915
-                foreach (array_map('trim', explode(',', $_SERVER[ $key ])) as $ip) {
916
-                    if ($ip === '127.0.0.1' || filter_var($ip, FILTER_VALIDATE_IP) !== false) {
917
-                        $visitor_ip = $ip;
918
-                    }
919
-                }
920
-            }
921
-        }
922
-        return $visitor_ip;
923
-    }
924
-
925
-
926
-
927
-    /**
928
-     * @get    the full page request the visitor is accessing
929
-     * @access public
930
-     * @return string
931
-     */
932
-    public function _get_page_visit()
933
-    {
934
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
935
-        // check for request url
936
-        if (isset($_SERVER['REQUEST_URI'])) {
937
-            $http_host   = '';
938
-            $page_id     = '?';
939
-            $e_reg       = '';
940
-            $request_uri = esc_url($_SERVER['REQUEST_URI']);
941
-            $ru_bits     = explode('?', $request_uri);
942
-            $request_uri = $ru_bits[0];
943
-            // check for and grab host as well
944
-            if (isset($_SERVER['HTTP_HOST'])) {
945
-                $http_host = esc_url($_SERVER['HTTP_HOST']);
946
-            }
947
-            // check for page_id in SERVER REQUEST
948
-            if (isset($_REQUEST['page_id'])) {
949
-                // rebuild $e_reg without any of the extra parameters
950
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
951
-            }
952
-            // check for $e_reg in SERVER REQUEST
953
-            if (isset($_REQUEST['ee'])) {
954
-                // rebuild $e_reg without any of the extra parameters
955
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
956
-            }
957
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
958
-        }
959
-        return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
960
-    }
961
-
962
-
963
-
964
-    /**
965
-     * @the    current wp user id
966
-     * @access public
967
-     * @return int
968
-     */
969
-    public function _wp_user_id()
970
-    {
971
-        // if I need to explain the following lines of code, then you shouldn't be looking at this!
972
-        $this->_wp_user_id = get_current_user_id();
973
-        return $this->_wp_user_id;
974
-    }
975
-
976
-
977
-
978
-    /**
979
-     * Clear EE_Session data
980
-     *
981
-     * @access public
982
-     * @param string $class
983
-     * @param string $function
984
-     * @return void
985
-     * @throws EE_Error
986
-     * @throws InvalidArgumentException
987
-     * @throws InvalidDataTypeException
988
-     * @throws InvalidInterfaceException
989
-     */
990
-    public function clear_session($class = '', $function = '')
991
-    {
992
-        //echo '<h3 style="color:#999;line-height:.9em;"><span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/><span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b></h3>';
993
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
994
-        $this->reset_cart();
995
-        $this->reset_checkout();
996
-        $this->reset_transaction();
997
-        // wipe out everything that isn't a default session datum
998
-        $this->reset_data(array_keys($this->_session_data));
999
-        // reset initial site access time and the session expiration
1000
-        $this->_set_init_access_and_expiration();
1001
-        $this->_save_session_to_db(true);
1002
-    }
1003
-
1004
-
1005
-
1006
-    /**
1007
-     * @resets all non-default session vars
1008
-     * @access public
1009
-     * @param array|mixed $data_to_reset
1010
-     * @param bool        $show_all_notices
1011
-     * @return TRUE on success, FALSE on fail
1012
-     */
1013
-    public function reset_data($data_to_reset = array(), $show_all_notices = false)
1014
-    {
1015
-        // if $data_to_reset is not in an array, then put it in one
1016
-        if (! is_array($data_to_reset)) {
1017
-            $data_to_reset = array($data_to_reset);
1018
-        }
1019
-        // nothing ??? go home!
1020
-        if (empty($data_to_reset)) {
1021
-            EE_Error::add_error(__('No session data could be reset, because no session var name was provided.',
1022
-                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1023
-            return false;
1024
-        }
1025
-        $return_value = true;
1026
-        // since $data_to_reset is an array, cycle through the values
1027
-        foreach ($data_to_reset as $reset) {
1028
-
1029
-            // first check to make sure it is a valid session var
1030
-            if (isset($this->_session_data[ $reset ])) {
1031
-                // then check to make sure it is not a default var
1032
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1033
-                    // remove session var
1034
-                    unset($this->_session_data[ $reset ]);
1035
-                    if ($show_all_notices) {
1036
-                        EE_Error::add_success(sprintf(__('The session variable %s was removed.', 'event_espresso'),
1037
-                            $reset), __FILE__, __FUNCTION__, __LINE__);
1038
-                    }
1039
-                } else {
1040
-                    // yeeeeeeeeerrrrrrrrrrr OUT !!!!
1041
-                    if ($show_all_notices) {
1042
-                        EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
1043
-                            'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1044
-                    }
1045
-                    $return_value = false;
1046
-                }
1047
-            } elseif ($show_all_notices) {
1048
-                // oops! that session var does not exist!
1049
-                EE_Error::add_error(sprintf(__('The session item provided, %s, is invalid or does not exist.',
1050
-                    'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1051
-                $return_value = false;
1052
-            }
1053
-        } // end of foreach
1054
-        return $return_value;
1055
-    }
1056
-
1057
-
1058
-
1059
-    /**
1060
-     *   wp_loaded
1061
-     *
1062
-     * @access public
1063
-     * @throws EE_Error
1064
-     * @throws InvalidDataTypeException
1065
-     * @throws InvalidInterfaceException
1066
-     * @throws InvalidArgumentException
1067
-     */
1068
-    public function wp_loaded()
1069
-    {
1070
-        if (
1071
-            EE_Registry::instance()->REQ instanceof EE_Request_Handler
1072
-            && EE_Registry::instance()->REQ->is_set('clear_session')
1073
-        ) {
1074
-            $this->clear_session(__CLASS__, __FUNCTION__);
1075
-        }
1076
-    }
1077
-
1078
-
1079
-
1080
-    /**
1081
-     * Used to reset the entire object (for tests).
1082
-     *
1083
-     * @since 4.3.0
1084
-     * @throws EE_Error
1085
-     * @throws InvalidDataTypeException
1086
-     * @throws InvalidInterfaceException
1087
-     * @throws InvalidArgumentException
1088
-     */
1089
-    public function reset_instance()
1090
-    {
1091
-        $this->clear_session();
1092
-        self::$_instance = null;
1093
-    }
1094
-
1095
-
1096
-
1097
-    public function configure_garbage_collection_filters()
1098
-    {
1099
-        // run old filter we had for controlling session cleanup
1100
-        $expired_session_transient_delete_query_limit = absint(
1101
-            apply_filters(
1102
-                'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1103
-                50
1104
-            )
1105
-        );
1106
-        // is there a value? or one that is different than the default 50 records?
1107
-        if ($expired_session_transient_delete_query_limit === 0) {
1108
-            // hook into TransientCacheStorage in case Session cleanup was turned off
1109
-            add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1110
-        } elseif ($expired_session_transient_delete_query_limit !== 50) {
1111
-            // or use that for the new transient cleanup query limit
1112
-            add_filter(
1113
-                'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1114
-                function () use ($expired_session_transient_delete_query_limit)
1115
-                {
1116
-                    return $expired_session_transient_delete_query_limit;
1117
-                }
1118
-            );
1119
-        }
1120
-    }
1121
-
1122
-
1123
-
1124
-    /**
1125
-     * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1126
-     * @param $data1
1127
-     * @return string
1128
-     */
1129
-    private function find_serialize_error($data1)
1130
-    {
1131
-        $error = '<pre>';
1132
-        $data2 = preg_replace_callback(
1133
-            '!s:(\d+):"(.*?)";!',
1134
-            function ($match)
1135
-            {
1136
-                return ($match[1] === strlen($match[2]))
1137
-                    ? $match[0]
1138
-                    : 's:'
1139
-                      . strlen($match[2])
1140
-                      . ':"'
1141
-                      . $match[2]
1142
-                      . '";';
1143
-            },
1144
-            $data1
1145
-        );
1146
-        $max   = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1147
-        $error .= $data1 . PHP_EOL;
1148
-        $error .= $data2 . PHP_EOL;
1149
-        for ($i = 0; $i < $max; $i++) {
1150
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1151
-                $error  .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1152
-                $error  .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1153
-                $error  .= "\t-> Line Number = $i" . PHP_EOL;
1154
-                $start  = ($i - 20);
1155
-                $start  = ($start < 0) ? 0 : $start;
1156
-                $length = 40;
1157
-                $point  = $max - $i;
1158
-                if ($point < 20) {
1159
-                    $rlength = 1;
1160
-                    $rpoint  = -$point;
1161
-                } else {
1162
-                    $rpoint  = $length - 20;
1163
-                    $rlength = 1;
1164
-                }
1165
-                $error .= "\t-> Section Data1  = ";
1166
-                $error .= substr_replace(
1167
-                    substr($data1, $start, $length),
1168
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1169
-                    $rpoint,
1170
-                    $rlength
1171
-                );
1172
-                $error .= PHP_EOL;
1173
-                $error .= "\t-> Section Data2  = ";
1174
-                $error .= substr_replace(
1175
-                    substr($data2, $start, $length),
1176
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1177
-                    $rpoint,
1178
-                    $rlength
1179
-                );
1180
-                $error .= PHP_EOL;
1181
-            }
1182
-        }
1183
-        $error .= '</pre>';
1184
-        return $error;
1185
-    }
1186
-
1187
-
1188
-    /**
1189
-     * Saves an  array of settings used for configuring aspects of session behaviour
1190
-     *
1191
-     * @param array $updated_settings
1192
-     */
1193
-    private function updateSessionSettings(array $updated_settings = array())
1194
-    {
1195
-        // add existing settings, but only if not included in incoming $updated_settings array
1196
-        $updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1197
-        update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1198
-    }
1199
-
1200
-
1201
-    /**
1202
-     * garbage_collection
1203
-     */
1204
-    public function garbageCollection()
1205
-    {
1206
-        // only perform during regular requests if last garbage collection was over an hour ago
1207
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1208
-            $this->_last_gc = time();
1209
-            $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1210
-            /** @type WPDB $wpdb */
1211
-            global $wpdb;
1212
-            // filter the query limit. Set to 0 to turn off garbage collection
1213
-            $expired_session_transient_delete_query_limit = absint(
1214
-                apply_filters(
1215
-                    'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1216
-                    50
1217
-                )
1218
-            );
1219
-            // non-zero LIMIT means take out the trash
1220
-            if ($expired_session_transient_delete_query_limit) {
1221
-                $session_key    = str_replace('_', '\_', EE_Session::session_id_prefix);
1222
-                $hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1223
-                // since transient expiration timestamps are set in the future, we can compare against NOW
1224
-                // but we only want to pick up any trash that's been around for more than a day
1225
-                $expiration = time() - DAY_IN_SECONDS;
1226
-                $SQL        = "
362
+	/**
363
+	 * reset_cart
364
+	 */
365
+	public function reset_cart()
366
+	{
367
+		do_action('AHEE__EE_Session__reset_cart__before_reset', $this);
368
+		$this->_session_data['cart'] = null;
369
+	}
370
+
371
+
372
+
373
+	/**
374
+	 * @return \EE_Cart
375
+	 */
376
+	public function cart()
377
+	{
378
+		return isset($this->_session_data['cart']) && $this->_session_data['cart'] instanceof EE_Cart
379
+			? $this->_session_data['cart']
380
+			: null;
381
+	}
382
+
383
+
384
+
385
+	/**
386
+	 * @param \EE_Checkout $checkout
387
+	 * @return bool
388
+	 */
389
+	public function set_checkout(EE_Checkout $checkout)
390
+	{
391
+		$this->_session_data['checkout'] = $checkout;
392
+		return true;
393
+	}
394
+
395
+
396
+
397
+	/**
398
+	 * reset_checkout
399
+	 */
400
+	public function reset_checkout()
401
+	{
402
+		do_action('AHEE__EE_Session__reset_checkout__before_reset', $this);
403
+		$this->_session_data['checkout'] = null;
404
+	}
405
+
406
+
407
+
408
+	/**
409
+	 * @return \EE_Checkout
410
+	 */
411
+	public function checkout()
412
+	{
413
+		return isset($this->_session_data['checkout']) && $this->_session_data['checkout'] instanceof EE_Checkout
414
+			? $this->_session_data['checkout']
415
+			: null;
416
+	}
417
+
418
+
419
+
420
+	/**
421
+	 * @param \EE_Transaction $transaction
422
+	 * @return bool
423
+	 * @throws EE_Error
424
+	 */
425
+	public function set_transaction(EE_Transaction $transaction)
426
+	{
427
+		// first remove the session from the transaction before we save the transaction in the session
428
+		$transaction->set_txn_session_data(null);
429
+		$this->_session_data['transaction'] = $transaction;
430
+		return true;
431
+	}
432
+
433
+
434
+
435
+	/**
436
+	 * reset_transaction
437
+	 */
438
+	public function reset_transaction()
439
+	{
440
+		do_action('AHEE__EE_Session__reset_transaction__before_reset', $this);
441
+		$this->_session_data['transaction'] = null;
442
+	}
443
+
444
+
445
+
446
+	/**
447
+	 * @return \EE_Transaction
448
+	 */
449
+	public function transaction()
450
+	{
451
+		return isset($this->_session_data['transaction'])
452
+			   && $this->_session_data['transaction'] instanceof EE_Transaction
453
+			? $this->_session_data['transaction']
454
+			: null;
455
+	}
456
+
457
+
458
+
459
+	/**
460
+	 * retrieve session data
461
+	 *
462
+	 * @access    public
463
+	 * @param null $key
464
+	 * @param bool $reset_cache
465
+	 * @return    array
466
+	 */
467
+	public function get_session_data($key = null, $reset_cache = false)
468
+	{
469
+		if ($reset_cache) {
470
+			$this->reset_cart();
471
+			$this->reset_checkout();
472
+			$this->reset_transaction();
473
+		}
474
+		if (! empty($key)) {
475
+			return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
476
+		}
477
+		return $this->_session_data;
478
+	}
479
+
480
+
481
+
482
+	/**
483
+	 * set session data
484
+	 *
485
+	 * @access    public
486
+	 * @param    array $data
487
+	 * @return    TRUE on success, FALSE on fail
488
+	 */
489
+	public function set_session_data($data)
490
+	{
491
+
492
+		// nothing ??? bad data ??? go home!
493
+		if (empty($data) || ! is_array($data)) {
494
+			EE_Error::add_error(__('No session data or invalid session data was provided.', 'event_espresso'), __FILE__,
495
+				__FUNCTION__, __LINE__);
496
+			return false;
497
+		}
498
+		foreach ($data as $key => $value) {
499
+			if (isset($this->_default_session_vars[ $key ])) {
500
+				EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
501
+					'event_espresso'), $key), __FILE__, __FUNCTION__, __LINE__);
502
+				return false;
503
+			}
504
+			$this->_session_data[ $key ] = $value;
505
+		}
506
+		return true;
507
+	}
508
+
509
+
510
+
511
+	/**
512
+	 * @initiate session
513
+	 * @access   private
514
+	 * @return TRUE on success, FALSE on fail
515
+	 * @throws EE_Error
516
+	 * @throws InvalidArgumentException
517
+	 * @throws InvalidDataTypeException
518
+	 * @throws InvalidInterfaceException
519
+	 * @throws InvalidSessionDataException
520
+	 */
521
+	private function _espresso_session()
522
+	{
523
+		do_action('AHEE_log', __FILE__, __FUNCTION__, '');
524
+		// check that session has started
525
+		if (session_id() === '') {
526
+			//starts a new session if one doesn't already exist, or re-initiates an existing one
527
+			session_start();
528
+		}
529
+		// get our modified session ID
530
+		$this->_sid = $this->_generate_session_id();
531
+		// and the visitors IP
532
+		$this->_ip_address = $this->_visitor_ip();
533
+		// set the "user agent"
534
+		$this->_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? esc_attr($_SERVER['HTTP_USER_AGENT']) : false;
535
+		// now let's retrieve what's in the db
536
+		$session_data = $this->_retrieve_session_data();
537
+		if (! empty($session_data)) {
538
+			// get the current time in UTC
539
+			$this->_time = $this->_time !== null ? $this->_time : time();
540
+			// and reset the session expiration
541
+			$this->_expiration = isset($session_data['expiration'])
542
+				? $session_data['expiration']
543
+				: $this->_time + $this->_lifespan;
544
+		} else {
545
+			// set initial site access time and the session expiration
546
+			$this->_set_init_access_and_expiration();
547
+			// set referer
548
+			$this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
549
+				? esc_attr($_SERVER['HTTP_REFERER'])
550
+				: '';
551
+			// no previous session = go back and create one (on top of the data above)
552
+			return false;
553
+		}
554
+		// now the user agent
555
+		if ($session_data['user_agent'] !== $this->_user_agent) {
556
+			return false;
557
+		}
558
+		// wait a minute... how old are you?
559
+		if ($this->_time > $this->_expiration) {
560
+			// yer too old fer me!
561
+			$this->_expired = true;
562
+			// wipe out everything that isn't a default session datum
563
+			$this->clear_session(__CLASS__, __FUNCTION__);
564
+		}
565
+		// make event espresso session data available to plugin
566
+		$this->_session_data = array_merge($this->_session_data, $session_data);
567
+		return true;
568
+	}
569
+
570
+
571
+
572
+	/**
573
+	 * _get_session_data
574
+	 * Retrieves the session data, and attempts to correct any encoding issues that can occur due to improperly setup
575
+	 * databases
576
+	 *
577
+	 * @return array
578
+	 * @throws EE_Error
579
+	 * @throws InvalidArgumentException
580
+	 * @throws InvalidSessionDataException
581
+	 * @throws InvalidDataTypeException
582
+	 * @throws InvalidInterfaceException
583
+	 */
584
+	protected function _retrieve_session_data()
585
+	{
586
+		$ssn_key = EE_Session::session_id_prefix . $this->_sid;
587
+		try {
588
+			// we're using WP's Transient API to store session data using the PHP session ID as the option name
589
+			$session_data = $this->cache_storage->get($ssn_key, false);
590
+			if (empty($session_data)) {
591
+				return array();
592
+			}
593
+			if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
594
+				$hash_check = $this->cache_storage->get(
595
+					EE_Session::hash_check_prefix . $this->_sid,
596
+					false
597
+				);
598
+				if ($hash_check && $hash_check !== md5($session_data)) {
599
+					EE_Error::add_error(
600
+						sprintf(
601
+							__(
602
+								'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
603
+								'event_espresso'
604
+							),
605
+							EE_Session::session_id_prefix . $this->_sid
606
+						),
607
+						__FILE__, __FUNCTION__, __LINE__
608
+					);
609
+				}
610
+			}
611
+		} catch (Exception $e) {
612
+			// let's just eat that error for now and attempt to correct any corrupted data
613
+			global $wpdb;
614
+			$row          = $wpdb->get_row(
615
+				$wpdb->prepare(
616
+					"SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
617
+					'_transient_' . $ssn_key
618
+				)
619
+			);
620
+			$session_data = is_object($row) ? $row->option_value : null;
621
+			if ($session_data) {
622
+				$session_data = preg_replace_callback(
623
+					'!s:(d+):"(.*?)";!',
624
+					function ($match)
625
+					{
626
+						return $match[1] === strlen($match[2])
627
+							? $match[0]
628
+							: 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
629
+					},
630
+					$session_data
631
+				);
632
+			}
633
+			$session_data = maybe_unserialize($session_data);
634
+		}
635
+		// in case the data is encoded... try to decode it
636
+		$session_data = $this->encryption instanceof EE_Encryption
637
+			? $this->encryption->base64_string_decode($session_data)
638
+			: $session_data;
639
+		if (! is_array($session_data)) {
640
+			try {
641
+				$session_data = maybe_unserialize($session_data);
642
+			} catch (Exception $e) {
643
+				$msg = esc_html__(
644
+					'An error occurred while attempting to unserialize the session data.',
645
+					'event_espresso'
646
+				);
647
+				$msg .= WP_DEBUG
648
+					? '<br><pre>'
649
+					  . print_r($session_data, true)
650
+					  . '</pre><br>'
651
+					  . $this->find_serialize_error($session_data)
652
+					: '';
653
+				$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
654
+				throw new InvalidSessionDataException($msg, 0, $e);
655
+			}
656
+		}
657
+		// just a check to make sure the session array is indeed an array
658
+		if (! is_array($session_data)) {
659
+			// no?!?! then something is wrong
660
+			$msg = esc_html__(
661
+				'The session data is missing, invalid, or corrupted.',
662
+				'event_espresso'
663
+			);
664
+			$msg .= WP_DEBUG
665
+				? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
666
+				: '';
667
+			$this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
668
+			throw new InvalidSessionDataException($msg);
669
+		}
670
+		if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
671
+			$session_data['transaction'] = EEM_Transaction::instance()->get_one_by_ID(
672
+				$session_data['transaction']
673
+			);
674
+		}
675
+		return $session_data;
676
+	}
677
+
678
+
679
+
680
+	/**
681
+	 * _generate_session_id
682
+	 * Retrieves the PHP session id either directly from the PHP session,
683
+	 * or from the $_REQUEST array if it was passed in from an AJAX request.
684
+	 * The session id is then salted and hashed (mmm sounds tasty)
685
+	 * so that it can be safely used as a $_REQUEST param
686
+	 *
687
+	 * @return string
688
+	 */
689
+	protected function _generate_session_id()
690
+	{
691
+		// check if the SID was passed explicitly, otherwise get from session, then add salt and hash it to reduce length
692
+		if (isset($_REQUEST['EESID'])) {
693
+			$session_id = sanitize_text_field($_REQUEST['EESID']);
694
+		} else {
695
+			$session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
696
+		}
697
+		return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
698
+	}
699
+
700
+
701
+
702
+	/**
703
+	 * _get_sid_salt
704
+	 *
705
+	 * @return string
706
+	 */
707
+	protected function _get_sid_salt()
708
+	{
709
+		// was session id salt already saved to db ?
710
+		if (empty($this->_sid_salt)) {
711
+			// no?  then maybe use WP defined constant
712
+			if (defined('AUTH_SALT')) {
713
+				$this->_sid_salt = AUTH_SALT;
714
+			}
715
+			// if salt doesn't exist or is too short
716
+			if (strlen($this->_sid_salt) < 32) {
717
+				// create a new one
718
+				$this->_sid_salt = wp_generate_password(64);
719
+			}
720
+			// and save it as a permanent session setting
721
+			$this->updateSessionSettings(array('sid_salt' => $this->_sid_salt));
722
+		}
723
+		return $this->_sid_salt;
724
+	}
725
+
726
+
727
+
728
+	/**
729
+	 * _set_init_access_and_expiration
730
+	 *
731
+	 * @return void
732
+	 */
733
+	protected function _set_init_access_and_expiration()
734
+	{
735
+		$this->_time       = time();
736
+		$this->_expiration = $this->_time + $this->_lifespan;
737
+		// set initial site access time
738
+		$this->_session_data['init_access'] = $this->_time;
739
+		// and the session expiration
740
+		$this->_session_data['expiration'] = $this->_expiration;
741
+	}
742
+
743
+
744
+
745
+	/**
746
+	 * @update session data  prior to saving to the db
747
+	 * @access public
748
+	 * @param bool $new_session
749
+	 * @return TRUE on success, FALSE on fail
750
+	 * @throws EE_Error
751
+	 * @throws InvalidArgumentException
752
+	 * @throws InvalidDataTypeException
753
+	 * @throws InvalidInterfaceException
754
+	 */
755
+	public function update($new_session = false)
756
+	{
757
+		$this->_session_data = $this->_session_data !== null
758
+							   && is_array($this->_session_data)
759
+							   && isset($this->_session_data['id'])
760
+			? $this->_session_data
761
+			: array();
762
+		if (empty($this->_session_data)) {
763
+			$this->_set_defaults();
764
+		}
765
+		$session_data = array();
766
+		foreach ($this->_session_data as $key => $value) {
767
+
768
+			switch ($key) {
769
+
770
+				case 'id' :
771
+					// session ID
772
+					$session_data['id'] = $this->_sid;
773
+					break;
774
+				case 'ip_address' :
775
+					// visitor ip address
776
+					$session_data['ip_address'] = $this->_visitor_ip();
777
+					break;
778
+				case 'user_agent' :
779
+					// visitor user_agent
780
+					$session_data['user_agent'] = $this->_user_agent;
781
+					break;
782
+				case 'init_access' :
783
+					$session_data['init_access'] = absint($value);
784
+					break;
785
+				case 'last_access' :
786
+					// current access time
787
+					$session_data['last_access'] = $this->_time;
788
+					break;
789
+				case 'expiration' :
790
+					// when the session expires
791
+					$session_data['expiration'] = ! empty($this->_expiration)
792
+						? $this->_expiration
793
+						: $session_data['init_access'] + $this->_lifespan;
794
+					break;
795
+				case 'user_id' :
796
+					// current user if logged in
797
+					$session_data['user_id'] = $this->_wp_user_id();
798
+					break;
799
+				case 'pages_visited' :
800
+					$page_visit = $this->_get_page_visit();
801
+					if ($page_visit) {
802
+						// set pages visited where the first will be the http referrer
803
+						$this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
804
+						// we'll only save the last 10 page visits.
805
+						$session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
806
+					}
807
+					break;
808
+				default :
809
+					// carry any other data over
810
+					$session_data[ $key ] = $this->_session_data[ $key ];
811
+			}
812
+		}
813
+		$this->_session_data = $session_data;
814
+		// creating a new session does not require saving to the db just yet
815
+		if (! $new_session) {
816
+			// ready? let's save
817
+			if ($this->_save_session_to_db()) {
818
+				return true;
819
+			}
820
+			return false;
821
+		}
822
+		// meh, why not?
823
+		return true;
824
+	}
825
+
826
+
827
+
828
+	/**
829
+	 * @create session data array
830
+	 * @access public
831
+	 * @return bool
832
+	 * @throws EE_Error
833
+	 * @throws InvalidArgumentException
834
+	 * @throws InvalidDataTypeException
835
+	 * @throws InvalidInterfaceException
836
+	 */
837
+	private function _create_espresso_session()
838
+	{
839
+		do_action('AHEE_log', __CLASS__, __FUNCTION__, '');
840
+		// use the update function for now with $new_session arg set to TRUE
841
+		return $this->update(true) ? true : false;
842
+	}
843
+
844
+
845
+
846
+	/**
847
+	 * _save_session_to_db
848
+	 *
849
+	 * @param bool $clear_session
850
+	 * @return string
851
+	 * @throws EE_Error
852
+	 * @throws InvalidArgumentException
853
+	 * @throws InvalidDataTypeException
854
+	 * @throws InvalidInterfaceException
855
+	 */
856
+	private function _save_session_to_db($clear_session = false)
857
+	{
858
+		// unless we're deleting the session data, don't save anything if there isn't a cart
859
+		if (! $clear_session && ! $this->cart() instanceof EE_Cart) {
860
+			return false;
861
+		}
862
+		$transaction = $this->transaction();
863
+		if ($transaction instanceof EE_Transaction) {
864
+			if (! $transaction->ID()) {
865
+				$transaction->save();
866
+			}
867
+			$this->_session_data['transaction'] = $transaction->ID();
868
+		}
869
+		// then serialize all of our session data
870
+		$session_data = serialize($this->_session_data);
871
+		// do we need to also encode it to avoid corrupted data when saved to the db?
872
+		$session_data = $this->_use_encryption
873
+			? $this->encryption->base64_string_encode($session_data)
874
+			: $session_data;
875
+		// maybe save hash check
876
+		if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
877
+			$this->cache_storage->add(
878
+				EE_Session::hash_check_prefix . $this->_sid,
879
+				md5($session_data),
880
+				$this->_lifespan
881
+			);
882
+		}
883
+		// we're using the Transient API for storing session data,
884
+		return $this->cache_storage->add(
885
+			EE_Session::session_id_prefix . $this->_sid,
886
+			$session_data,
887
+			$this->_lifespan
888
+		);
889
+	}
890
+
891
+
892
+
893
+	/**
894
+	 * _visitor_ip
895
+	 *    attempt to get IP address of current visitor from server
896
+	 * plz see: http://stackoverflow.com/a/2031935/1475279
897
+	 *
898
+	 * @access public
899
+	 * @return string
900
+	 */
901
+	private function _visitor_ip()
902
+	{
903
+		$visitor_ip  = '0.0.0.0';
904
+		$server_keys = array(
905
+			'HTTP_CLIENT_IP',
906
+			'HTTP_X_FORWARDED_FOR',
907
+			'HTTP_X_FORWARDED',
908
+			'HTTP_X_CLUSTER_CLIENT_IP',
909
+			'HTTP_FORWARDED_FOR',
910
+			'HTTP_FORWARDED',
911
+			'REMOTE_ADDR',
912
+		);
913
+		foreach ($server_keys as $key) {
914
+			if (isset($_SERVER[ $key ])) {
915
+				foreach (array_map('trim', explode(',', $_SERVER[ $key ])) as $ip) {
916
+					if ($ip === '127.0.0.1' || filter_var($ip, FILTER_VALIDATE_IP) !== false) {
917
+						$visitor_ip = $ip;
918
+					}
919
+				}
920
+			}
921
+		}
922
+		return $visitor_ip;
923
+	}
924
+
925
+
926
+
927
+	/**
928
+	 * @get    the full page request the visitor is accessing
929
+	 * @access public
930
+	 * @return string
931
+	 */
932
+	public function _get_page_visit()
933
+	{
934
+		$page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
935
+		// check for request url
936
+		if (isset($_SERVER['REQUEST_URI'])) {
937
+			$http_host   = '';
938
+			$page_id     = '?';
939
+			$e_reg       = '';
940
+			$request_uri = esc_url($_SERVER['REQUEST_URI']);
941
+			$ru_bits     = explode('?', $request_uri);
942
+			$request_uri = $ru_bits[0];
943
+			// check for and grab host as well
944
+			if (isset($_SERVER['HTTP_HOST'])) {
945
+				$http_host = esc_url($_SERVER['HTTP_HOST']);
946
+			}
947
+			// check for page_id in SERVER REQUEST
948
+			if (isset($_REQUEST['page_id'])) {
949
+				// rebuild $e_reg without any of the extra parameters
950
+				$page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
951
+			}
952
+			// check for $e_reg in SERVER REQUEST
953
+			if (isset($_REQUEST['ee'])) {
954
+				// rebuild $e_reg without any of the extra parameters
955
+				$e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
956
+			}
957
+			$page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
958
+		}
959
+		return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
960
+	}
961
+
962
+
963
+
964
+	/**
965
+	 * @the    current wp user id
966
+	 * @access public
967
+	 * @return int
968
+	 */
969
+	public function _wp_user_id()
970
+	{
971
+		// if I need to explain the following lines of code, then you shouldn't be looking at this!
972
+		$this->_wp_user_id = get_current_user_id();
973
+		return $this->_wp_user_id;
974
+	}
975
+
976
+
977
+
978
+	/**
979
+	 * Clear EE_Session data
980
+	 *
981
+	 * @access public
982
+	 * @param string $class
983
+	 * @param string $function
984
+	 * @return void
985
+	 * @throws EE_Error
986
+	 * @throws InvalidArgumentException
987
+	 * @throws InvalidDataTypeException
988
+	 * @throws InvalidInterfaceException
989
+	 */
990
+	public function clear_session($class = '', $function = '')
991
+	{
992
+		//echo '<h3 style="color:#999;line-height:.9em;"><span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/><span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b></h3>';
993
+		do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
994
+		$this->reset_cart();
995
+		$this->reset_checkout();
996
+		$this->reset_transaction();
997
+		// wipe out everything that isn't a default session datum
998
+		$this->reset_data(array_keys($this->_session_data));
999
+		// reset initial site access time and the session expiration
1000
+		$this->_set_init_access_and_expiration();
1001
+		$this->_save_session_to_db(true);
1002
+	}
1003
+
1004
+
1005
+
1006
+	/**
1007
+	 * @resets all non-default session vars
1008
+	 * @access public
1009
+	 * @param array|mixed $data_to_reset
1010
+	 * @param bool        $show_all_notices
1011
+	 * @return TRUE on success, FALSE on fail
1012
+	 */
1013
+	public function reset_data($data_to_reset = array(), $show_all_notices = false)
1014
+	{
1015
+		// if $data_to_reset is not in an array, then put it in one
1016
+		if (! is_array($data_to_reset)) {
1017
+			$data_to_reset = array($data_to_reset);
1018
+		}
1019
+		// nothing ??? go home!
1020
+		if (empty($data_to_reset)) {
1021
+			EE_Error::add_error(__('No session data could be reset, because no session var name was provided.',
1022
+				'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
1023
+			return false;
1024
+		}
1025
+		$return_value = true;
1026
+		// since $data_to_reset is an array, cycle through the values
1027
+		foreach ($data_to_reset as $reset) {
1028
+
1029
+			// first check to make sure it is a valid session var
1030
+			if (isset($this->_session_data[ $reset ])) {
1031
+				// then check to make sure it is not a default var
1032
+				if (! array_key_exists($reset, $this->_default_session_vars)) {
1033
+					// remove session var
1034
+					unset($this->_session_data[ $reset ]);
1035
+					if ($show_all_notices) {
1036
+						EE_Error::add_success(sprintf(__('The session variable %s was removed.', 'event_espresso'),
1037
+							$reset), __FILE__, __FUNCTION__, __LINE__);
1038
+					}
1039
+				} else {
1040
+					// yeeeeeeeeerrrrrrrrrrr OUT !!!!
1041
+					if ($show_all_notices) {
1042
+						EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
1043
+							'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1044
+					}
1045
+					$return_value = false;
1046
+				}
1047
+			} elseif ($show_all_notices) {
1048
+				// oops! that session var does not exist!
1049
+				EE_Error::add_error(sprintf(__('The session item provided, %s, is invalid or does not exist.',
1050
+					'event_espresso'), $reset), __FILE__, __FUNCTION__, __LINE__);
1051
+				$return_value = false;
1052
+			}
1053
+		} // end of foreach
1054
+		return $return_value;
1055
+	}
1056
+
1057
+
1058
+
1059
+	/**
1060
+	 *   wp_loaded
1061
+	 *
1062
+	 * @access public
1063
+	 * @throws EE_Error
1064
+	 * @throws InvalidDataTypeException
1065
+	 * @throws InvalidInterfaceException
1066
+	 * @throws InvalidArgumentException
1067
+	 */
1068
+	public function wp_loaded()
1069
+	{
1070
+		if (
1071
+			EE_Registry::instance()->REQ instanceof EE_Request_Handler
1072
+			&& EE_Registry::instance()->REQ->is_set('clear_session')
1073
+		) {
1074
+			$this->clear_session(__CLASS__, __FUNCTION__);
1075
+		}
1076
+	}
1077
+
1078
+
1079
+
1080
+	/**
1081
+	 * Used to reset the entire object (for tests).
1082
+	 *
1083
+	 * @since 4.3.0
1084
+	 * @throws EE_Error
1085
+	 * @throws InvalidDataTypeException
1086
+	 * @throws InvalidInterfaceException
1087
+	 * @throws InvalidArgumentException
1088
+	 */
1089
+	public function reset_instance()
1090
+	{
1091
+		$this->clear_session();
1092
+		self::$_instance = null;
1093
+	}
1094
+
1095
+
1096
+
1097
+	public function configure_garbage_collection_filters()
1098
+	{
1099
+		// run old filter we had for controlling session cleanup
1100
+		$expired_session_transient_delete_query_limit = absint(
1101
+			apply_filters(
1102
+				'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1103
+				50
1104
+			)
1105
+		);
1106
+		// is there a value? or one that is different than the default 50 records?
1107
+		if ($expired_session_transient_delete_query_limit === 0) {
1108
+			// hook into TransientCacheStorage in case Session cleanup was turned off
1109
+			add_filter('FHEE__TransientCacheStorage__transient_cleanup_schedule', '__return_zero');
1110
+		} elseif ($expired_session_transient_delete_query_limit !== 50) {
1111
+			// or use that for the new transient cleanup query limit
1112
+			add_filter(
1113
+				'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1114
+				function () use ($expired_session_transient_delete_query_limit)
1115
+				{
1116
+					return $expired_session_transient_delete_query_limit;
1117
+				}
1118
+			);
1119
+		}
1120
+	}
1121
+
1122
+
1123
+
1124
+	/**
1125
+	 * @see http://stackoverflow.com/questions/10152904/unserialize-function-unserialize-error-at-offset/21389439#10152996
1126
+	 * @param $data1
1127
+	 * @return string
1128
+	 */
1129
+	private function find_serialize_error($data1)
1130
+	{
1131
+		$error = '<pre>';
1132
+		$data2 = preg_replace_callback(
1133
+			'!s:(\d+):"(.*?)";!',
1134
+			function ($match)
1135
+			{
1136
+				return ($match[1] === strlen($match[2]))
1137
+					? $match[0]
1138
+					: 's:'
1139
+					  . strlen($match[2])
1140
+					  . ':"'
1141
+					  . $match[2]
1142
+					  . '";';
1143
+			},
1144
+			$data1
1145
+		);
1146
+		$max   = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1147
+		$error .= $data1 . PHP_EOL;
1148
+		$error .= $data2 . PHP_EOL;
1149
+		for ($i = 0; $i < $max; $i++) {
1150
+			if (@$data1[ $i ] !== @$data2[ $i ]) {
1151
+				$error  .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1152
+				$error  .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1153
+				$error  .= "\t-> Line Number = $i" . PHP_EOL;
1154
+				$start  = ($i - 20);
1155
+				$start  = ($start < 0) ? 0 : $start;
1156
+				$length = 40;
1157
+				$point  = $max - $i;
1158
+				if ($point < 20) {
1159
+					$rlength = 1;
1160
+					$rpoint  = -$point;
1161
+				} else {
1162
+					$rpoint  = $length - 20;
1163
+					$rlength = 1;
1164
+				}
1165
+				$error .= "\t-> Section Data1  = ";
1166
+				$error .= substr_replace(
1167
+					substr($data1, $start, $length),
1168
+					"<b style=\"color:green\">{$data1[ $i ]}</b>",
1169
+					$rpoint,
1170
+					$rlength
1171
+				);
1172
+				$error .= PHP_EOL;
1173
+				$error .= "\t-> Section Data2  = ";
1174
+				$error .= substr_replace(
1175
+					substr($data2, $start, $length),
1176
+					"<b style=\"color:red\">{$data2[ $i ]}</b>",
1177
+					$rpoint,
1178
+					$rlength
1179
+				);
1180
+				$error .= PHP_EOL;
1181
+			}
1182
+		}
1183
+		$error .= '</pre>';
1184
+		return $error;
1185
+	}
1186
+
1187
+
1188
+	/**
1189
+	 * Saves an  array of settings used for configuring aspects of session behaviour
1190
+	 *
1191
+	 * @param array $updated_settings
1192
+	 */
1193
+	private function updateSessionSettings(array $updated_settings = array())
1194
+	{
1195
+		// add existing settings, but only if not included in incoming $updated_settings array
1196
+		$updated_settings += get_option(EE_Session::OPTION_NAME_SETTINGS, array());
1197
+		update_option(EE_Session::OPTION_NAME_SETTINGS, $updated_settings);
1198
+	}
1199
+
1200
+
1201
+	/**
1202
+	 * garbage_collection
1203
+	 */
1204
+	public function garbageCollection()
1205
+	{
1206
+		// only perform during regular requests if last garbage collection was over an hour ago
1207
+		if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1208
+			$this->_last_gc = time();
1209
+			$this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1210
+			/** @type WPDB $wpdb */
1211
+			global $wpdb;
1212
+			// filter the query limit. Set to 0 to turn off garbage collection
1213
+			$expired_session_transient_delete_query_limit = absint(
1214
+				apply_filters(
1215
+					'FHEE__EE_Session__garbage_collection___expired_session_transient_delete_query_limit',
1216
+					50
1217
+				)
1218
+			);
1219
+			// non-zero LIMIT means take out the trash
1220
+			if ($expired_session_transient_delete_query_limit) {
1221
+				$session_key    = str_replace('_', '\_', EE_Session::session_id_prefix);
1222
+				$hash_check_key = str_replace('_', '\_', EE_Session::hash_check_prefix);
1223
+				// since transient expiration timestamps are set in the future, we can compare against NOW
1224
+				// but we only want to pick up any trash that's been around for more than a day
1225
+				$expiration = time() - DAY_IN_SECONDS;
1226
+				$SQL        = "
1227 1227
                     SELECT option_name
1228 1228
                     FROM {$wpdb->options}
1229 1229
                     WHERE
@@ -1232,19 +1232,19 @@  discard block
 block discarded – undo
1232 1232
                     AND option_value < {$expiration}
1233 1233
                     LIMIT {$expired_session_transient_delete_query_limit}
1234 1234
                 ";
1235
-                // produces something like:
1236
-                // SELECT option_name FROM wp_options
1237
-                // WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1238
-                // OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1239
-                // AND option_value < 1508368198 LIMIT 50
1240
-                $expired_sessions = $wpdb->get_col($SQL);
1241
-                // valid results?
1242
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1243
-                    $this->cache_storage->deleteMany($expired_sessions, true);
1244
-                }
1245
-            }
1246
-        }
1247
-    }
1235
+				// produces something like:
1236
+				// SELECT option_name FROM wp_options
1237
+				// WHERE ( option_name LIKE '\_transient\_timeout\_ee\_ssn\_%'
1238
+				// OR option_name LIKE '\_transient\_timeout\_ee\_shc\_%' )
1239
+				// AND option_value < 1508368198 LIMIT 50
1240
+				$expired_sessions = $wpdb->get_col($SQL);
1241
+				// valid results?
1242
+				if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1243
+					$this->cache_storage->deleteMany($expired_sessions, true);
1244
+				}
1245
+			}
1246
+		}
1247
+	}
1248 1248
 
1249 1249
 
1250 1250
 
Please login to merge, or discard this patch.
Spacing   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -164,7 +164,7 @@  discard block
 block discarded – undo
164 164
         // check if class object is instantiated
165 165
         // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via:
166 166
         // add_filter( 'FHEE_load_EE_Session', '__return_false' );
167
-        if (! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
167
+        if ( ! self::$_instance instanceof EE_Session && apply_filters('FHEE_load_EE_Session', true)) {
168 168
             self::$_instance = new self($cache_storage, $encryption);
169 169
         }
170 170
         return self::$_instance;
@@ -185,11 +185,11 @@  discard block
 block discarded – undo
185 185
     {
186 186
 
187 187
         // session loading is turned ON by default, but prior to the init hook, can be turned back OFF via: add_filter( 'FHEE_load_EE_Session', '__return_false' );
188
-        if (! apply_filters('FHEE_load_EE_Session', true)) {
188
+        if ( ! apply_filters('FHEE_load_EE_Session', true)) {
189 189
             return;
190 190
         }
191 191
         do_action('AHEE_log', __FILE__, __FUNCTION__, '');
192
-        if (! defined('ESPRESSO_SESSION')) {
192
+        if ( ! defined('ESPRESSO_SESSION')) {
193 193
             define('ESPRESSO_SESSION', true);
194 194
         }
195 195
         // default session lifespan in seconds
@@ -205,11 +205,11 @@  discard block
 block discarded – undo
205 205
          */
206 206
         // retrieve session options from db
207 207
         $session_settings = (array) get_option(EE_Session::OPTION_NAME_SETTINGS, array());
208
-        if (! empty($session_settings)) {
208
+        if ( ! empty($session_settings)) {
209 209
             // cycle though existing session options
210 210
             foreach ($session_settings as $var_name => $session_setting) {
211 211
                 // set values for class properties
212
-                $var_name          = '_' . $var_name;
212
+                $var_name          = '_'.$var_name;
213 213
                 $this->{$var_name} = $session_setting;
214 214
             }
215 215
         }
@@ -247,7 +247,7 @@  discard block
 block discarded – undo
247 247
     public function open_session()
248 248
     {
249 249
         // check for existing session and retrieve it from db
250
-        if (! $this->_espresso_session()) {
250
+        if ( ! $this->_espresso_session()) {
251 251
             // or just start a new one
252 252
             $this->_create_espresso_session();
253 253
         }
@@ -299,7 +299,7 @@  discard block
 block discarded – undo
299 299
      */
300 300
     public function extend_expiration($time = 0)
301 301
     {
302
-        $time              = $time ? $time : $this->extension();
302
+        $time = $time ? $time : $this->extension();
303 303
         $this->_expiration += absint($time);
304 304
     }
305 305
 
@@ -326,9 +326,9 @@  discard block
 block discarded – undo
326 326
         // set some defaults
327 327
         foreach ($this->_default_session_vars as $key => $default_var) {
328 328
             if (is_array($default_var)) {
329
-                $this->_session_data[ $key ] = array();
329
+                $this->_session_data[$key] = array();
330 330
             } else {
331
-                $this->_session_data[ $key ] = '';
331
+                $this->_session_data[$key] = '';
332 332
             }
333 333
         }
334 334
     }
@@ -471,8 +471,8 @@  discard block
 block discarded – undo
471 471
             $this->reset_checkout();
472 472
             $this->reset_transaction();
473 473
         }
474
-        if (! empty($key)) {
475
-            return isset($this->_session_data[ $key ]) ? $this->_session_data[ $key ] : null;
474
+        if ( ! empty($key)) {
475
+            return isset($this->_session_data[$key]) ? $this->_session_data[$key] : null;
476 476
         }
477 477
         return $this->_session_data;
478 478
     }
@@ -496,12 +496,12 @@  discard block
 block discarded – undo
496 496
             return false;
497 497
         }
498 498
         foreach ($data as $key => $value) {
499
-            if (isset($this->_default_session_vars[ $key ])) {
499
+            if (isset($this->_default_session_vars[$key])) {
500 500
                 EE_Error::add_error(sprintf(__('Sorry! %s is a default session datum and can not be reset.',
501 501
                     'event_espresso'), $key), __FILE__, __FUNCTION__, __LINE__);
502 502
                 return false;
503 503
             }
504
-            $this->_session_data[ $key ] = $value;
504
+            $this->_session_data[$key] = $value;
505 505
         }
506 506
         return true;
507 507
     }
@@ -534,7 +534,7 @@  discard block
 block discarded – undo
534 534
         $this->_user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? esc_attr($_SERVER['HTTP_USER_AGENT']) : false;
535 535
         // now let's retrieve what's in the db
536 536
         $session_data = $this->_retrieve_session_data();
537
-        if (! empty($session_data)) {
537
+        if ( ! empty($session_data)) {
538 538
             // get the current time in UTC
539 539
             $this->_time = $this->_time !== null ? $this->_time : time();
540 540
             // and reset the session expiration
@@ -545,7 +545,7 @@  discard block
 block discarded – undo
545 545
             // set initial site access time and the session expiration
546 546
             $this->_set_init_access_and_expiration();
547 547
             // set referer
548
-            $this->_session_data['pages_visited'][ $this->_session_data['init_access'] ] = isset($_SERVER['HTTP_REFERER'])
548
+            $this->_session_data['pages_visited'][$this->_session_data['init_access']] = isset($_SERVER['HTTP_REFERER'])
549 549
                 ? esc_attr($_SERVER['HTTP_REFERER'])
550 550
                 : '';
551 551
             // no previous session = go back and create one (on top of the data above)
@@ -583,7 +583,7 @@  discard block
 block discarded – undo
583 583
      */
584 584
     protected function _retrieve_session_data()
585 585
     {
586
-        $ssn_key = EE_Session::session_id_prefix . $this->_sid;
586
+        $ssn_key = EE_Session::session_id_prefix.$this->_sid;
587 587
         try {
588 588
             // we're using WP's Transient API to store session data using the PHP session ID as the option name
589 589
             $session_data = $this->cache_storage->get($ssn_key, false);
@@ -592,7 +592,7 @@  discard block
 block discarded – undo
592 592
             }
593 593
             if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
594 594
                 $hash_check = $this->cache_storage->get(
595
-                    EE_Session::hash_check_prefix . $this->_sid,
595
+                    EE_Session::hash_check_prefix.$this->_sid,
596 596
                     false
597 597
                 );
598 598
                 if ($hash_check && $hash_check !== md5($session_data)) {
@@ -602,7 +602,7 @@  discard block
 block discarded – undo
602 602
                                 'The stored data for session %1$s failed to pass a hash check and therefore appears to be invalid.',
603 603
                                 'event_espresso'
604 604
                             ),
605
-                            EE_Session::session_id_prefix . $this->_sid
605
+                            EE_Session::session_id_prefix.$this->_sid
606 606
                         ),
607 607
                         __FILE__, __FUNCTION__, __LINE__
608 608
                     );
@@ -611,21 +611,21 @@  discard block
 block discarded – undo
611 611
         } catch (Exception $e) {
612 612
             // let's just eat that error for now and attempt to correct any corrupted data
613 613
             global $wpdb;
614
-            $row          = $wpdb->get_row(
614
+            $row = $wpdb->get_row(
615 615
                 $wpdb->prepare(
616 616
                     "SELECT option_value FROM {$wpdb->options} WHERE option_name = %s LIMIT 1",
617
-                    '_transient_' . $ssn_key
617
+                    '_transient_'.$ssn_key
618 618
                 )
619 619
             );
620 620
             $session_data = is_object($row) ? $row->option_value : null;
621 621
             if ($session_data) {
622 622
                 $session_data = preg_replace_callback(
623 623
                     '!s:(d+):"(.*?)";!',
624
-                    function ($match)
624
+                    function($match)
625 625
                     {
626 626
                         return $match[1] === strlen($match[2])
627 627
                             ? $match[0]
628
-                            : 's:' . strlen($match[2]) . ':"' . $match[2] . '";';
628
+                            : 's:'.strlen($match[2]).':"'.$match[2].'";';
629 629
                     },
630 630
                     $session_data
631 631
                 );
@@ -636,7 +636,7 @@  discard block
 block discarded – undo
636 636
         $session_data = $this->encryption instanceof EE_Encryption
637 637
             ? $this->encryption->base64_string_decode($session_data)
638 638
             : $session_data;
639
-        if (! is_array($session_data)) {
639
+        if ( ! is_array($session_data)) {
640 640
             try {
641 641
                 $session_data = maybe_unserialize($session_data);
642 642
             } catch (Exception $e) {
@@ -650,21 +650,21 @@  discard block
 block discarded – undo
650 650
                       . '</pre><br>'
651 651
                       . $this->find_serialize_error($session_data)
652 652
                     : '';
653
-                $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
653
+                $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
654 654
                 throw new InvalidSessionDataException($msg, 0, $e);
655 655
             }
656 656
         }
657 657
         // just a check to make sure the session array is indeed an array
658
-        if (! is_array($session_data)) {
658
+        if ( ! is_array($session_data)) {
659 659
             // no?!?! then something is wrong
660 660
             $msg = esc_html__(
661 661
                 'The session data is missing, invalid, or corrupted.',
662 662
                 'event_espresso'
663 663
             );
664 664
             $msg .= WP_DEBUG
665
-                ? '<br><pre>' . print_r($session_data, true) . '</pre><br>' . $this->find_serialize_error($session_data)
665
+                ? '<br><pre>'.print_r($session_data, true).'</pre><br>'.$this->find_serialize_error($session_data)
666 666
                 : '';
667
-            $this->cache_storage->delete(EE_Session::session_id_prefix . $this->_sid);
667
+            $this->cache_storage->delete(EE_Session::session_id_prefix.$this->_sid);
668 668
             throw new InvalidSessionDataException($msg);
669 669
         }
670 670
         if (isset($session_data['transaction']) && absint($session_data['transaction']) !== 0) {
@@ -692,7 +692,7 @@  discard block
 block discarded – undo
692 692
         if (isset($_REQUEST['EESID'])) {
693 693
             $session_id = sanitize_text_field($_REQUEST['EESID']);
694 694
         } else {
695
-            $session_id = md5(session_id() . get_current_blog_id() . $this->_get_sid_salt());
695
+            $session_id = md5(session_id().get_current_blog_id().$this->_get_sid_salt());
696 696
         }
697 697
         return apply_filters('FHEE__EE_Session___generate_session_id__session_id', $session_id);
698 698
     }
@@ -800,19 +800,19 @@  discard block
 block discarded – undo
800 800
                     $page_visit = $this->_get_page_visit();
801 801
                     if ($page_visit) {
802 802
                         // set pages visited where the first will be the http referrer
803
-                        $this->_session_data['pages_visited'][ $this->_time ] = $page_visit;
803
+                        $this->_session_data['pages_visited'][$this->_time] = $page_visit;
804 804
                         // we'll only save the last 10 page visits.
805 805
                         $session_data['pages_visited'] = array_slice($this->_session_data['pages_visited'], -10);
806 806
                     }
807 807
                     break;
808 808
                 default :
809 809
                     // carry any other data over
810
-                    $session_data[ $key ] = $this->_session_data[ $key ];
810
+                    $session_data[$key] = $this->_session_data[$key];
811 811
             }
812 812
         }
813 813
         $this->_session_data = $session_data;
814 814
         // creating a new session does not require saving to the db just yet
815
-        if (! $new_session) {
815
+        if ( ! $new_session) {
816 816
             // ready? let's save
817 817
             if ($this->_save_session_to_db()) {
818 818
                 return true;
@@ -856,12 +856,12 @@  discard block
 block discarded – undo
856 856
     private function _save_session_to_db($clear_session = false)
857 857
     {
858 858
         // unless we're deleting the session data, don't save anything if there isn't a cart
859
-        if (! $clear_session && ! $this->cart() instanceof EE_Cart) {
859
+        if ( ! $clear_session && ! $this->cart() instanceof EE_Cart) {
860 860
             return false;
861 861
         }
862 862
         $transaction = $this->transaction();
863 863
         if ($transaction instanceof EE_Transaction) {
864
-            if (! $transaction->ID()) {
864
+            if ( ! $transaction->ID()) {
865 865
                 $transaction->save();
866 866
             }
867 867
             $this->_session_data['transaction'] = $transaction->ID();
@@ -875,14 +875,14 @@  discard block
 block discarded – undo
875 875
         // maybe save hash check
876 876
         if (apply_filters('FHEE__EE_Session___perform_session_id_hash_check', WP_DEBUG)) {
877 877
             $this->cache_storage->add(
878
-                EE_Session::hash_check_prefix . $this->_sid,
878
+                EE_Session::hash_check_prefix.$this->_sid,
879 879
                 md5($session_data),
880 880
                 $this->_lifespan
881 881
             );
882 882
         }
883 883
         // we're using the Transient API for storing session data,
884 884
         return $this->cache_storage->add(
885
-            EE_Session::session_id_prefix . $this->_sid,
885
+            EE_Session::session_id_prefix.$this->_sid,
886 886
             $session_data,
887 887
             $this->_lifespan
888 888
         );
@@ -911,8 +911,8 @@  discard block
 block discarded – undo
911 911
             'REMOTE_ADDR',
912 912
         );
913 913
         foreach ($server_keys as $key) {
914
-            if (isset($_SERVER[ $key ])) {
915
-                foreach (array_map('trim', explode(',', $_SERVER[ $key ])) as $ip) {
914
+            if (isset($_SERVER[$key])) {
915
+                foreach (array_map('trim', explode(',', $_SERVER[$key])) as $ip) {
916 916
                     if ($ip === '127.0.0.1' || filter_var($ip, FILTER_VALIDATE_IP) !== false) {
917 917
                         $visitor_ip = $ip;
918 918
                     }
@@ -931,7 +931,7 @@  discard block
 block discarded – undo
931 931
      */
932 932
     public function _get_page_visit()
933 933
     {
934
-        $page_visit = home_url('/') . 'wp-admin/admin-ajax.php';
934
+        $page_visit = home_url('/').'wp-admin/admin-ajax.php';
935 935
         // check for request url
936 936
         if (isset($_SERVER['REQUEST_URI'])) {
937 937
             $http_host   = '';
@@ -947,14 +947,14 @@  discard block
 block discarded – undo
947 947
             // check for page_id in SERVER REQUEST
948 948
             if (isset($_REQUEST['page_id'])) {
949 949
                 // rebuild $e_reg without any of the extra parameters
950
-                $page_id = '?page_id=' . esc_attr($_REQUEST['page_id']) . '&amp;';
950
+                $page_id = '?page_id='.esc_attr($_REQUEST['page_id']).'&amp;';
951 951
             }
952 952
             // check for $e_reg in SERVER REQUEST
953 953
             if (isset($_REQUEST['ee'])) {
954 954
                 // rebuild $e_reg without any of the extra parameters
955
-                $e_reg = 'ee=' . esc_attr($_REQUEST['ee']);
955
+                $e_reg = 'ee='.esc_attr($_REQUEST['ee']);
956 956
             }
957
-            $page_visit = rtrim($http_host . $request_uri . $page_id . $e_reg, '?');
957
+            $page_visit = rtrim($http_host.$request_uri.$page_id.$e_reg, '?');
958 958
         }
959 959
         return $page_visit !== home_url('/wp-admin/admin-ajax.php') ? $page_visit : '';
960 960
     }
@@ -990,7 +990,7 @@  discard block
 block discarded – undo
990 990
     public function clear_session($class = '', $function = '')
991 991
     {
992 992
         //echo '<h3 style="color:#999;line-height:.9em;"><span style="color:#2EA2CC">' . __CLASS__ . '</span>::<span style="color:#E76700">' . __FUNCTION__ . '( ' . $class . '::' . $function . '() )</span><br/><span style="font-size:9px;font-weight:normal;">' . __FILE__ . '</span>    <b style="font-size:10px;">  ' . __LINE__ . ' </b></h3>';
993
-        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : ' . $class . '::' . $function . '()');
993
+        do_action('AHEE_log', __FILE__, __FUNCTION__, 'session cleared by : '.$class.'::'.$function.'()');
994 994
         $this->reset_cart();
995 995
         $this->reset_checkout();
996 996
         $this->reset_transaction();
@@ -1013,7 +1013,7 @@  discard block
 block discarded – undo
1013 1013
     public function reset_data($data_to_reset = array(), $show_all_notices = false)
1014 1014
     {
1015 1015
         // if $data_to_reset is not in an array, then put it in one
1016
-        if (! is_array($data_to_reset)) {
1016
+        if ( ! is_array($data_to_reset)) {
1017 1017
             $data_to_reset = array($data_to_reset);
1018 1018
         }
1019 1019
         // nothing ??? go home!
@@ -1027,11 +1027,11 @@  discard block
 block discarded – undo
1027 1027
         foreach ($data_to_reset as $reset) {
1028 1028
 
1029 1029
             // first check to make sure it is a valid session var
1030
-            if (isset($this->_session_data[ $reset ])) {
1030
+            if (isset($this->_session_data[$reset])) {
1031 1031
                 // then check to make sure it is not a default var
1032
-                if (! array_key_exists($reset, $this->_default_session_vars)) {
1032
+                if ( ! array_key_exists($reset, $this->_default_session_vars)) {
1033 1033
                     // remove session var
1034
-                    unset($this->_session_data[ $reset ]);
1034
+                    unset($this->_session_data[$reset]);
1035 1035
                     if ($show_all_notices) {
1036 1036
                         EE_Error::add_success(sprintf(__('The session variable %s was removed.', 'event_espresso'),
1037 1037
                             $reset), __FILE__, __FUNCTION__, __LINE__);
@@ -1111,7 +1111,7 @@  discard block
 block discarded – undo
1111 1111
             // or use that for the new transient cleanup query limit
1112 1112
             add_filter(
1113 1113
                 'FHEE__TransientCacheStorage__clearExpiredTransients__limit',
1114
-                function () use ($expired_session_transient_delete_query_limit)
1114
+                function() use ($expired_session_transient_delete_query_limit)
1115 1115
                 {
1116 1116
                     return $expired_session_transient_delete_query_limit;
1117 1117
                 }
@@ -1131,7 +1131,7 @@  discard block
 block discarded – undo
1131 1131
         $error = '<pre>';
1132 1132
         $data2 = preg_replace_callback(
1133 1133
             '!s:(\d+):"(.*?)";!',
1134
-            function ($match)
1134
+            function($match)
1135 1135
             {
1136 1136
                 return ($match[1] === strlen($match[2]))
1137 1137
                     ? $match[0]
@@ -1143,14 +1143,14 @@  discard block
 block discarded – undo
1143 1143
             },
1144 1144
             $data1
1145 1145
         );
1146
-        $max   = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1147
-        $error .= $data1 . PHP_EOL;
1148
-        $error .= $data2 . PHP_EOL;
1146
+        $max = (strlen($data1) > strlen($data2)) ? strlen($data1) : strlen($data2);
1147
+        $error .= $data1.PHP_EOL;
1148
+        $error .= $data2.PHP_EOL;
1149 1149
         for ($i = 0; $i < $max; $i++) {
1150
-            if (@$data1[ $i ] !== @$data2[ $i ]) {
1151
-                $error  .= 'Difference ' . @$data1[ $i ] . ' != ' . @$data2[ $i ] . PHP_EOL;
1152
-                $error  .= "\t-> ORD number " . ord(@$data1[ $i ]) . ' != ' . ord(@$data2[ $i ]) . PHP_EOL;
1153
-                $error  .= "\t-> Line Number = $i" . PHP_EOL;
1150
+            if (@$data1[$i] !== @$data2[$i]) {
1151
+                $error  .= 'Difference '.@$data1[$i].' != '.@$data2[$i].PHP_EOL;
1152
+                $error  .= "\t-> ORD number ".ord(@$data1[$i]).' != '.ord(@$data2[$i]).PHP_EOL;
1153
+                $error  .= "\t-> Line Number = $i".PHP_EOL;
1154 1154
                 $start  = ($i - 20);
1155 1155
                 $start  = ($start < 0) ? 0 : $start;
1156 1156
                 $length = 40;
@@ -1165,7 +1165,7 @@  discard block
 block discarded – undo
1165 1165
                 $error .= "\t-> Section Data1  = ";
1166 1166
                 $error .= substr_replace(
1167 1167
                     substr($data1, $start, $length),
1168
-                    "<b style=\"color:green\">{$data1[ $i ]}</b>",
1168
+                    "<b style=\"color:green\">{$data1[$i]}</b>",
1169 1169
                     $rpoint,
1170 1170
                     $rlength
1171 1171
                 );
@@ -1173,7 +1173,7 @@  discard block
 block discarded – undo
1173 1173
                 $error .= "\t-> Section Data2  = ";
1174 1174
                 $error .= substr_replace(
1175 1175
                     substr($data2, $start, $length),
1176
-                    "<b style=\"color:red\">{$data2[ $i ]}</b>",
1176
+                    "<b style=\"color:red\">{$data2[$i]}</b>",
1177 1177
                     $rpoint,
1178 1178
                     $rlength
1179 1179
                 );
@@ -1204,7 +1204,7 @@  discard block
 block discarded – undo
1204 1204
     public function garbageCollection()
1205 1205
     {
1206 1206
         // only perform during regular requests if last garbage collection was over an hour ago
1207
-        if (! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1207
+        if ( ! (defined('DOING_AJAX') && DOING_AJAX) && (time() - HOUR_IN_SECONDS) >= $this->_last_gc) {
1208 1208
             $this->_last_gc = time();
1209 1209
             $this->updateSessionSettings(array('last_gc' => $this->_last_gc));
1210 1210
             /** @type WPDB $wpdb */
@@ -1239,7 +1239,7 @@  discard block
 block discarded – undo
1239 1239
                 // AND option_value < 1508368198 LIMIT 50
1240 1240
                 $expired_sessions = $wpdb->get_col($SQL);
1241 1241
                 // valid results?
1242
-                if (! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1242
+                if ( ! $expired_sessions instanceof WP_Error && ! empty($expired_sessions)) {
1243 1243
                     $this->cache_storage->deleteMany($expired_sessions, true);
1244 1244
                 }
1245 1245
             }
Please login to merge, or discard this patch.
modules/core_rest_api/EED_Core_Rest_Api.module.php 1 patch
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -1,5 +1,4 @@
 block discarded – undo
1 1
 <?php
2
-use EventEspresso\core\domain\entities\notifications\PersistentAdminNotice;
3 2
 use EventEspresso\core\domain\services\factories\EmailAddressFactory;
4 3
 use EventEspresso\core\domain\services\validation\email\EmailValidationException;
5 4
 use EventEspresso\core\exceptions\InvalidDataTypeException;
Please login to merge, or discard this patch.
modules/messages/EED_Messages.module.php 2 patches
Indentation   +1239 added lines, -1239 removed lines patch added patch discarded remove patch
@@ -18,1254 +18,1254 @@
 block discarded – undo
18 18
 class EED_Messages extends EED_Module
19 19
 {
20 20
 
21
-    /**
22
-     * This holds the EE_messages controller
23
-     *
24
-     * @deprecated 4.9.0
25
-     * @var EE_messages $_EEMSG
26
-     */
27
-    protected static $_EEMSG;
28
-
29
-    /**
30
-     * @type EE_Message_Resource_Manager $_message_resource_manager
31
-     */
32
-    protected static $_message_resource_manager;
33
-
34
-    /**
35
-     * This holds the EE_Messages_Processor business class.
36
-     *
37
-     * @type EE_Messages_Processor
38
-     */
39
-    protected static $_MSG_PROCESSOR;
40
-
41
-    /**
42
-     * holds all the paths for various messages components.
43
-     * Utilized by autoloader registry
44
-     *
45
-     * @var array
46
-     */
47
-    protected static $_MSG_PATHS;
48
-
49
-
50
-    /**
51
-     * This will hold an array of messages template packs that are registered in the messages system.
52
-     * Format is:
53
-     * array(
54
-     *    'template_pack_dbref' => EE_Messages_Template_Pack (instance)
55
-     * )
56
-     *
57
-     * @var EE_Messages_Template_Pack[]
58
-     */
59
-    protected static $_TMP_PACKS = array();
60
-
61
-
62
-    /**
63
-     * @return EED_Messages
64
-     */
65
-    public static function instance()
66
-    {
67
-        return parent::get_instance(__CLASS__);
68
-    }
69
-
70
-
71
-    /**
72
-     *  set_hooks - for hooking into EE Core, other modules, etc
73
-     *
74
-     * @since 4.5.0
75
-     * @return    void
76
-     */
77
-    public static function set_hooks()
78
-    {
79
-        //actions
80
-        add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', array('EED_Messages', 'payment'), 10, 2);
81
-        add_action('AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
82
-            array('EED_Messages', 'maybe_registration'), 10, 2);
83
-        //filters
84
-        add_filter('FHEE__EE_Registration__receipt_url__receipt_url',
85
-            array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
86
-        add_filter('FHEE__EE_Registration__invoice_url__invoice_url',
87
-            array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
88
-        //register routes
89
-        self::_register_routes();
90
-    }
91
-
92
-    /**
93
-     *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
94
-     *
95
-     * @access    public
96
-     * @return    void
97
-     */
98
-    public static function set_hooks_admin()
99
-    {
100
-        //actions
101
-        add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', array('EED_Messages', 'payment'), 10, 2);
102
-        add_action('AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
103
-            array('EED_Messages', 'payment_reminder'), 10);
104
-        add_action('AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
105
-            array('EED_Messages', 'maybe_registration'), 10, 3);
106
-        add_action('AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
107
-            array('EED_Messages', 'send_newsletter_message'), 10, 2);
108
-        add_action('AHEE__EES_Espresso_Cancelled__process_shortcode__transaction',
109
-            array('EED_Messages', 'cancelled_registration'), 10);
110
-        add_action('AHEE__EE_Admin_Page___process_admin_payment_notification',
111
-            array('EED_Messages', 'process_admin_payment'), 10, 1);
112
-        //filters
113
-        add_filter('FHEE__EE_Admin_Page___process_resend_registration__success',
114
-            array('EED_Messages', 'process_resend'), 10, 2);
115
-        add_filter('FHEE__EE_Registration__receipt_url__receipt_url',
116
-            array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
117
-        add_filter('FHEE__EE_Registration__invoice_url__invoice_url',
118
-            array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
119
-    }
120
-
121
-
122
-    /**
123
-     * All the message triggers done by route go in here.
124
-     *
125
-     * @since 4.5.0
126
-     * @return void
127
-     */
128
-    protected static function _register_routes()
129
-    {
130
-        EE_Config::register_route('msg_url_trigger', 'Messages', 'run');
131
-        EE_Config::register_route('msg_cron_trigger', 'Messages', 'execute_batch_request');
132
-        EE_Config::register_route('msg_browser_trigger', 'Messages', 'browser_trigger');
133
-        EE_Config::register_route('msg_browser_error_trigger', 'Messages', 'browser_error_trigger');
134
-        do_action('AHEE__EED_Messages___register_routes');
135
-    }
136
-
137
-
138
-    /**
139
-     * This is called when a browser display trigger is executed.
140
-     * The browser display trigger is typically used when a already generated message is displayed directly in the
141
-     * browser.
142
-     *
143
-     * @since 4.9.0
144
-     * @param WP $WP
145
-     * @throws EE_Error
146
-     * @throws InvalidArgumentException
147
-     * @throws ReflectionException
148
-     * @throws InvalidDataTypeException
149
-     * @throws InvalidInterfaceException
150
-     */
151
-    public function browser_trigger($WP)
152
-    {
153
-        //ensure controller is loaded
154
-        self::_load_controller();
155
-        $token = EE_Registry::instance()->REQ->get('token');
156
-        try {
157
-            $mtg = new EE_Message_Generated_From_Token($token, 'html', self::$_message_resource_manager);
158
-            self::$_MSG_PROCESSOR->generate_and_send_now($mtg);
159
-        } catch (EE_Error $e) {
160
-            $error_msg = __('Please note that a system message failed to send due to a technical issue.',
161
-                'event_espresso');
162
-            // add specific message for developers if WP_DEBUG in on
163
-            $error_msg .= '||' . $e->getMessage();
164
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
165
-        }
166
-    }
167
-
168
-
169
-    /**
170
-     * This is called when a browser error trigger is executed.
171
-     * When triggered this will grab the EE_Message matching the token in the request and use that to get the error
172
-     * message and display it.
173
-     *
174
-     * @since 4.9.0
175
-     * @param $WP
176
-     * @throws EE_Error
177
-     * @throws InvalidArgumentException
178
-     * @throws InvalidDataTypeException
179
-     * @throws InvalidInterfaceException
180
-     */
181
-    public function browser_error_trigger($WP)
182
-    {
183
-        $token = EE_Registry::instance()->REQ->get('token');
184
-        if ($token) {
185
-            $message = EEM_Message::instance()->get_one_by_token($token);
186
-            if ($message instanceof EE_Message) {
187
-                header('HTTP/1.1 200 OK');
188
-                $error_msg = nl2br($message->error_message());
189
-                ?>
21
+	/**
22
+	 * This holds the EE_messages controller
23
+	 *
24
+	 * @deprecated 4.9.0
25
+	 * @var EE_messages $_EEMSG
26
+	 */
27
+	protected static $_EEMSG;
28
+
29
+	/**
30
+	 * @type EE_Message_Resource_Manager $_message_resource_manager
31
+	 */
32
+	protected static $_message_resource_manager;
33
+
34
+	/**
35
+	 * This holds the EE_Messages_Processor business class.
36
+	 *
37
+	 * @type EE_Messages_Processor
38
+	 */
39
+	protected static $_MSG_PROCESSOR;
40
+
41
+	/**
42
+	 * holds all the paths for various messages components.
43
+	 * Utilized by autoloader registry
44
+	 *
45
+	 * @var array
46
+	 */
47
+	protected static $_MSG_PATHS;
48
+
49
+
50
+	/**
51
+	 * This will hold an array of messages template packs that are registered in the messages system.
52
+	 * Format is:
53
+	 * array(
54
+	 *    'template_pack_dbref' => EE_Messages_Template_Pack (instance)
55
+	 * )
56
+	 *
57
+	 * @var EE_Messages_Template_Pack[]
58
+	 */
59
+	protected static $_TMP_PACKS = array();
60
+
61
+
62
+	/**
63
+	 * @return EED_Messages
64
+	 */
65
+	public static function instance()
66
+	{
67
+		return parent::get_instance(__CLASS__);
68
+	}
69
+
70
+
71
+	/**
72
+	 *  set_hooks - for hooking into EE Core, other modules, etc
73
+	 *
74
+	 * @since 4.5.0
75
+	 * @return    void
76
+	 */
77
+	public static function set_hooks()
78
+	{
79
+		//actions
80
+		add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', array('EED_Messages', 'payment'), 10, 2);
81
+		add_action('AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
82
+			array('EED_Messages', 'maybe_registration'), 10, 2);
83
+		//filters
84
+		add_filter('FHEE__EE_Registration__receipt_url__receipt_url',
85
+			array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
86
+		add_filter('FHEE__EE_Registration__invoice_url__invoice_url',
87
+			array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
88
+		//register routes
89
+		self::_register_routes();
90
+	}
91
+
92
+	/**
93
+	 *    set_hooks_admin - for hooking into EE Admin Core, other modules, etc
94
+	 *
95
+	 * @access    public
96
+	 * @return    void
97
+	 */
98
+	public static function set_hooks_admin()
99
+	{
100
+		//actions
101
+		add_action('AHEE__EE_Payment_Processor__update_txn_based_on_payment', array('EED_Messages', 'payment'), 10, 2);
102
+		add_action('AHEE__Transactions_Admin_Page___send_payment_reminder__process_admin_payment_reminder',
103
+			array('EED_Messages', 'payment_reminder'), 10);
104
+		add_action('AHEE__EE_Registration_Processor__trigger_registration_update_notifications',
105
+			array('EED_Messages', 'maybe_registration'), 10, 3);
106
+		add_action('AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send__with_registrations',
107
+			array('EED_Messages', 'send_newsletter_message'), 10, 2);
108
+		add_action('AHEE__EES_Espresso_Cancelled__process_shortcode__transaction',
109
+			array('EED_Messages', 'cancelled_registration'), 10);
110
+		add_action('AHEE__EE_Admin_Page___process_admin_payment_notification',
111
+			array('EED_Messages', 'process_admin_payment'), 10, 1);
112
+		//filters
113
+		add_filter('FHEE__EE_Admin_Page___process_resend_registration__success',
114
+			array('EED_Messages', 'process_resend'), 10, 2);
115
+		add_filter('FHEE__EE_Registration__receipt_url__receipt_url',
116
+			array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
117
+		add_filter('FHEE__EE_Registration__invoice_url__invoice_url',
118
+			array('EED_Messages', 'registration_message_trigger_url'), 10, 4);
119
+	}
120
+
121
+
122
+	/**
123
+	 * All the message triggers done by route go in here.
124
+	 *
125
+	 * @since 4.5.0
126
+	 * @return void
127
+	 */
128
+	protected static function _register_routes()
129
+	{
130
+		EE_Config::register_route('msg_url_trigger', 'Messages', 'run');
131
+		EE_Config::register_route('msg_cron_trigger', 'Messages', 'execute_batch_request');
132
+		EE_Config::register_route('msg_browser_trigger', 'Messages', 'browser_trigger');
133
+		EE_Config::register_route('msg_browser_error_trigger', 'Messages', 'browser_error_trigger');
134
+		do_action('AHEE__EED_Messages___register_routes');
135
+	}
136
+
137
+
138
+	/**
139
+	 * This is called when a browser display trigger is executed.
140
+	 * The browser display trigger is typically used when a already generated message is displayed directly in the
141
+	 * browser.
142
+	 *
143
+	 * @since 4.9.0
144
+	 * @param WP $WP
145
+	 * @throws EE_Error
146
+	 * @throws InvalidArgumentException
147
+	 * @throws ReflectionException
148
+	 * @throws InvalidDataTypeException
149
+	 * @throws InvalidInterfaceException
150
+	 */
151
+	public function browser_trigger($WP)
152
+	{
153
+		//ensure controller is loaded
154
+		self::_load_controller();
155
+		$token = EE_Registry::instance()->REQ->get('token');
156
+		try {
157
+			$mtg = new EE_Message_Generated_From_Token($token, 'html', self::$_message_resource_manager);
158
+			self::$_MSG_PROCESSOR->generate_and_send_now($mtg);
159
+		} catch (EE_Error $e) {
160
+			$error_msg = __('Please note that a system message failed to send due to a technical issue.',
161
+				'event_espresso');
162
+			// add specific message for developers if WP_DEBUG in on
163
+			$error_msg .= '||' . $e->getMessage();
164
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
165
+		}
166
+	}
167
+
168
+
169
+	/**
170
+	 * This is called when a browser error trigger is executed.
171
+	 * When triggered this will grab the EE_Message matching the token in the request and use that to get the error
172
+	 * message and display it.
173
+	 *
174
+	 * @since 4.9.0
175
+	 * @param $WP
176
+	 * @throws EE_Error
177
+	 * @throws InvalidArgumentException
178
+	 * @throws InvalidDataTypeException
179
+	 * @throws InvalidInterfaceException
180
+	 */
181
+	public function browser_error_trigger($WP)
182
+	{
183
+		$token = EE_Registry::instance()->REQ->get('token');
184
+		if ($token) {
185
+			$message = EEM_Message::instance()->get_one_by_token($token);
186
+			if ($message instanceof EE_Message) {
187
+				header('HTTP/1.1 200 OK');
188
+				$error_msg = nl2br($message->error_message());
189
+				?>
190 190
                 <!DOCTYPE html>
191 191
                 <html>
192 192
                 <head></head>
193 193
                 <body>
194 194
                 <?php echo empty($error_msg)
195
-                    ? esc_html__('Unfortunately, we were unable to capture the error message for this message.',
196
-                        'event_espresso')
197
-                    : wp_kses(
198
-                        $error_msg,
199
-                        array(
200
-                            'a'      => array(
201
-                                'href'  => array(),
202
-                                'title' => array(),
203
-                            ),
204
-                            'span'   => array(),
205
-                            'div'    => array(),
206
-                            'p'      => array(),
207
-                            'strong' => array(),
208
-                            'em'     => array(),
209
-                            'br'     => array(),
210
-                        )
211
-                    ); ?>
195
+					? esc_html__('Unfortunately, we were unable to capture the error message for this message.',
196
+						'event_espresso')
197
+					: wp_kses(
198
+						$error_msg,
199
+						array(
200
+							'a'      => array(
201
+								'href'  => array(),
202
+								'title' => array(),
203
+							),
204
+							'span'   => array(),
205
+							'div'    => array(),
206
+							'p'      => array(),
207
+							'strong' => array(),
208
+							'em'     => array(),
209
+							'br'     => array(),
210
+						)
211
+					); ?>
212 212
                 </body>
213 213
                 </html>
214 214
                 <?php
215
-                exit;
216
-            }
217
-        }
218
-        return;
219
-    }
220
-
221
-
222
-    /**
223
-     *  This runs when the msg_url_trigger route has initiated.
224
-     *
225
-     * @since 4.5.0
226
-     * @param WP $WP
227
-     * @throws EE_Error
228
-     * @throws InvalidArgumentException
229
-     * @throws ReflectionException
230
-     * @throws InvalidDataTypeException
231
-     * @throws InvalidInterfaceException
232
-     */
233
-    public function run($WP)
234
-    {
235
-        //ensure controller is loaded
236
-        self::_load_controller();
237
-        // attempt to process message
238
-        try {
239
-            /** @type EE_Message_To_Generate_From_Request $message_to_generate */
240
-            $message_to_generate = EE_Registry::instance()->load_lib('Message_To_Generate_From_Request');
241
-            self::$_MSG_PROCESSOR->generate_and_send_now($message_to_generate);
242
-        } catch (EE_Error $e) {
243
-            $error_msg = __('Please note that a system message failed to send due to a technical issue.',
244
-                'event_espresso');
245
-            // add specific message for developers if WP_DEBUG in on
246
-            $error_msg .= '||' . $e->getMessage();
247
-            EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
248
-        }
249
-    }
250
-
251
-
252
-    /**
253
-     * This is triggered by the 'msg_cron_trigger' route.
254
-     *
255
-     * @param WP $WP
256
-     */
257
-    public function execute_batch_request($WP)
258
-    {
259
-        $this->run_cron();
260
-        header('HTTP/1.1 200 OK');
261
-        exit();
262
-    }
263
-
264
-
265
-    /**
266
-     * This gets executed on wp_cron jobs or when a batch request is initiated on its own separate non regular wp
267
-     * request.
268
-     */
269
-    public function run_cron()
270
-    {
271
-        self::_load_controller();
272
-        //get required vars
273
-        $cron_type     = EE_Registry::instance()->REQ->get('type');
274
-        $transient_key = EE_Registry::instance()->REQ->get('key');
275
-
276
-        //now let's verify transient, if not valid exit immediately
277
-        if (! get_transient($transient_key)) {
278
-            /**
279
-             * trigger error so this gets in the error logs.  This is important because it happens on a non-user
280
-             * request.
281
-             */
282
-            trigger_error(esc_attr__('Invalid Request (Transient does not exist)', 'event_espresso'));
283
-        }
284
-
285
-        //if made it here, lets' delete the transient to keep the db clean
286
-        delete_transient($transient_key);
287
-
288
-        if (apply_filters('FHEE__EED_Messages__run_cron__use_wp_cron', true)) {
289
-
290
-            $method = 'batch_' . $cron_type . '_from_queue';
291
-            if (method_exists(self::$_MSG_PROCESSOR, $method)) {
292
-                self::$_MSG_PROCESSOR->$method();
293
-            } else {
294
-                //no matching task
295
-                /**
296
-                 * trigger error so this gets in the error logs.  This is important because it happens on a non user
297
-                 * request.
298
-                 */
299
-                trigger_error(esc_attr(sprintf(__('There is no task corresponding to this route %s', 'event_espresso'),
300
-                    $cron_type)));
301
-            }
302
-        }
303
-
304
-        do_action('FHEE__EED_Messages__run_cron__end');
305
-    }
306
-
307
-
308
-    /**
309
-     * This is used to retrieve the template pack for the given name.
310
-     * Retrieved packs are cached on the static $_TMP_PACKS array.  If there is no class matching the given name then
311
-     * the default template pack is returned.
312
-     *
313
-     * @deprecated 4.9.0  @see EEH_MSG_Template::get_template_pack()
314
-     * @param string $template_pack_name This should correspond to the dbref of the template pack (which is also used
315
-     *                                   in generating the Pack class name).
316
-     * @return EE_Messages_Template_Pack
317
-     * @throws EE_Error
318
-     * @throws InvalidArgumentException
319
-     * @throws ReflectionException
320
-     * @throws InvalidDataTypeException
321
-     * @throws InvalidInterfaceException
322
-     */
323
-    public static function get_template_pack($template_pack_name)
324
-    {
325
-        EE_Registry::instance()->load_helper('MSG_Template');
326
-        return EEH_MSG_Template::get_template_pack($template_pack_name);
327
-    }
328
-
329
-
330
-    /**
331
-     * Retrieves an array of all template packs.
332
-     * Array is in the format array( 'dbref' => EE_Messages_Template_Pack )
333
-     *
334
-     * @deprecated 4.9.0  @see EEH_MSG_Template_Pack::get_template_pack_collection
335
-     * @return EE_Messages_Template_Pack[]
336
-     * @throws EE_Error
337
-     * @throws InvalidArgumentException
338
-     * @throws ReflectionException
339
-     * @throws InvalidDataTypeException
340
-     * @throws InvalidInterfaceException
341
-     */
342
-    public static function get_template_packs()
343
-    {
344
-        EE_Registry::instance()->load_helper('MSG_Template');
345
-
346
-        //for backward compat, let's make sure this returns in the same format as originally.
347
-        $template_pack_collection = EEH_MSG_Template::get_template_pack_collection();
348
-        $template_pack_collection->rewind();
349
-        $template_packs = array();
350
-        while ($template_pack_collection->valid()) {
351
-            $template_packs[$template_pack_collection->current()->dbref] = $template_pack_collection->current();
352
-            $template_pack_collection->next();
353
-        }
354
-        return $template_packs;
355
-    }
356
-
357
-
358
-    /**
359
-     * This simply makes sure the autoloaders are registered for the EE_messages system.
360
-     *
361
-     * @since 4.5.0
362
-     * @return void
363
-     * @throws EE_Error
364
-     */
365
-    public static function set_autoloaders()
366
-    {
367
-        if (empty(self::$_MSG_PATHS)) {
368
-            self::_set_messages_paths();
369
-            foreach (self::$_MSG_PATHS as $path) {
370
-                EEH_Autoloader::register_autoloaders_for_each_file_in_folder($path);
371
-            }
372
-            // add aliases
373
-            EEH_Autoloader::add_alias('EE_messages', 'EE_messages');
374
-            EEH_Autoloader::add_alias('EE_messenger', 'EE_messenger');
375
-        }
376
-    }
377
-
378
-
379
-    /**
380
-     * Take care of adding all the paths for the messages components to the $_MSG_PATHS property
381
-     * for use by the Messages Autoloaders
382
-     *
383
-     * @since 4.5.0
384
-     * @return void.
385
-     */
386
-    protected static function _set_messages_paths()
387
-    {
388
-        $dir_ref = array(
389
-            'messages/message_type',
390
-            'messages/messenger',
391
-            'messages/defaults',
392
-            'messages/defaults/email',
393
-            'messages/data_class',
394
-            'messages/validators',
395
-            'messages/validators/email',
396
-            'messages/validators/html',
397
-            'shortcodes',
398
-        );
399
-        $paths   = array();
400
-        foreach ($dir_ref as $index => $dir) {
401
-            $paths[$index] = EE_LIBRARIES . $dir;
402
-        }
403
-        self::$_MSG_PATHS = apply_filters('FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths);
404
-    }
405
-
406
-
407
-    /**
408
-     * Takes care of loading dependencies
409
-     *
410
-     * @since 4.5.0
411
-     * @return void
412
-     * @throws EE_Error
413
-     * @throws InvalidArgumentException
414
-     * @throws ReflectionException
415
-     * @throws InvalidDataTypeException
416
-     * @throws InvalidInterfaceException
417
-     */
418
-    protected static function _load_controller()
419
-    {
420
-        if (! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
421
-            EE_Registry::instance()->load_core('Request_Handler');
422
-            self::set_autoloaders();
423
-            self::$_EEMSG                    = EE_Registry::instance()->load_lib('messages');
424
-            self::$_MSG_PROCESSOR            = EE_Registry::instance()->load_lib('Messages_Processor');
425
-            self::$_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
426
-        }
427
-    }
428
-
429
-
430
-    /**
431
-     * @param EE_Transaction $transaction
432
-     * @throws EE_Error
433
-     * @throws InvalidArgumentException
434
-     * @throws InvalidDataTypeException
435
-     * @throws InvalidInterfaceException
436
-     * @throws ReflectionException
437
-     */
438
-    public static function payment_reminder(EE_Transaction $transaction)
439
-    {
440
-        self::_load_controller();
441
-        $data = array($transaction, null);
442
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers('payment_reminder', $data);
443
-    }
444
-
445
-
446
-    /**
447
-     * Any messages triggers for after successful gateway payments should go in here.
448
-     *
449
-     * @param EE_Transaction $transaction object
450
-     * @param EE_Payment|null     $payment     object
451
-     * @return void
452
-     * @throws EE_Error
453
-     * @throws InvalidArgumentException
454
-     * @throws ReflectionException
455
-     * @throws InvalidDataTypeException
456
-     * @throws InvalidInterfaceException
457
-     */
458
-    public static function payment(EE_Transaction $transaction, EE_Payment $payment = null)
459
-    {
460
-        //if there's no payment object, then we cannot do a payment type message!
461
-        if (! $payment instanceof EE_Payment) {
462
-            return;
463
-        }
464
-        self::_load_controller();
465
-        $data = array($transaction, $payment);
466
-        EE_Registry::instance()->load_helper('MSG_Template');
467
-        $message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
468
-        //if payment amount is less than 0 then switch to payment_refund message type.
469
-        $message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
470
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
471
-    }
472
-
473
-
474
-    /**
475
-     * @param EE_Transaction $transaction
476
-     * @throws EE_Error
477
-     * @throws InvalidArgumentException
478
-     * @throws InvalidDataTypeException
479
-     * @throws InvalidInterfaceException
480
-     * @throws ReflectionException
481
-     */
482
-    public static function cancelled_registration(EE_Transaction $transaction)
483
-    {
484
-        self::_load_controller();
485
-        $data = array($transaction, null);
486
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers('cancelled_registration', $data);
487
-    }
488
-
489
-
490
-
491
-    /**
492
-     * Trigger for Registration messages
493
-     * Note that what registration message type is sent depends on what the reg status is for the registrations on the
494
-     * incoming transaction.
495
-     *
496
-     * @param EE_Registration $registration
497
-     * @param array           $extra_details
498
-     * @return void
499
-     * @throws EE_Error
500
-     * @throws InvalidArgumentException
501
-     * @throws InvalidDataTypeException
502
-     * @throws InvalidInterfaceException
503
-     * @throws ReflectionException
504
-     * @throws EntityNotFoundException
505
-     */
506
-    public static function maybe_registration(EE_Registration $registration, $extra_details = array())
507
-    {
508
-
509
-        if (! self::_verify_registration_notification_send($registration, $extra_details)) {
510
-            //no messages please
511
-            return;
512
-        }
513
-
514
-        // get all non-trashed registrations so we make sure we send messages for the right status.
515
-        $all_registrations = $registration->transaction()->registrations(
516
-            array(
517
-                array('REG_deleted' => false),
518
-                'order_by' => array(
519
-                    'Event.EVT_name'     => 'ASC',
520
-                    'Attendee.ATT_lname' => 'ASC',
521
-                    'Attendee.ATT_fname' => 'ASC'
522
-                )
523
-            )
524
-        );
525
-        //cached array of statuses so we only trigger messages once per status.
526
-        $statuses_sent = array();
527
-        self::_load_controller();
528
-        $mtgs = array();
529
-
530
-        //loop through registrations and trigger messages once per status.
531
-        foreach ($all_registrations as $reg) {
532
-
533
-            //already triggered?
534
-            if (in_array($reg->status_ID(), $statuses_sent)) {
535
-                continue;
536
-            }
537
-
538
-            $message_type    = EEH_MSG_Template::convert_reg_status_to_message_type($reg->status_ID());
539
-            $mtgs            = array_merge(
540
-                    $mtgs,
541
-                    self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
542
-                            $message_type,
543
-                            array($registration->transaction(), null, $reg->status_ID())
544
-                    )
545
-            );
546
-            $statuses_sent[] = $reg->status_ID();
547
-        }
548
-
549
-        if (count($statuses_sent) > 1) {
550
-            $mtgs = array_merge(
551
-                $mtgs,
552
-                self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
553
-                    'registration_summary',
554
-                    array($registration->transaction(), null)
555
-                )
556
-            );
557
-        }
558
-
559
-        //batch queue and initiate request
560
-        self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($mtgs);
561
-        self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
562
-    }
563
-
564
-
565
-    /**
566
-     * This is a helper method used to very whether a registration notification should be sent or
567
-     * not.  Prevents duplicate notifications going out for registration context notifications.
568
-     *
569
-     * @param EE_Registration $registration  [description]
570
-     * @param array           $extra_details [description]
571
-     * @return bool          true = send away, false = nope halt the presses.
572
-     */
573
-    protected static function _verify_registration_notification_send(
574
-        EE_Registration $registration,
575
-        $extra_details = array()
576
-    ) {
577
-        //self::log(
578
-        //	__CLASS__, __FUNCTION__, __LINE__,
579
-        //	$registration->transaction(),
580
-        //	array( '$extra_details' => $extra_details )
581
-        //);
582
-        // currently only using this to send messages for the primary registrant
583
-        if (! $registration->is_primary_registrant()) {
584
-            return false;
585
-        }
586
-        // first we check if we're in admin and not doing front ajax
587
-        if (is_admin() && ! EE_FRONT_AJAX) {
588
-            //make sure appropriate admin params are set for sending messages
589
-            if (empty($_REQUEST['txn_reg_status_change']['send_notifications']) || ! absint($_REQUEST['txn_reg_status_change']['send_notifications'])) {
590
-                //no messages sent please.
591
-                return false;
592
-            }
593
-        } else {
594
-            // frontend request (either regular or via AJAX)
595
-            // TXN is NOT finalized ?
596
-            if (! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
597
-                return false;
598
-            }
599
-            // return visit but nothing changed ???
600
-            if (
601
-                isset($extra_details['revisit'], $extra_details['status_updates']) &&
602
-                $extra_details['revisit'] && ! $extra_details['status_updates']
603
-            ) {
604
-                return false;
605
-            }
606
-            // NOT sending messages && reg status is something other than "Not-Approved"
607
-            if (
608
-                ! apply_filters('FHEE__EED_Messages___maybe_registration__deliver_notifications', false) &&
609
-                $registration->status_ID() !== EEM_Registration::status_id_not_approved
610
-            ) {
611
-                return false;
612
-            }
613
-        }
614
-        // release the kraken
615
-        return true;
616
-    }
617
-
618
-
619
-    /**
620
-     * Simply returns an array indexed by Registration Status ID and the related message_type name associated with that
621
-     * status id.
622
-     *
623
-     * @deprecated 4.9.0  Use EEH_MSG_Template::reg_status_to_message_type_array()
624
-     *                    or EEH_MSG_Template::convert_reg_status_to_message_type
625
-     * @param string $reg_status
626
-     * @return array
627
-     * @throws EE_Error
628
-     * @throws InvalidArgumentException
629
-     * @throws ReflectionException
630
-     * @throws InvalidDataTypeException
631
-     * @throws InvalidInterfaceException
632
-     */
633
-    protected static function _get_reg_status_array($reg_status = '')
634
-    {
635
-        EE_Registry::instance()->load_helper('MSG_Template');
636
-        return EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
637
-            ? EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
638
-            : EEH_MSG_Template::reg_status_to_message_type_array();
639
-    }
640
-
641
-
642
-    /**
643
-     * Simply returns the payment message type for the given payment status.
644
-     *
645
-     * @deprecated 4.9.0 Use EEH_MSG_Template::payment_status_to_message_type_array
646
-     *                   or EEH_MSG_Template::convert_payment_status_to_message_type
647
-     * @param string $payment_status The payment status being matched.
648
-     * @return bool|string The payment message type slug matching the status or false if no match.
649
-     * @throws EE_Error
650
-     * @throws InvalidArgumentException
651
-     * @throws ReflectionException
652
-     * @throws InvalidDataTypeException
653
-     * @throws InvalidInterfaceException
654
-     */
655
-    protected static function _get_payment_message_type($payment_status)
656
-    {
657
-        EE_Registry::instance()->load_helper('MSG_Template');
658
-        return EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
659
-            ? EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
660
-            : false;
661
-    }
662
-
663
-
664
-    /**
665
-     * Message triggers for a resending already sent message(s) (via EE_Message list table)
666
-     *
667
-     * @access public
668
-     * @param array $req_data This is the $_POST & $_GET data sent from EE_Admin Pages
669
-     * @return bool success/fail
670
-     * @throws EE_Error
671
-     * @throws InvalidArgumentException
672
-     * @throws InvalidDataTypeException
673
-     * @throws InvalidInterfaceException
674
-     * @throws ReflectionException
675
-     */
676
-    public static function process_resend($req_data)
677
-    {
678
-        self::_load_controller();
679
-
680
-        //if $msgID in this request then skip to the new resend_message
681
-        if (EE_Registry::instance()->REQ->get('MSG_ID')) {
682
-            return self::resend_message();
683
-        }
684
-
685
-        //make sure any incoming request data is set on the REQ so that it gets picked up later.
686
-        $req_data = (array)$req_data;
687
-        foreach ($req_data as $request_key => $request_value) {
688
-            EE_Registry::instance()->REQ->set($request_key, $request_value);
689
-        }
690
-
691
-        if (! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request()) {
692
-            return false;
693
-        }
694
-
695
-        try {
696
-            self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($messages_to_send);
697
-            self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
698
-        } catch (EE_Error $e) {
699
-            EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
700
-            return false;
701
-        }
702
-        EE_Error::add_success(
703
-            __('Messages have been successfully queued for generation and sending.', 'event_espresso')
704
-        );
705
-        return true; //everything got queued.
706
-    }
707
-
708
-
709
-    /**
710
-     * Message triggers for a resending already sent message(s) (via EE_Message list table)
711
-     *
712
-     * @return bool
713
-     * @throws EE_Error
714
-     * @throws InvalidArgumentException
715
-     * @throws InvalidDataTypeException
716
-     * @throws InvalidInterfaceException
717
-     * @throws ReflectionException
718
-     */
719
-    public static function resend_message()
720
-    {
721
-        self::_load_controller();
722
-
723
-        $msgID = EE_Registry::instance()->REQ->get('MSG_ID');
724
-        if (! $msgID) {
725
-            EE_Error::add_error(__('Something went wrong because there is no "MSG_ID" value in the request',
726
-                'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
727
-            return false;
728
-        }
729
-
730
-        self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send((array)$msgID);
731
-
732
-        //setup success message.
733
-        $count_ready_for_resend = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
734
-        EE_Error::add_success(sprintf(
735
-            _n(
736
-                'There was %d message queued for resending.',
737
-                'There were %d messages queued for resending.',
738
-                $count_ready_for_resend,
739
-                'event_espresso'
740
-            ),
741
-            $count_ready_for_resend
742
-        ));
743
-        return true;
744
-    }
745
-
746
-
747
-    /**
748
-     * Message triggers for manual payment applied by admin
749
-     *
750
-     * @param  EE_Payment $payment EE_payment object
751
-     * @return bool success/fail
752
-     * @throws EE_Error
753
-     * @throws InvalidArgumentException
754
-     * @throws ReflectionException
755
-     * @throws InvalidDataTypeException
756
-     * @throws InvalidInterfaceException
757
-     */
758
-    public static function process_admin_payment(EE_Payment $payment)
759
-    {
760
-        EE_Registry::instance()->load_helper('MSG_Template');
761
-        //we need to get the transaction object
762
-        $transaction = $payment->transaction();
763
-        if ($transaction instanceof EE_Transaction) {
764
-            $data         = array($transaction, $payment);
765
-            $message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
766
-
767
-            //if payment amount is less than 0 then switch to payment_refund message type.
768
-            $message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
769
-
770
-            //if payment_refund is selected, but the status is NOT accepted.  Then change message type to false so NO message notification goes out.
771
-            $message_type = $message_type == 'payment_refund' && $payment->STS_ID() != EEM_Payment::status_id_approved ? false : $message_type;
772
-
773
-            self::_load_controller();
774
-
775
-            self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
776
-
777
-            //get count of queued for generation
778
-            $count_to_generate = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(array(
779
-                EEM_Message::status_incomplete,
780
-                EEM_Message::status_idle,
781
-            ));
782
-
783
-            if ($count_to_generate > 0 && self::$_MSG_PROCESSOR->get_queue()->get_message_repository()->count() !== 0) {
784
-                add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
785
-                return true;
786
-            } else {
787
-                $count_failed = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::instance()->stati_indicating_failed_sending());
788
-                /**
789
-                 * Verify that there are actually errors.  If not then we return a success message because the queue might have been emptied due to successful
790
-                 * IMMEDIATE generation.
791
-                 */
792
-                if ($count_failed > 0) {
793
-                    EE_Error::add_error(sprintf(
794
-                        _n(
795
-                            'The payment notification generation failed.',
796
-                            '%d payment notifications failed being sent.',
797
-                            $count_failed,
798
-                            'event_espresso'
799
-                        ),
800
-                        $count_failed
801
-                    ), __FILE__, __FUNCTION__, __LINE__);
802
-
803
-                    return false;
804
-                } else {
805
-                    add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
806
-                    return true;
807
-                }
808
-            }
809
-        } else {
810
-            EE_Error::add_error(
811
-                'Unable to generate the payment notification because the given value for the transaction is invalid.',
812
-                'event_espresso'
813
-            );
814
-            return false;
815
-        }
816
-    }
817
-
818
-
819
-    /**
820
-     * Callback for AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send_with_registrations trigger
821
-     *
822
-     * @since   4.3.0
823
-     * @param  EE_Registration[] $registrations an array of EE_Registration objects
824
-     * @param  int               $grp_id        a specific message template group id.
825
-     * @return void
826
-     * @throws EE_Error
827
-     * @throws InvalidArgumentException
828
-     * @throws InvalidDataTypeException
829
-     * @throws InvalidInterfaceException
830
-     * @throws ReflectionException
831
-     */
832
-    public static function send_newsletter_message($registrations, $grp_id)
833
-    {
834
-        //make sure mtp is id and set it in the EE_Request Handler later messages setup.
835
-        EE_Registry::instance()->REQ->set('GRP_ID', (int)$grp_id);
836
-        self::_load_controller();
837
-        self::$_MSG_PROCESSOR->generate_for_all_active_messengers('newsletter', $registrations);
838
-    }
839
-
840
-
841
-    /**
842
-     * Callback for FHEE__EE_Registration__invoice_url__invoice_url or FHEE__EE_Registration__receipt_url__receipt_url
843
-     *
844
-     * @since   4.3.0
845
-     * @param    string          $registration_message_trigger_url
846
-     * @param    EE_Registration $registration
847
-     * @param string             $messenger
848
-     * @param string             $message_type
849
-     * @return string
850
-     * @throws EE_Error
851
-     * @throws InvalidArgumentException
852
-     * @throws InvalidDataTypeException
853
-     * @throws InvalidInterfaceException
854
-     */
855
-    public static function registration_message_trigger_url(
856
-        $registration_message_trigger_url,
857
-        EE_Registration $registration,
858
-        $messenger = 'html',
859
-        $message_type = 'invoice'
860
-    ) {
861
-        // whitelist $messenger
862
-        switch ($messenger) {
863
-            case 'pdf' :
864
-                $sending_messenger    = 'pdf';
865
-                $generating_messenger = 'html';
866
-                break;
867
-            case 'html' :
868
-            default :
869
-                $sending_messenger    = 'html';
870
-                $generating_messenger = 'html';
871
-                break;
872
-        }
873
-        // whitelist $message_type
874
-        switch ($message_type) {
875
-            case 'receipt' :
876
-                $message_type = 'receipt';
877
-                break;
878
-            case 'invoice' :
879
-            default :
880
-                $message_type = 'invoice';
881
-                break;
882
-        }
883
-        // verify that both the messenger AND the message type are active
884
-        if (EEH_MSG_Template::is_messenger_active($sending_messenger) && EEH_MSG_Template::is_mt_active($message_type)) {
885
-            //need to get the correct message template group for this (i.e. is there a custom invoice for the event this registration is registered for?)
886
-            $template_query_params = array(
887
-                'MTP_is_active'    => true,
888
-                'MTP_messenger'    => $generating_messenger,
889
-                'MTP_message_type' => $message_type,
890
-                'Event.EVT_ID'     => $registration->event_ID(),
891
-            );
892
-            //get the message template group.
893
-            $msg_template_group = EEM_Message_Template_Group::instance()->get_one(array($template_query_params));
894
-            //if we don't have an EE_Message_Template_Group then return
895
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
896
-                // remove EVT_ID from query params so that global templates get picked up
897
-                unset($template_query_params['Event.EVT_ID']);
898
-                //get global template as the fallback
899
-                $msg_template_group = EEM_Message_Template_Group::instance()->get_one(array($template_query_params));
900
-            }
901
-            //if we don't have an EE_Message_Template_Group then return
902
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
903
-                return '';
904
-            }
905
-            // generate the URL
906
-            $registration_message_trigger_url = EEH_MSG_Template::generate_url_trigger(
907
-                $sending_messenger,
908
-                $generating_messenger,
909
-                'purchaser',
910
-                $message_type,
911
-                $registration,
912
-                $msg_template_group->ID(),
913
-                $registration->transaction_ID()
914
-            );
915
-
916
-        }
917
-        return $registration_message_trigger_url;
918
-    }
919
-
920
-
921
-    /**
922
-     * Use to generate and return a message preview!
923
-     *
924
-     * @param  string $type      This should correspond with a valid message type
925
-     * @param  string $context   This should correspond with a valid context for the message type
926
-     * @param  string $messenger This should correspond with a valid messenger.
927
-     * @param bool    $send      true we will do a test send using the messenger delivery, false we just do a regular
928
-     *                           preview
929
-     * @return bool|string The body of the message or if send is requested, sends.
930
-     * @throws EE_Error
931
-     * @throws InvalidArgumentException
932
-     * @throws InvalidDataTypeException
933
-     * @throws InvalidInterfaceException
934
-     * @throws ReflectionException
935
-     */
936
-    public static function preview_message($type, $context, $messenger, $send = false)
937
-    {
938
-        self::_load_controller();
939
-        $mtg                     = new EE_Message_To_Generate(
940
-            $messenger,
941
-            $type,
942
-            array(),
943
-            $context,
944
-            true
945
-        );
946
-        $generated_preview_queue = self::$_MSG_PROCESSOR->generate_for_preview($mtg, $send);
947
-        if ($generated_preview_queue instanceof EE_Messages_Queue) {
948
-            //loop through all content for the preview and remove any persisted records.
949
-            $content = '';
950
-            foreach ($generated_preview_queue->get_message_repository() as $message) {
951
-                $content = $message->content();
952
-                if ($message->ID() > 0 && $message->STS_ID() !== EEM_Message::status_failed) {
953
-                    $message->delete();
954
-                }
955
-            }
956
-            return $content;
957
-        } else {
958
-            return $generated_preview_queue;
959
-        }
960
-    }
961
-
962
-
963
-    /**
964
-     * This is a method that allows for sending a message using a messenger matching the string given and the provided
965
-     * EE_Message_Queue object.  The EE_Message_Queue object is used to create a single aggregate EE_Message via the
966
-     * content found in the EE_Message objects in the queue.
967
-     *
968
-     * @since 4.9.0
969
-     * @param string            $messenger            a string matching a valid active messenger in the system
970
-     * @param string            $message_type         Although it seems contrary to the name of the method, a message
971
-     *                                                type name is still required to send along the message type to the
972
-     *                                                messenger because this is used for determining what specific
973
-     *                                                variations might be loaded for the generated message.
974
-     * @param EE_Messages_Queue $queue
975
-     * @param string            $custom_subject       Can be used to set what the custom subject string will be on the
976
-     *                                                aggregate EE_Message object.
977
-     * @return bool success or fail.
978
-     * @throws EE_Error
979
-     * @throws InvalidArgumentException
980
-     * @throws ReflectionException
981
-     * @throws InvalidDataTypeException
982
-     * @throws InvalidInterfaceException
983
-     */
984
-    public static function send_message_with_messenger_only(
985
-        $messenger,
986
-        $message_type,
987
-        EE_Messages_Queue $queue,
988
-        $custom_subject = ''
989
-    ) {
990
-        self::_load_controller();
991
-        /** @type EE_Message_To_Generate_From_Queue $message_to_generate */
992
-        $message_to_generate = EE_Registry::instance()->load_lib(
993
-            'Message_To_Generate_From_Queue',
994
-            array(
995
-                $messenger,
996
-                $message_type,
997
-                $queue,
998
-                $custom_subject,
999
-            )
1000
-        );
1001
-        return self::$_MSG_PROCESSOR->queue_for_sending($message_to_generate);
1002
-    }
1003
-
1004
-
1005
-    /**
1006
-     * Generates Messages immediately for EE_Message IDs (but only for the correct status for generation)
1007
-     *
1008
-     * @since 4.9.0
1009
-     * @param array $message_ids An array of message ids
1010
-     * @return bool|EE_Messages_Queue false if nothing was generated, EE_Messages_Queue containing generated
1011
-     *                           messages.
1012
-     * @throws EE_Error
1013
-     * @throws InvalidArgumentException
1014
-     * @throws InvalidDataTypeException
1015
-     * @throws InvalidInterfaceException
1016
-     * @throws ReflectionException
1017
-     */
1018
-    public static function generate_now($message_ids)
1019
-    {
1020
-        self::_load_controller();
1021
-        $messages        = EEM_Message::instance()->get_all(
1022
-            array(
1023
-                0 => array(
1024
-                    'MSG_ID' => array('IN', $message_ids),
1025
-                    'STS_ID' => EEM_Message::status_incomplete,
1026
-                ),
1027
-            )
1028
-        );
1029
-        $generated_queue = false;
1030
-        if ($messages) {
1031
-            $generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue($messages);
1032
-        }
1033
-
1034
-        if (! $generated_queue instanceof EE_Messages_Queue) {
1035
-            EE_Error::add_error(
1036
-                __('The messages were not generated. This could mean there is already a batch being generated on a separate request, or because the selected messages are not ready for generation. Please wait a minute or two and try again.',
1037
-                    'event_espresso'),
1038
-                __FILE__, __FUNCTION__, __LINE__
1039
-            );
1040
-        }
1041
-        return $generated_queue;
1042
-    }
1043
-
1044
-
1045
-    /**
1046
-     * Sends messages immediately for the incoming message_ids that have the status of EEM_Message::status_resend or,
1047
-     * EEM_Message::status_idle
1048
-     *
1049
-     * @since 4.9.0
1050
-     * @param $message_ids
1051
-     * @return bool|EE_Messages_Queue false if no messages sent.
1052
-     * @throws EE_Error
1053
-     * @throws InvalidArgumentException
1054
-     * @throws InvalidDataTypeException
1055
-     * @throws InvalidInterfaceException
1056
-     * @throws ReflectionException
1057
-     */
1058
-    public static function send_now($message_ids)
1059
-    {
1060
-        self::_load_controller();
1061
-        $messages   = EEM_Message::instance()->get_all(
1062
-            array(
1063
-                0 => array(
1064
-                    'MSG_ID' => array('IN', $message_ids),
1065
-                    'STS_ID' => array(
1066
-                        'IN',
1067
-                        array(EEM_Message::status_idle, EEM_Message::status_resend, EEM_Message::status_retry),
1068
-                    ),
1069
-                ),
1070
-            )
1071
-        );
1072
-        $sent_queue = false;
1073
-        if ($messages) {
1074
-            $sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue($messages);
1075
-        }
1076
-
1077
-        if (! $sent_queue instanceof EE_Messages_Queue) {
1078
-            EE_Error::add_error(
1079
-                __('The messages were not sent. This could mean there is already a batch being sent on a separate request, or because the selected messages are not sendable. Please wait a minute or two and try again.',
1080
-                    'event_espresso'),
1081
-                __FILE__, __FUNCTION__, __LINE__
1082
-            );
1083
-        } else {
1084
-            //can count how many sent by using the messages in the queue
1085
-            $sent_count = $sent_queue->count_STS_in_queue(EEM_Message::instance()->stati_indicating_sent());
1086
-            if ($sent_count > 0) {
1087
-                EE_Error::add_success(
1088
-                    sprintf(
1089
-                        _n(
1090
-                            'There was %d message successfully sent.',
1091
-                            'There were %d messages successfully sent.',
1092
-                            $sent_count,
1093
-                            'event_espresso'
1094
-                        ),
1095
-                        $sent_count
1096
-                    )
1097
-                );
1098
-            } else {
1099
-                EE_Error::overwrite_errors();
1100
-                EE_Error::add_error(
1101
-                    __('No message was sent because of problems with sending. Either all the messages you selected were not a sendable message, they were ALREADY sent on a different scheduled task, or there was an error.
215
+				exit;
216
+			}
217
+		}
218
+		return;
219
+	}
220
+
221
+
222
+	/**
223
+	 *  This runs when the msg_url_trigger route has initiated.
224
+	 *
225
+	 * @since 4.5.0
226
+	 * @param WP $WP
227
+	 * @throws EE_Error
228
+	 * @throws InvalidArgumentException
229
+	 * @throws ReflectionException
230
+	 * @throws InvalidDataTypeException
231
+	 * @throws InvalidInterfaceException
232
+	 */
233
+	public function run($WP)
234
+	{
235
+		//ensure controller is loaded
236
+		self::_load_controller();
237
+		// attempt to process message
238
+		try {
239
+			/** @type EE_Message_To_Generate_From_Request $message_to_generate */
240
+			$message_to_generate = EE_Registry::instance()->load_lib('Message_To_Generate_From_Request');
241
+			self::$_MSG_PROCESSOR->generate_and_send_now($message_to_generate);
242
+		} catch (EE_Error $e) {
243
+			$error_msg = __('Please note that a system message failed to send due to a technical issue.',
244
+				'event_espresso');
245
+			// add specific message for developers if WP_DEBUG in on
246
+			$error_msg .= '||' . $e->getMessage();
247
+			EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
248
+		}
249
+	}
250
+
251
+
252
+	/**
253
+	 * This is triggered by the 'msg_cron_trigger' route.
254
+	 *
255
+	 * @param WP $WP
256
+	 */
257
+	public function execute_batch_request($WP)
258
+	{
259
+		$this->run_cron();
260
+		header('HTTP/1.1 200 OK');
261
+		exit();
262
+	}
263
+
264
+
265
+	/**
266
+	 * This gets executed on wp_cron jobs or when a batch request is initiated on its own separate non regular wp
267
+	 * request.
268
+	 */
269
+	public function run_cron()
270
+	{
271
+		self::_load_controller();
272
+		//get required vars
273
+		$cron_type     = EE_Registry::instance()->REQ->get('type');
274
+		$transient_key = EE_Registry::instance()->REQ->get('key');
275
+
276
+		//now let's verify transient, if not valid exit immediately
277
+		if (! get_transient($transient_key)) {
278
+			/**
279
+			 * trigger error so this gets in the error logs.  This is important because it happens on a non-user
280
+			 * request.
281
+			 */
282
+			trigger_error(esc_attr__('Invalid Request (Transient does not exist)', 'event_espresso'));
283
+		}
284
+
285
+		//if made it here, lets' delete the transient to keep the db clean
286
+		delete_transient($transient_key);
287
+
288
+		if (apply_filters('FHEE__EED_Messages__run_cron__use_wp_cron', true)) {
289
+
290
+			$method = 'batch_' . $cron_type . '_from_queue';
291
+			if (method_exists(self::$_MSG_PROCESSOR, $method)) {
292
+				self::$_MSG_PROCESSOR->$method();
293
+			} else {
294
+				//no matching task
295
+				/**
296
+				 * trigger error so this gets in the error logs.  This is important because it happens on a non user
297
+				 * request.
298
+				 */
299
+				trigger_error(esc_attr(sprintf(__('There is no task corresponding to this route %s', 'event_espresso'),
300
+					$cron_type)));
301
+			}
302
+		}
303
+
304
+		do_action('FHEE__EED_Messages__run_cron__end');
305
+	}
306
+
307
+
308
+	/**
309
+	 * This is used to retrieve the template pack for the given name.
310
+	 * Retrieved packs are cached on the static $_TMP_PACKS array.  If there is no class matching the given name then
311
+	 * the default template pack is returned.
312
+	 *
313
+	 * @deprecated 4.9.0  @see EEH_MSG_Template::get_template_pack()
314
+	 * @param string $template_pack_name This should correspond to the dbref of the template pack (which is also used
315
+	 *                                   in generating the Pack class name).
316
+	 * @return EE_Messages_Template_Pack
317
+	 * @throws EE_Error
318
+	 * @throws InvalidArgumentException
319
+	 * @throws ReflectionException
320
+	 * @throws InvalidDataTypeException
321
+	 * @throws InvalidInterfaceException
322
+	 */
323
+	public static function get_template_pack($template_pack_name)
324
+	{
325
+		EE_Registry::instance()->load_helper('MSG_Template');
326
+		return EEH_MSG_Template::get_template_pack($template_pack_name);
327
+	}
328
+
329
+
330
+	/**
331
+	 * Retrieves an array of all template packs.
332
+	 * Array is in the format array( 'dbref' => EE_Messages_Template_Pack )
333
+	 *
334
+	 * @deprecated 4.9.0  @see EEH_MSG_Template_Pack::get_template_pack_collection
335
+	 * @return EE_Messages_Template_Pack[]
336
+	 * @throws EE_Error
337
+	 * @throws InvalidArgumentException
338
+	 * @throws ReflectionException
339
+	 * @throws InvalidDataTypeException
340
+	 * @throws InvalidInterfaceException
341
+	 */
342
+	public static function get_template_packs()
343
+	{
344
+		EE_Registry::instance()->load_helper('MSG_Template');
345
+
346
+		//for backward compat, let's make sure this returns in the same format as originally.
347
+		$template_pack_collection = EEH_MSG_Template::get_template_pack_collection();
348
+		$template_pack_collection->rewind();
349
+		$template_packs = array();
350
+		while ($template_pack_collection->valid()) {
351
+			$template_packs[$template_pack_collection->current()->dbref] = $template_pack_collection->current();
352
+			$template_pack_collection->next();
353
+		}
354
+		return $template_packs;
355
+	}
356
+
357
+
358
+	/**
359
+	 * This simply makes sure the autoloaders are registered for the EE_messages system.
360
+	 *
361
+	 * @since 4.5.0
362
+	 * @return void
363
+	 * @throws EE_Error
364
+	 */
365
+	public static function set_autoloaders()
366
+	{
367
+		if (empty(self::$_MSG_PATHS)) {
368
+			self::_set_messages_paths();
369
+			foreach (self::$_MSG_PATHS as $path) {
370
+				EEH_Autoloader::register_autoloaders_for_each_file_in_folder($path);
371
+			}
372
+			// add aliases
373
+			EEH_Autoloader::add_alias('EE_messages', 'EE_messages');
374
+			EEH_Autoloader::add_alias('EE_messenger', 'EE_messenger');
375
+		}
376
+	}
377
+
378
+
379
+	/**
380
+	 * Take care of adding all the paths for the messages components to the $_MSG_PATHS property
381
+	 * for use by the Messages Autoloaders
382
+	 *
383
+	 * @since 4.5.0
384
+	 * @return void.
385
+	 */
386
+	protected static function _set_messages_paths()
387
+	{
388
+		$dir_ref = array(
389
+			'messages/message_type',
390
+			'messages/messenger',
391
+			'messages/defaults',
392
+			'messages/defaults/email',
393
+			'messages/data_class',
394
+			'messages/validators',
395
+			'messages/validators/email',
396
+			'messages/validators/html',
397
+			'shortcodes',
398
+		);
399
+		$paths   = array();
400
+		foreach ($dir_ref as $index => $dir) {
401
+			$paths[$index] = EE_LIBRARIES . $dir;
402
+		}
403
+		self::$_MSG_PATHS = apply_filters('FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths);
404
+	}
405
+
406
+
407
+	/**
408
+	 * Takes care of loading dependencies
409
+	 *
410
+	 * @since 4.5.0
411
+	 * @return void
412
+	 * @throws EE_Error
413
+	 * @throws InvalidArgumentException
414
+	 * @throws ReflectionException
415
+	 * @throws InvalidDataTypeException
416
+	 * @throws InvalidInterfaceException
417
+	 */
418
+	protected static function _load_controller()
419
+	{
420
+		if (! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
421
+			EE_Registry::instance()->load_core('Request_Handler');
422
+			self::set_autoloaders();
423
+			self::$_EEMSG                    = EE_Registry::instance()->load_lib('messages');
424
+			self::$_MSG_PROCESSOR            = EE_Registry::instance()->load_lib('Messages_Processor');
425
+			self::$_message_resource_manager = EE_Registry::instance()->load_lib('Message_Resource_Manager');
426
+		}
427
+	}
428
+
429
+
430
+	/**
431
+	 * @param EE_Transaction $transaction
432
+	 * @throws EE_Error
433
+	 * @throws InvalidArgumentException
434
+	 * @throws InvalidDataTypeException
435
+	 * @throws InvalidInterfaceException
436
+	 * @throws ReflectionException
437
+	 */
438
+	public static function payment_reminder(EE_Transaction $transaction)
439
+	{
440
+		self::_load_controller();
441
+		$data = array($transaction, null);
442
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers('payment_reminder', $data);
443
+	}
444
+
445
+
446
+	/**
447
+	 * Any messages triggers for after successful gateway payments should go in here.
448
+	 *
449
+	 * @param EE_Transaction $transaction object
450
+	 * @param EE_Payment|null     $payment     object
451
+	 * @return void
452
+	 * @throws EE_Error
453
+	 * @throws InvalidArgumentException
454
+	 * @throws ReflectionException
455
+	 * @throws InvalidDataTypeException
456
+	 * @throws InvalidInterfaceException
457
+	 */
458
+	public static function payment(EE_Transaction $transaction, EE_Payment $payment = null)
459
+	{
460
+		//if there's no payment object, then we cannot do a payment type message!
461
+		if (! $payment instanceof EE_Payment) {
462
+			return;
463
+		}
464
+		self::_load_controller();
465
+		$data = array($transaction, $payment);
466
+		EE_Registry::instance()->load_helper('MSG_Template');
467
+		$message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
468
+		//if payment amount is less than 0 then switch to payment_refund message type.
469
+		$message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
470
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
471
+	}
472
+
473
+
474
+	/**
475
+	 * @param EE_Transaction $transaction
476
+	 * @throws EE_Error
477
+	 * @throws InvalidArgumentException
478
+	 * @throws InvalidDataTypeException
479
+	 * @throws InvalidInterfaceException
480
+	 * @throws ReflectionException
481
+	 */
482
+	public static function cancelled_registration(EE_Transaction $transaction)
483
+	{
484
+		self::_load_controller();
485
+		$data = array($transaction, null);
486
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers('cancelled_registration', $data);
487
+	}
488
+
489
+
490
+
491
+	/**
492
+	 * Trigger for Registration messages
493
+	 * Note that what registration message type is sent depends on what the reg status is for the registrations on the
494
+	 * incoming transaction.
495
+	 *
496
+	 * @param EE_Registration $registration
497
+	 * @param array           $extra_details
498
+	 * @return void
499
+	 * @throws EE_Error
500
+	 * @throws InvalidArgumentException
501
+	 * @throws InvalidDataTypeException
502
+	 * @throws InvalidInterfaceException
503
+	 * @throws ReflectionException
504
+	 * @throws EntityNotFoundException
505
+	 */
506
+	public static function maybe_registration(EE_Registration $registration, $extra_details = array())
507
+	{
508
+
509
+		if (! self::_verify_registration_notification_send($registration, $extra_details)) {
510
+			//no messages please
511
+			return;
512
+		}
513
+
514
+		// get all non-trashed registrations so we make sure we send messages for the right status.
515
+		$all_registrations = $registration->transaction()->registrations(
516
+			array(
517
+				array('REG_deleted' => false),
518
+				'order_by' => array(
519
+					'Event.EVT_name'     => 'ASC',
520
+					'Attendee.ATT_lname' => 'ASC',
521
+					'Attendee.ATT_fname' => 'ASC'
522
+				)
523
+			)
524
+		);
525
+		//cached array of statuses so we only trigger messages once per status.
526
+		$statuses_sent = array();
527
+		self::_load_controller();
528
+		$mtgs = array();
529
+
530
+		//loop through registrations and trigger messages once per status.
531
+		foreach ($all_registrations as $reg) {
532
+
533
+			//already triggered?
534
+			if (in_array($reg->status_ID(), $statuses_sent)) {
535
+				continue;
536
+			}
537
+
538
+			$message_type    = EEH_MSG_Template::convert_reg_status_to_message_type($reg->status_ID());
539
+			$mtgs            = array_merge(
540
+					$mtgs,
541
+					self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
542
+							$message_type,
543
+							array($registration->transaction(), null, $reg->status_ID())
544
+					)
545
+			);
546
+			$statuses_sent[] = $reg->status_ID();
547
+		}
548
+
549
+		if (count($statuses_sent) > 1) {
550
+			$mtgs = array_merge(
551
+				$mtgs,
552
+				self::$_MSG_PROCESSOR->setup_mtgs_for_all_active_messengers(
553
+					'registration_summary',
554
+					array($registration->transaction(), null)
555
+				)
556
+			);
557
+		}
558
+
559
+		//batch queue and initiate request
560
+		self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($mtgs);
561
+		self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
562
+	}
563
+
564
+
565
+	/**
566
+	 * This is a helper method used to very whether a registration notification should be sent or
567
+	 * not.  Prevents duplicate notifications going out for registration context notifications.
568
+	 *
569
+	 * @param EE_Registration $registration  [description]
570
+	 * @param array           $extra_details [description]
571
+	 * @return bool          true = send away, false = nope halt the presses.
572
+	 */
573
+	protected static function _verify_registration_notification_send(
574
+		EE_Registration $registration,
575
+		$extra_details = array()
576
+	) {
577
+		//self::log(
578
+		//	__CLASS__, __FUNCTION__, __LINE__,
579
+		//	$registration->transaction(),
580
+		//	array( '$extra_details' => $extra_details )
581
+		//);
582
+		// currently only using this to send messages for the primary registrant
583
+		if (! $registration->is_primary_registrant()) {
584
+			return false;
585
+		}
586
+		// first we check if we're in admin and not doing front ajax
587
+		if (is_admin() && ! EE_FRONT_AJAX) {
588
+			//make sure appropriate admin params are set for sending messages
589
+			if (empty($_REQUEST['txn_reg_status_change']['send_notifications']) || ! absint($_REQUEST['txn_reg_status_change']['send_notifications'])) {
590
+				//no messages sent please.
591
+				return false;
592
+			}
593
+		} else {
594
+			// frontend request (either regular or via AJAX)
595
+			// TXN is NOT finalized ?
596
+			if (! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
597
+				return false;
598
+			}
599
+			// return visit but nothing changed ???
600
+			if (
601
+				isset($extra_details['revisit'], $extra_details['status_updates']) &&
602
+				$extra_details['revisit'] && ! $extra_details['status_updates']
603
+			) {
604
+				return false;
605
+			}
606
+			// NOT sending messages && reg status is something other than "Not-Approved"
607
+			if (
608
+				! apply_filters('FHEE__EED_Messages___maybe_registration__deliver_notifications', false) &&
609
+				$registration->status_ID() !== EEM_Registration::status_id_not_approved
610
+			) {
611
+				return false;
612
+			}
613
+		}
614
+		// release the kraken
615
+		return true;
616
+	}
617
+
618
+
619
+	/**
620
+	 * Simply returns an array indexed by Registration Status ID and the related message_type name associated with that
621
+	 * status id.
622
+	 *
623
+	 * @deprecated 4.9.0  Use EEH_MSG_Template::reg_status_to_message_type_array()
624
+	 *                    or EEH_MSG_Template::convert_reg_status_to_message_type
625
+	 * @param string $reg_status
626
+	 * @return array
627
+	 * @throws EE_Error
628
+	 * @throws InvalidArgumentException
629
+	 * @throws ReflectionException
630
+	 * @throws InvalidDataTypeException
631
+	 * @throws InvalidInterfaceException
632
+	 */
633
+	protected static function _get_reg_status_array($reg_status = '')
634
+	{
635
+		EE_Registry::instance()->load_helper('MSG_Template');
636
+		return EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
637
+			? EEH_MSG_Template::convert_reg_status_to_message_type($reg_status)
638
+			: EEH_MSG_Template::reg_status_to_message_type_array();
639
+	}
640
+
641
+
642
+	/**
643
+	 * Simply returns the payment message type for the given payment status.
644
+	 *
645
+	 * @deprecated 4.9.0 Use EEH_MSG_Template::payment_status_to_message_type_array
646
+	 *                   or EEH_MSG_Template::convert_payment_status_to_message_type
647
+	 * @param string $payment_status The payment status being matched.
648
+	 * @return bool|string The payment message type slug matching the status or false if no match.
649
+	 * @throws EE_Error
650
+	 * @throws InvalidArgumentException
651
+	 * @throws ReflectionException
652
+	 * @throws InvalidDataTypeException
653
+	 * @throws InvalidInterfaceException
654
+	 */
655
+	protected static function _get_payment_message_type($payment_status)
656
+	{
657
+		EE_Registry::instance()->load_helper('MSG_Template');
658
+		return EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
659
+			? EEH_MSG_Template::convert_payment_status_to_message_type($payment_status)
660
+			: false;
661
+	}
662
+
663
+
664
+	/**
665
+	 * Message triggers for a resending already sent message(s) (via EE_Message list table)
666
+	 *
667
+	 * @access public
668
+	 * @param array $req_data This is the $_POST & $_GET data sent from EE_Admin Pages
669
+	 * @return bool success/fail
670
+	 * @throws EE_Error
671
+	 * @throws InvalidArgumentException
672
+	 * @throws InvalidDataTypeException
673
+	 * @throws InvalidInterfaceException
674
+	 * @throws ReflectionException
675
+	 */
676
+	public static function process_resend($req_data)
677
+	{
678
+		self::_load_controller();
679
+
680
+		//if $msgID in this request then skip to the new resend_message
681
+		if (EE_Registry::instance()->REQ->get('MSG_ID')) {
682
+			return self::resend_message();
683
+		}
684
+
685
+		//make sure any incoming request data is set on the REQ so that it gets picked up later.
686
+		$req_data = (array)$req_data;
687
+		foreach ($req_data as $request_key => $request_value) {
688
+			EE_Registry::instance()->REQ->set($request_key, $request_value);
689
+		}
690
+
691
+		if (! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request()) {
692
+			return false;
693
+		}
694
+
695
+		try {
696
+			self::$_MSG_PROCESSOR->batch_queue_for_generation_and_persist($messages_to_send);
697
+			self::$_MSG_PROCESSOR->get_queue()->initiate_request_by_priority();
698
+		} catch (EE_Error $e) {
699
+			EE_Error::add_error($e->getMessage(), __FILE__, __FUNCTION__, __LINE__);
700
+			return false;
701
+		}
702
+		EE_Error::add_success(
703
+			__('Messages have been successfully queued for generation and sending.', 'event_espresso')
704
+		);
705
+		return true; //everything got queued.
706
+	}
707
+
708
+
709
+	/**
710
+	 * Message triggers for a resending already sent message(s) (via EE_Message list table)
711
+	 *
712
+	 * @return bool
713
+	 * @throws EE_Error
714
+	 * @throws InvalidArgumentException
715
+	 * @throws InvalidDataTypeException
716
+	 * @throws InvalidInterfaceException
717
+	 * @throws ReflectionException
718
+	 */
719
+	public static function resend_message()
720
+	{
721
+		self::_load_controller();
722
+
723
+		$msgID = EE_Registry::instance()->REQ->get('MSG_ID');
724
+		if (! $msgID) {
725
+			EE_Error::add_error(__('Something went wrong because there is no "MSG_ID" value in the request',
726
+				'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
727
+			return false;
728
+		}
729
+
730
+		self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send((array)$msgID);
731
+
732
+		//setup success message.
733
+		$count_ready_for_resend = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
734
+		EE_Error::add_success(sprintf(
735
+			_n(
736
+				'There was %d message queued for resending.',
737
+				'There were %d messages queued for resending.',
738
+				$count_ready_for_resend,
739
+				'event_espresso'
740
+			),
741
+			$count_ready_for_resend
742
+		));
743
+		return true;
744
+	}
745
+
746
+
747
+	/**
748
+	 * Message triggers for manual payment applied by admin
749
+	 *
750
+	 * @param  EE_Payment $payment EE_payment object
751
+	 * @return bool success/fail
752
+	 * @throws EE_Error
753
+	 * @throws InvalidArgumentException
754
+	 * @throws ReflectionException
755
+	 * @throws InvalidDataTypeException
756
+	 * @throws InvalidInterfaceException
757
+	 */
758
+	public static function process_admin_payment(EE_Payment $payment)
759
+	{
760
+		EE_Registry::instance()->load_helper('MSG_Template');
761
+		//we need to get the transaction object
762
+		$transaction = $payment->transaction();
763
+		if ($transaction instanceof EE_Transaction) {
764
+			$data         = array($transaction, $payment);
765
+			$message_type = EEH_MSG_Template::convert_payment_status_to_message_type($payment->STS_ID());
766
+
767
+			//if payment amount is less than 0 then switch to payment_refund message type.
768
+			$message_type = $payment->amount() < 0 ? 'payment_refund' : $message_type;
769
+
770
+			//if payment_refund is selected, but the status is NOT accepted.  Then change message type to false so NO message notification goes out.
771
+			$message_type = $message_type == 'payment_refund' && $payment->STS_ID() != EEM_Payment::status_id_approved ? false : $message_type;
772
+
773
+			self::_load_controller();
774
+
775
+			self::$_MSG_PROCESSOR->generate_for_all_active_messengers($message_type, $data);
776
+
777
+			//get count of queued for generation
778
+			$count_to_generate = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(array(
779
+				EEM_Message::status_incomplete,
780
+				EEM_Message::status_idle,
781
+			));
782
+
783
+			if ($count_to_generate > 0 && self::$_MSG_PROCESSOR->get_queue()->get_message_repository()->count() !== 0) {
784
+				add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
785
+				return true;
786
+			} else {
787
+				$count_failed = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::instance()->stati_indicating_failed_sending());
788
+				/**
789
+				 * Verify that there are actually errors.  If not then we return a success message because the queue might have been emptied due to successful
790
+				 * IMMEDIATE generation.
791
+				 */
792
+				if ($count_failed > 0) {
793
+					EE_Error::add_error(sprintf(
794
+						_n(
795
+							'The payment notification generation failed.',
796
+							'%d payment notifications failed being sent.',
797
+							$count_failed,
798
+							'event_espresso'
799
+						),
800
+						$count_failed
801
+					), __FILE__, __FUNCTION__, __LINE__);
802
+
803
+					return false;
804
+				} else {
805
+					add_filter('FHEE__EE_Admin_Page___process_admin_payment_notification__success', '__return_true');
806
+					return true;
807
+				}
808
+			}
809
+		} else {
810
+			EE_Error::add_error(
811
+				'Unable to generate the payment notification because the given value for the transaction is invalid.',
812
+				'event_espresso'
813
+			);
814
+			return false;
815
+		}
816
+	}
817
+
818
+
819
+	/**
820
+	 * Callback for AHEE__Extend_Registrations_Admin_Page___newsletter_selected_send_with_registrations trigger
821
+	 *
822
+	 * @since   4.3.0
823
+	 * @param  EE_Registration[] $registrations an array of EE_Registration objects
824
+	 * @param  int               $grp_id        a specific message template group id.
825
+	 * @return void
826
+	 * @throws EE_Error
827
+	 * @throws InvalidArgumentException
828
+	 * @throws InvalidDataTypeException
829
+	 * @throws InvalidInterfaceException
830
+	 * @throws ReflectionException
831
+	 */
832
+	public static function send_newsletter_message($registrations, $grp_id)
833
+	{
834
+		//make sure mtp is id and set it in the EE_Request Handler later messages setup.
835
+		EE_Registry::instance()->REQ->set('GRP_ID', (int)$grp_id);
836
+		self::_load_controller();
837
+		self::$_MSG_PROCESSOR->generate_for_all_active_messengers('newsletter', $registrations);
838
+	}
839
+
840
+
841
+	/**
842
+	 * Callback for FHEE__EE_Registration__invoice_url__invoice_url or FHEE__EE_Registration__receipt_url__receipt_url
843
+	 *
844
+	 * @since   4.3.0
845
+	 * @param    string          $registration_message_trigger_url
846
+	 * @param    EE_Registration $registration
847
+	 * @param string             $messenger
848
+	 * @param string             $message_type
849
+	 * @return string
850
+	 * @throws EE_Error
851
+	 * @throws InvalidArgumentException
852
+	 * @throws InvalidDataTypeException
853
+	 * @throws InvalidInterfaceException
854
+	 */
855
+	public static function registration_message_trigger_url(
856
+		$registration_message_trigger_url,
857
+		EE_Registration $registration,
858
+		$messenger = 'html',
859
+		$message_type = 'invoice'
860
+	) {
861
+		// whitelist $messenger
862
+		switch ($messenger) {
863
+			case 'pdf' :
864
+				$sending_messenger    = 'pdf';
865
+				$generating_messenger = 'html';
866
+				break;
867
+			case 'html' :
868
+			default :
869
+				$sending_messenger    = 'html';
870
+				$generating_messenger = 'html';
871
+				break;
872
+		}
873
+		// whitelist $message_type
874
+		switch ($message_type) {
875
+			case 'receipt' :
876
+				$message_type = 'receipt';
877
+				break;
878
+			case 'invoice' :
879
+			default :
880
+				$message_type = 'invoice';
881
+				break;
882
+		}
883
+		// verify that both the messenger AND the message type are active
884
+		if (EEH_MSG_Template::is_messenger_active($sending_messenger) && EEH_MSG_Template::is_mt_active($message_type)) {
885
+			//need to get the correct message template group for this (i.e. is there a custom invoice for the event this registration is registered for?)
886
+			$template_query_params = array(
887
+				'MTP_is_active'    => true,
888
+				'MTP_messenger'    => $generating_messenger,
889
+				'MTP_message_type' => $message_type,
890
+				'Event.EVT_ID'     => $registration->event_ID(),
891
+			);
892
+			//get the message template group.
893
+			$msg_template_group = EEM_Message_Template_Group::instance()->get_one(array($template_query_params));
894
+			//if we don't have an EE_Message_Template_Group then return
895
+			if (! $msg_template_group instanceof EE_Message_Template_Group) {
896
+				// remove EVT_ID from query params so that global templates get picked up
897
+				unset($template_query_params['Event.EVT_ID']);
898
+				//get global template as the fallback
899
+				$msg_template_group = EEM_Message_Template_Group::instance()->get_one(array($template_query_params));
900
+			}
901
+			//if we don't have an EE_Message_Template_Group then return
902
+			if (! $msg_template_group instanceof EE_Message_Template_Group) {
903
+				return '';
904
+			}
905
+			// generate the URL
906
+			$registration_message_trigger_url = EEH_MSG_Template::generate_url_trigger(
907
+				$sending_messenger,
908
+				$generating_messenger,
909
+				'purchaser',
910
+				$message_type,
911
+				$registration,
912
+				$msg_template_group->ID(),
913
+				$registration->transaction_ID()
914
+			);
915
+
916
+		}
917
+		return $registration_message_trigger_url;
918
+	}
919
+
920
+
921
+	/**
922
+	 * Use to generate and return a message preview!
923
+	 *
924
+	 * @param  string $type      This should correspond with a valid message type
925
+	 * @param  string $context   This should correspond with a valid context for the message type
926
+	 * @param  string $messenger This should correspond with a valid messenger.
927
+	 * @param bool    $send      true we will do a test send using the messenger delivery, false we just do a regular
928
+	 *                           preview
929
+	 * @return bool|string The body of the message or if send is requested, sends.
930
+	 * @throws EE_Error
931
+	 * @throws InvalidArgumentException
932
+	 * @throws InvalidDataTypeException
933
+	 * @throws InvalidInterfaceException
934
+	 * @throws ReflectionException
935
+	 */
936
+	public static function preview_message($type, $context, $messenger, $send = false)
937
+	{
938
+		self::_load_controller();
939
+		$mtg                     = new EE_Message_To_Generate(
940
+			$messenger,
941
+			$type,
942
+			array(),
943
+			$context,
944
+			true
945
+		);
946
+		$generated_preview_queue = self::$_MSG_PROCESSOR->generate_for_preview($mtg, $send);
947
+		if ($generated_preview_queue instanceof EE_Messages_Queue) {
948
+			//loop through all content for the preview and remove any persisted records.
949
+			$content = '';
950
+			foreach ($generated_preview_queue->get_message_repository() as $message) {
951
+				$content = $message->content();
952
+				if ($message->ID() > 0 && $message->STS_ID() !== EEM_Message::status_failed) {
953
+					$message->delete();
954
+				}
955
+			}
956
+			return $content;
957
+		} else {
958
+			return $generated_preview_queue;
959
+		}
960
+	}
961
+
962
+
963
+	/**
964
+	 * This is a method that allows for sending a message using a messenger matching the string given and the provided
965
+	 * EE_Message_Queue object.  The EE_Message_Queue object is used to create a single aggregate EE_Message via the
966
+	 * content found in the EE_Message objects in the queue.
967
+	 *
968
+	 * @since 4.9.0
969
+	 * @param string            $messenger            a string matching a valid active messenger in the system
970
+	 * @param string            $message_type         Although it seems contrary to the name of the method, a message
971
+	 *                                                type name is still required to send along the message type to the
972
+	 *                                                messenger because this is used for determining what specific
973
+	 *                                                variations might be loaded for the generated message.
974
+	 * @param EE_Messages_Queue $queue
975
+	 * @param string            $custom_subject       Can be used to set what the custom subject string will be on the
976
+	 *                                                aggregate EE_Message object.
977
+	 * @return bool success or fail.
978
+	 * @throws EE_Error
979
+	 * @throws InvalidArgumentException
980
+	 * @throws ReflectionException
981
+	 * @throws InvalidDataTypeException
982
+	 * @throws InvalidInterfaceException
983
+	 */
984
+	public static function send_message_with_messenger_only(
985
+		$messenger,
986
+		$message_type,
987
+		EE_Messages_Queue $queue,
988
+		$custom_subject = ''
989
+	) {
990
+		self::_load_controller();
991
+		/** @type EE_Message_To_Generate_From_Queue $message_to_generate */
992
+		$message_to_generate = EE_Registry::instance()->load_lib(
993
+			'Message_To_Generate_From_Queue',
994
+			array(
995
+				$messenger,
996
+				$message_type,
997
+				$queue,
998
+				$custom_subject,
999
+			)
1000
+		);
1001
+		return self::$_MSG_PROCESSOR->queue_for_sending($message_to_generate);
1002
+	}
1003
+
1004
+
1005
+	/**
1006
+	 * Generates Messages immediately for EE_Message IDs (but only for the correct status for generation)
1007
+	 *
1008
+	 * @since 4.9.0
1009
+	 * @param array $message_ids An array of message ids
1010
+	 * @return bool|EE_Messages_Queue false if nothing was generated, EE_Messages_Queue containing generated
1011
+	 *                           messages.
1012
+	 * @throws EE_Error
1013
+	 * @throws InvalidArgumentException
1014
+	 * @throws InvalidDataTypeException
1015
+	 * @throws InvalidInterfaceException
1016
+	 * @throws ReflectionException
1017
+	 */
1018
+	public static function generate_now($message_ids)
1019
+	{
1020
+		self::_load_controller();
1021
+		$messages        = EEM_Message::instance()->get_all(
1022
+			array(
1023
+				0 => array(
1024
+					'MSG_ID' => array('IN', $message_ids),
1025
+					'STS_ID' => EEM_Message::status_incomplete,
1026
+				),
1027
+			)
1028
+		);
1029
+		$generated_queue = false;
1030
+		if ($messages) {
1031
+			$generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue($messages);
1032
+		}
1033
+
1034
+		if (! $generated_queue instanceof EE_Messages_Queue) {
1035
+			EE_Error::add_error(
1036
+				__('The messages were not generated. This could mean there is already a batch being generated on a separate request, or because the selected messages are not ready for generation. Please wait a minute or two and try again.',
1037
+					'event_espresso'),
1038
+				__FILE__, __FUNCTION__, __LINE__
1039
+			);
1040
+		}
1041
+		return $generated_queue;
1042
+	}
1043
+
1044
+
1045
+	/**
1046
+	 * Sends messages immediately for the incoming message_ids that have the status of EEM_Message::status_resend or,
1047
+	 * EEM_Message::status_idle
1048
+	 *
1049
+	 * @since 4.9.0
1050
+	 * @param $message_ids
1051
+	 * @return bool|EE_Messages_Queue false if no messages sent.
1052
+	 * @throws EE_Error
1053
+	 * @throws InvalidArgumentException
1054
+	 * @throws InvalidDataTypeException
1055
+	 * @throws InvalidInterfaceException
1056
+	 * @throws ReflectionException
1057
+	 */
1058
+	public static function send_now($message_ids)
1059
+	{
1060
+		self::_load_controller();
1061
+		$messages   = EEM_Message::instance()->get_all(
1062
+			array(
1063
+				0 => array(
1064
+					'MSG_ID' => array('IN', $message_ids),
1065
+					'STS_ID' => array(
1066
+						'IN',
1067
+						array(EEM_Message::status_idle, EEM_Message::status_resend, EEM_Message::status_retry),
1068
+					),
1069
+				),
1070
+			)
1071
+		);
1072
+		$sent_queue = false;
1073
+		if ($messages) {
1074
+			$sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue($messages);
1075
+		}
1076
+
1077
+		if (! $sent_queue instanceof EE_Messages_Queue) {
1078
+			EE_Error::add_error(
1079
+				__('The messages were not sent. This could mean there is already a batch being sent on a separate request, or because the selected messages are not sendable. Please wait a minute or two and try again.',
1080
+					'event_espresso'),
1081
+				__FILE__, __FUNCTION__, __LINE__
1082
+			);
1083
+		} else {
1084
+			//can count how many sent by using the messages in the queue
1085
+			$sent_count = $sent_queue->count_STS_in_queue(EEM_Message::instance()->stati_indicating_sent());
1086
+			if ($sent_count > 0) {
1087
+				EE_Error::add_success(
1088
+					sprintf(
1089
+						_n(
1090
+							'There was %d message successfully sent.',
1091
+							'There were %d messages successfully sent.',
1092
+							$sent_count,
1093
+							'event_espresso'
1094
+						),
1095
+						$sent_count
1096
+					)
1097
+				);
1098
+			} else {
1099
+				EE_Error::overwrite_errors();
1100
+				EE_Error::add_error(
1101
+					__('No message was sent because of problems with sending. Either all the messages you selected were not a sendable message, they were ALREADY sent on a different scheduled task, or there was an error.
1102 1102
 					If there was an error, you can look at the messages in the message activity list table for any error messages.',
1103
-                        'event_espresso'),
1104
-                    __FILE__, __FUNCTION__, __LINE__
1105
-                );
1106
-            }
1107
-        }
1108
-        return $sent_queue;
1109
-    }
1110
-
1111
-
1112
-    /**
1113
-     * Generate and send immediately from the given $message_ids
1114
-     *
1115
-     * @param array $message_ids EE_Message entity ids.
1116
-     * @throws EE_Error
1117
-     * @throws InvalidArgumentException
1118
-     * @throws InvalidDataTypeException
1119
-     * @throws InvalidInterfaceException
1120
-     * @throws ReflectionException
1121
-     */
1122
-    public static function generate_and_send_now(array $message_ids)
1123
-    {
1124
-        $generated_queue = self::generate_now($message_ids);
1125
-        //now let's just trigger sending immediately from this queue.
1126
-        $messages_sent = $generated_queue instanceof EE_Messages_Queue
1127
-            ? $generated_queue->execute()
1128
-            : 0;
1129
-        if ($messages_sent) {
1130
-            EE_Error::add_success(
1131
-                esc_html(
1132
-                    sprintf(
1133
-                        _n(
1134
-                            'There was %d message successfully generated and sent.',
1135
-                            'There were %d messages successfully generated and sent.',
1136
-                            $messages_sent,
1137
-                            'event_espresso'
1138
-                        ),
1139
-                        $messages_sent
1140
-                    )
1141
-                )
1142
-            );
1143
-            //errors would be added via the generate_now method.
1144
-        }
1145
-    }
1146
-
1147
-
1148
-    /**
1149
-     * This will queue the incoming message ids for resending.
1150
-     * Note, only message_ids corresponding to messages with the status of EEM_Message::sent will be queued.
1151
-     *
1152
-     * @since 4.9.0
1153
-     * @param array $message_ids An array of EE_Message IDs
1154
-     * @return bool true means messages were successfully queued for resending, false means none were queued for
1155
-     *                           resending.
1156
-     * @throws EE_Error
1157
-     * @throws InvalidArgumentException
1158
-     * @throws InvalidDataTypeException
1159
-     * @throws InvalidInterfaceException
1160
-     * @throws ReflectionException
1161
-     */
1162
-    public static function queue_for_resending($message_ids)
1163
-    {
1164
-        self::_load_controller();
1165
-        self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send($message_ids);
1166
-
1167
-        //get queue and count
1168
-        $queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
1169
-
1170
-        if (
1171
-            $queue_count > 0
1172
-        ) {
1173
-            EE_Error::add_success(
1174
-                sprintf(
1175
-                    _n(
1176
-                        '%d message successfully queued for resending.',
1177
-                        '%d messages successfully queued for resending.',
1178
-                        $queue_count,
1179
-                        'event_espresso'
1180
-                    ),
1181
-                    $queue_count
1182
-                )
1183
-            );
1184
-            /**
1185
-             * @see filter usage in EE_Messages_Queue::initiate_request_by_priority
1186
-             */
1187
-        } elseif (
1188
-            apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', true)
1189
-            || EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
1190
-        ) {
1191
-            $queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_sent);
1192
-            if ($queue_count > 0) {
1193
-                EE_Error::add_success(
1194
-                    sprintf(
1195
-                        _n(
1196
-                            '%d message successfully sent.',
1197
-                            '%d messages successfully sent.',
1198
-                            $queue_count,
1199
-                            'event_espresso'
1200
-                        ),
1201
-                        $queue_count
1202
-                    )
1203
-                );
1204
-            } else {
1205
-                EE_Error::add_error(
1206
-                    __('No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1207
-                        'event_espresso'),
1208
-                    __FILE__, __FUNCTION__, __LINE__
1209
-                );
1210
-            }
1211
-        } else {
1212
-            EE_Error::add_error(
1213
-                __('No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1214
-                    'event_espresso'),
1215
-                __FILE__, __FUNCTION__, __LINE__
1216
-            );
1217
-        }
1218
-        return (bool)$queue_count;
1219
-    }
1220
-
1221
-
1222
-    /**
1223
-     * debug
1224
-     *
1225
-     * @param string          $class
1226
-     * @param string          $func
1227
-     * @param string          $line
1228
-     * @param \EE_Transaction $transaction
1229
-     * @param array           $info
1230
-     * @param bool            $display_request
1231
-     * @throws EE_Error
1232
-     * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
1233
-     */
1234
-    protected static function log(
1235
-        $class = '',
1236
-        $func = '',
1237
-        $line = '',
1238
-        EE_Transaction $transaction,
1239
-        $info = array(),
1240
-        $display_request = false
1241
-    ) {
1242
-        if (defined('EE_DEBUG') && EE_DEBUG) {
1243
-            if ($transaction instanceof EE_Transaction) {
1244
-                // don't serialize objects
1245
-                $info                  = EEH_Debug_Tools::strip_objects($info);
1246
-                $info['TXN_status']    = $transaction->status_ID();
1247
-                $info['TXN_reg_steps'] = $transaction->reg_steps();
1248
-                if ($transaction->ID()) {
1249
-                    $index = 'EE_Transaction: ' . $transaction->ID();
1250
-                    EEH_Debug_Tools::log($class, $func, $line, $info, $display_request, $index);
1251
-                }
1252
-            }
1253
-        }
1254
-
1255
-    }
1256
-
1257
-
1258
-    /**
1259
-     *  Resets all the static properties in this class when called.
1260
-     */
1261
-    public static function reset()
1262
-    {
1263
-        self::$_EEMSG                    = null;
1264
-        self::$_message_resource_manager = null;
1265
-        self::$_MSG_PROCESSOR            = null;
1266
-        self::$_MSG_PATHS                = null;
1267
-        self::$_TMP_PACKS                = array();
1268
-    }
1103
+						'event_espresso'),
1104
+					__FILE__, __FUNCTION__, __LINE__
1105
+				);
1106
+			}
1107
+		}
1108
+		return $sent_queue;
1109
+	}
1110
+
1111
+
1112
+	/**
1113
+	 * Generate and send immediately from the given $message_ids
1114
+	 *
1115
+	 * @param array $message_ids EE_Message entity ids.
1116
+	 * @throws EE_Error
1117
+	 * @throws InvalidArgumentException
1118
+	 * @throws InvalidDataTypeException
1119
+	 * @throws InvalidInterfaceException
1120
+	 * @throws ReflectionException
1121
+	 */
1122
+	public static function generate_and_send_now(array $message_ids)
1123
+	{
1124
+		$generated_queue = self::generate_now($message_ids);
1125
+		//now let's just trigger sending immediately from this queue.
1126
+		$messages_sent = $generated_queue instanceof EE_Messages_Queue
1127
+			? $generated_queue->execute()
1128
+			: 0;
1129
+		if ($messages_sent) {
1130
+			EE_Error::add_success(
1131
+				esc_html(
1132
+					sprintf(
1133
+						_n(
1134
+							'There was %d message successfully generated and sent.',
1135
+							'There were %d messages successfully generated and sent.',
1136
+							$messages_sent,
1137
+							'event_espresso'
1138
+						),
1139
+						$messages_sent
1140
+					)
1141
+				)
1142
+			);
1143
+			//errors would be added via the generate_now method.
1144
+		}
1145
+	}
1146
+
1147
+
1148
+	/**
1149
+	 * This will queue the incoming message ids for resending.
1150
+	 * Note, only message_ids corresponding to messages with the status of EEM_Message::sent will be queued.
1151
+	 *
1152
+	 * @since 4.9.0
1153
+	 * @param array $message_ids An array of EE_Message IDs
1154
+	 * @return bool true means messages were successfully queued for resending, false means none were queued for
1155
+	 *                           resending.
1156
+	 * @throws EE_Error
1157
+	 * @throws InvalidArgumentException
1158
+	 * @throws InvalidDataTypeException
1159
+	 * @throws InvalidInterfaceException
1160
+	 * @throws ReflectionException
1161
+	 */
1162
+	public static function queue_for_resending($message_ids)
1163
+	{
1164
+		self::_load_controller();
1165
+		self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send($message_ids);
1166
+
1167
+		//get queue and count
1168
+		$queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
1169
+
1170
+		if (
1171
+			$queue_count > 0
1172
+		) {
1173
+			EE_Error::add_success(
1174
+				sprintf(
1175
+					_n(
1176
+						'%d message successfully queued for resending.',
1177
+						'%d messages successfully queued for resending.',
1178
+						$queue_count,
1179
+						'event_espresso'
1180
+					),
1181
+					$queue_count
1182
+				)
1183
+			);
1184
+			/**
1185
+			 * @see filter usage in EE_Messages_Queue::initiate_request_by_priority
1186
+			 */
1187
+		} elseif (
1188
+			apply_filters('FHEE__EE_Messages_Processor__initiate_request_by_priority__do_immediate_processing', true)
1189
+			|| EE_Registry::instance()->NET_CFG->core->do_messages_on_same_request
1190
+		) {
1191
+			$queue_count = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_sent);
1192
+			if ($queue_count > 0) {
1193
+				EE_Error::add_success(
1194
+					sprintf(
1195
+						_n(
1196
+							'%d message successfully sent.',
1197
+							'%d messages successfully sent.',
1198
+							$queue_count,
1199
+							'event_espresso'
1200
+						),
1201
+						$queue_count
1202
+					)
1203
+				);
1204
+			} else {
1205
+				EE_Error::add_error(
1206
+					__('No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1207
+						'event_espresso'),
1208
+					__FILE__, __FUNCTION__, __LINE__
1209
+				);
1210
+			}
1211
+		} else {
1212
+			EE_Error::add_error(
1213
+				__('No messages were queued for resending. This usually only happens when all the messages flagged for resending are not a status that can be resent.',
1214
+					'event_espresso'),
1215
+				__FILE__, __FUNCTION__, __LINE__
1216
+			);
1217
+		}
1218
+		return (bool)$queue_count;
1219
+	}
1220
+
1221
+
1222
+	/**
1223
+	 * debug
1224
+	 *
1225
+	 * @param string          $class
1226
+	 * @param string          $func
1227
+	 * @param string          $line
1228
+	 * @param \EE_Transaction $transaction
1229
+	 * @param array           $info
1230
+	 * @param bool            $display_request
1231
+	 * @throws EE_Error
1232
+	 * @throws \EventEspresso\core\exceptions\InvalidSessionDataException
1233
+	 */
1234
+	protected static function log(
1235
+		$class = '',
1236
+		$func = '',
1237
+		$line = '',
1238
+		EE_Transaction $transaction,
1239
+		$info = array(),
1240
+		$display_request = false
1241
+	) {
1242
+		if (defined('EE_DEBUG') && EE_DEBUG) {
1243
+			if ($transaction instanceof EE_Transaction) {
1244
+				// don't serialize objects
1245
+				$info                  = EEH_Debug_Tools::strip_objects($info);
1246
+				$info['TXN_status']    = $transaction->status_ID();
1247
+				$info['TXN_reg_steps'] = $transaction->reg_steps();
1248
+				if ($transaction->ID()) {
1249
+					$index = 'EE_Transaction: ' . $transaction->ID();
1250
+					EEH_Debug_Tools::log($class, $func, $line, $info, $display_request, $index);
1251
+				}
1252
+			}
1253
+		}
1254
+
1255
+	}
1256
+
1257
+
1258
+	/**
1259
+	 *  Resets all the static properties in this class when called.
1260
+	 */
1261
+	public static function reset()
1262
+	{
1263
+		self::$_EEMSG                    = null;
1264
+		self::$_message_resource_manager = null;
1265
+		self::$_MSG_PROCESSOR            = null;
1266
+		self::$_MSG_PATHS                = null;
1267
+		self::$_TMP_PACKS                = array();
1268
+	}
1269 1269
 
1270 1270
 }
1271 1271
 // End of file EED_Messages.module.php
Please login to merge, or discard this patch.
Spacing   +25 added lines, -25 removed lines patch added patch discarded remove patch
@@ -160,7 +160,7 @@  discard block
 block discarded – undo
160 160
             $error_msg = __('Please note that a system message failed to send due to a technical issue.',
161 161
                 'event_espresso');
162 162
             // add specific message for developers if WP_DEBUG in on
163
-            $error_msg .= '||' . $e->getMessage();
163
+            $error_msg .= '||'.$e->getMessage();
164 164
             EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
165 165
         }
166 166
     }
@@ -243,7 +243,7 @@  discard block
 block discarded – undo
243 243
             $error_msg = __('Please note that a system message failed to send due to a technical issue.',
244 244
                 'event_espresso');
245 245
             // add specific message for developers if WP_DEBUG in on
246
-            $error_msg .= '||' . $e->getMessage();
246
+            $error_msg .= '||'.$e->getMessage();
247 247
             EE_Error::add_error($error_msg, __FILE__, __FUNCTION__, __LINE__);
248 248
         }
249 249
     }
@@ -274,7 +274,7 @@  discard block
 block discarded – undo
274 274
         $transient_key = EE_Registry::instance()->REQ->get('key');
275 275
 
276 276
         //now let's verify transient, if not valid exit immediately
277
-        if (! get_transient($transient_key)) {
277
+        if ( ! get_transient($transient_key)) {
278 278
             /**
279 279
              * trigger error so this gets in the error logs.  This is important because it happens on a non-user
280 280
              * request.
@@ -287,7 +287,7 @@  discard block
 block discarded – undo
287 287
 
288 288
         if (apply_filters('FHEE__EED_Messages__run_cron__use_wp_cron', true)) {
289 289
 
290
-            $method = 'batch_' . $cron_type . '_from_queue';
290
+            $method = 'batch_'.$cron_type.'_from_queue';
291 291
             if (method_exists(self::$_MSG_PROCESSOR, $method)) {
292 292
                 self::$_MSG_PROCESSOR->$method();
293 293
             } else {
@@ -396,9 +396,9 @@  discard block
 block discarded – undo
396 396
             'messages/validators/html',
397 397
             'shortcodes',
398 398
         );
399
-        $paths   = array();
399
+        $paths = array();
400 400
         foreach ($dir_ref as $index => $dir) {
401
-            $paths[$index] = EE_LIBRARIES . $dir;
401
+            $paths[$index] = EE_LIBRARIES.$dir;
402 402
         }
403 403
         self::$_MSG_PATHS = apply_filters('FHEE__EED_Messages___set_messages_paths___MSG_PATHS', $paths);
404 404
     }
@@ -417,7 +417,7 @@  discard block
 block discarded – undo
417 417
      */
418 418
     protected static function _load_controller()
419 419
     {
420
-        if (! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
420
+        if ( ! self::$_MSG_PROCESSOR instanceof EE_Messages_Processor) {
421 421
             EE_Registry::instance()->load_core('Request_Handler');
422 422
             self::set_autoloaders();
423 423
             self::$_EEMSG                    = EE_Registry::instance()->load_lib('messages');
@@ -458,7 +458,7 @@  discard block
 block discarded – undo
458 458
     public static function payment(EE_Transaction $transaction, EE_Payment $payment = null)
459 459
     {
460 460
         //if there's no payment object, then we cannot do a payment type message!
461
-        if (! $payment instanceof EE_Payment) {
461
+        if ( ! $payment instanceof EE_Payment) {
462 462
             return;
463 463
         }
464 464
         self::_load_controller();
@@ -506,7 +506,7 @@  discard block
 block discarded – undo
506 506
     public static function maybe_registration(EE_Registration $registration, $extra_details = array())
507 507
     {
508 508
 
509
-        if (! self::_verify_registration_notification_send($registration, $extra_details)) {
509
+        if ( ! self::_verify_registration_notification_send($registration, $extra_details)) {
510 510
             //no messages please
511 511
             return;
512 512
         }
@@ -580,7 +580,7 @@  discard block
 block discarded – undo
580 580
         //	array( '$extra_details' => $extra_details )
581 581
         //);
582 582
         // currently only using this to send messages for the primary registrant
583
-        if (! $registration->is_primary_registrant()) {
583
+        if ( ! $registration->is_primary_registrant()) {
584 584
             return false;
585 585
         }
586 586
         // first we check if we're in admin and not doing front ajax
@@ -593,7 +593,7 @@  discard block
 block discarded – undo
593 593
         } else {
594 594
             // frontend request (either regular or via AJAX)
595 595
             // TXN is NOT finalized ?
596
-            if (! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
596
+            if ( ! isset($extra_details['finalized']) || $extra_details['finalized'] === false) {
597 597
                 return false;
598 598
             }
599 599
             // return visit but nothing changed ???
@@ -683,12 +683,12 @@  discard block
 block discarded – undo
683 683
         }
684 684
 
685 685
         //make sure any incoming request data is set on the REQ so that it gets picked up later.
686
-        $req_data = (array)$req_data;
686
+        $req_data = (array) $req_data;
687 687
         foreach ($req_data as $request_key => $request_value) {
688 688
             EE_Registry::instance()->REQ->set($request_key, $request_value);
689 689
         }
690 690
 
691
-        if (! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request()) {
691
+        if ( ! $messages_to_send = self::$_MSG_PROCESSOR->setup_messages_to_generate_from_registration_ids_in_request()) {
692 692
             return false;
693 693
         }
694 694
 
@@ -721,13 +721,13 @@  discard block
 block discarded – undo
721 721
         self::_load_controller();
722 722
 
723 723
         $msgID = EE_Registry::instance()->REQ->get('MSG_ID');
724
-        if (! $msgID) {
724
+        if ( ! $msgID) {
725 725
             EE_Error::add_error(__('Something went wrong because there is no "MSG_ID" value in the request',
726 726
                 'event_espresso'), __FILE__, __FUNCTION__, __LINE__);
727 727
             return false;
728 728
         }
729 729
 
730
-        self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send((array)$msgID);
730
+        self::$_MSG_PROCESSOR->setup_messages_from_ids_and_send((array) $msgID);
731 731
 
732 732
         //setup success message.
733 733
         $count_ready_for_resend = self::$_MSG_PROCESSOR->get_queue()->count_STS_in_queue(EEM_Message::status_resend);
@@ -832,7 +832,7 @@  discard block
 block discarded – undo
832 832
     public static function send_newsletter_message($registrations, $grp_id)
833 833
     {
834 834
         //make sure mtp is id and set it in the EE_Request Handler later messages setup.
835
-        EE_Registry::instance()->REQ->set('GRP_ID', (int)$grp_id);
835
+        EE_Registry::instance()->REQ->set('GRP_ID', (int) $grp_id);
836 836
         self::_load_controller();
837 837
         self::$_MSG_PROCESSOR->generate_for_all_active_messengers('newsletter', $registrations);
838 838
     }
@@ -892,14 +892,14 @@  discard block
 block discarded – undo
892 892
             //get the message template group.
893 893
             $msg_template_group = EEM_Message_Template_Group::instance()->get_one(array($template_query_params));
894 894
             //if we don't have an EE_Message_Template_Group then return
895
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
895
+            if ( ! $msg_template_group instanceof EE_Message_Template_Group) {
896 896
                 // remove EVT_ID from query params so that global templates get picked up
897 897
                 unset($template_query_params['Event.EVT_ID']);
898 898
                 //get global template as the fallback
899 899
                 $msg_template_group = EEM_Message_Template_Group::instance()->get_one(array($template_query_params));
900 900
             }
901 901
             //if we don't have an EE_Message_Template_Group then return
902
-            if (! $msg_template_group instanceof EE_Message_Template_Group) {
902
+            if ( ! $msg_template_group instanceof EE_Message_Template_Group) {
903 903
                 return '';
904 904
             }
905 905
             // generate the URL
@@ -936,7 +936,7 @@  discard block
 block discarded – undo
936 936
     public static function preview_message($type, $context, $messenger, $send = false)
937 937
     {
938 938
         self::_load_controller();
939
-        $mtg                     = new EE_Message_To_Generate(
939
+        $mtg = new EE_Message_To_Generate(
940 940
             $messenger,
941 941
             $type,
942 942
             array(),
@@ -1018,7 +1018,7 @@  discard block
 block discarded – undo
1018 1018
     public static function generate_now($message_ids)
1019 1019
     {
1020 1020
         self::_load_controller();
1021
-        $messages        = EEM_Message::instance()->get_all(
1021
+        $messages = EEM_Message::instance()->get_all(
1022 1022
             array(
1023 1023
                 0 => array(
1024 1024
                     'MSG_ID' => array('IN', $message_ids),
@@ -1031,7 +1031,7 @@  discard block
 block discarded – undo
1031 1031
             $generated_queue = self::$_MSG_PROCESSOR->batch_generate_from_queue($messages);
1032 1032
         }
1033 1033
 
1034
-        if (! $generated_queue instanceof EE_Messages_Queue) {
1034
+        if ( ! $generated_queue instanceof EE_Messages_Queue) {
1035 1035
             EE_Error::add_error(
1036 1036
                 __('The messages were not generated. This could mean there is already a batch being generated on a separate request, or because the selected messages are not ready for generation. Please wait a minute or two and try again.',
1037 1037
                     'event_espresso'),
@@ -1058,7 +1058,7 @@  discard block
 block discarded – undo
1058 1058
     public static function send_now($message_ids)
1059 1059
     {
1060 1060
         self::_load_controller();
1061
-        $messages   = EEM_Message::instance()->get_all(
1061
+        $messages = EEM_Message::instance()->get_all(
1062 1062
             array(
1063 1063
                 0 => array(
1064 1064
                     'MSG_ID' => array('IN', $message_ids),
@@ -1074,7 +1074,7 @@  discard block
 block discarded – undo
1074 1074
             $sent_queue = self::$_MSG_PROCESSOR->batch_send_from_queue($messages);
1075 1075
         }
1076 1076
 
1077
-        if (! $sent_queue instanceof EE_Messages_Queue) {
1077
+        if ( ! $sent_queue instanceof EE_Messages_Queue) {
1078 1078
             EE_Error::add_error(
1079 1079
                 __('The messages were not sent. This could mean there is already a batch being sent on a separate request, or because the selected messages are not sendable. Please wait a minute or two and try again.',
1080 1080
                     'event_espresso'),
@@ -1215,7 +1215,7 @@  discard block
 block discarded – undo
1215 1215
                 __FILE__, __FUNCTION__, __LINE__
1216 1216
             );
1217 1217
         }
1218
-        return (bool)$queue_count;
1218
+        return (bool) $queue_count;
1219 1219
     }
1220 1220
 
1221 1221
 
@@ -1246,7 +1246,7 @@  discard block
 block discarded – undo
1246 1246
                 $info['TXN_status']    = $transaction->status_ID();
1247 1247
                 $info['TXN_reg_steps'] = $transaction->reg_steps();
1248 1248
                 if ($transaction->ID()) {
1249
-                    $index = 'EE_Transaction: ' . $transaction->ID();
1249
+                    $index = 'EE_Transaction: '.$transaction->ID();
1250 1250
                     EEH_Debug_Tools::log($class, $func, $line, $info, $display_request, $index);
1251 1251
                 }
1252 1252
             }
Please login to merge, or discard this patch.
core/libraries/messages/validators/EE_Messages_Validator.core.php 3 patches
Doc Comments   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -505,7 +505,7 @@
 block discarded – undo
505 505
      *
506 506
      * @param  string $value            string to evaluate
507 507
      * @param  array  $valid_shortcodes array of shortcodes that are acceptable.
508
-     * @return mixed (bool|string)  return either a list of invalid shortcodes OR false if the shortcodes validate.
508
+     * @return false|string (bool|string)  return either a list of invalid shortcodes OR false if the shortcodes validate.
509 509
      */
510 510
     protected function _invalid_shortcodes($value, $valid_shortcodes)
511 511
     {
Please login to merge, or discard this patch.
Indentation   +622 added lines, -622 removed lines patch added patch discarded remove patch
@@ -20,626 +20,626 @@
 block discarded – undo
20 20
 {
21 21
 
22 22
 
23
-    /**
24
-     * These properties just hold the name for the Messenger and Message Type (defined by child classes).
25
-     * These are used for retrieving objects etc.
26
-     *
27
-     * @var string
28
-     */
29
-    protected $_m_name;
30
-    protected $_mt_name;
31
-
32
-
33
-    /**
34
-     * This will hold any error messages from the validation process.
35
-     * The _errors property holds an associative array of error messages
36
-     * listing the field as the key and the message as the value.
37
-     *
38
-     * @var array()
39
-     */
40
-    private $_errors = array();
41
-
42
-
43
-    /**
44
-     * holds an array of fields being validated
45
-     *
46
-     * @var array
47
-     */
48
-    protected $_fields;
49
-
50
-
51
-    /**
52
-     * this will hold the incoming context
53
-     *
54
-     * @var string
55
-     */
56
-    protected $_context;
57
-
58
-
59
-    /**
60
-     * this holds an array of fields and the relevant validation information
61
-     * that the incoming fields data get validated against.
62
-     * This gets setup in the _set_props() method.
63
-     *
64
-     * @var array
65
-     */
66
-    protected $_validators;
67
-
68
-
69
-    /**
70
-     * holds the messenger object
71
-     *
72
-     * @var object
73
-     */
74
-    protected $_messenger;
75
-
76
-
77
-    /**
78
-     * holds the message type object
79
-     *
80
-     * @var object
81
-     */
82
-    protected $_message_type;
83
-
84
-
85
-    /**
86
-     * will hold any valid_shortcode modifications made by the _modify_validator() method.
87
-     *
88
-     * @var array
89
-     */
90
-    protected $_valid_shortcodes_modifier;
91
-
92
-
93
-    /**
94
-     * There may be times where a message type wants to include a shortcode group but exclude specific
95
-     * shortcodes.  If that's the case then it can set this property as an array of shortcodes to exclude and
96
-     * they will not be allowed.
97
-     * Array should be indexed by field and values are an array of specific shortcodes to exclude.
98
-     *
99
-     * @var array
100
-     */
101
-    protected $_specific_shortcode_excludes = array();
102
-
103
-
104
-    /**
105
-     * Runs the validator using the incoming fields array as the fields/values to check.
106
-     *
107
-     * @param array $fields The fields sent by the EEM object.
108
-     * @param       $context
109
-     * @throws EE_Error
110
-     * @throws ReflectionException
111
-     */
112
-    public function __construct($fields, $context)
113
-    {
114
-        //check that _m_name and _mt_name have been set by child class otherwise we get out.
115
-        if (empty($this->_m_name) || empty($this->_mt_name)) {
116
-            throw new EE_Error(
117
-                esc_html__(
118
-                    'EE_Messages_Validator child classes MUST set the $_m_name and $_mt_name property.  Check that the child class is doing this',
119
-                    'event_espresso'
120
-                )
121
-            );
122
-        }
123
-        $this->_fields  = $fields;
124
-        $this->_context = $context;
125
-
126
-        //load messenger and message_type objects and the related shortcode objects.
127
-        $this->_load_objects();
128
-
129
-
130
-        //modify any messenger/message_type specific validation instructions.  This is what child classes define.
131
-        $this->_modify_validator();
132
-
133
-
134
-        //let's set validators property
135
-        $this->_set_validators();
136
-    }
137
-
138
-
139
-    /**
140
-     * Child classes instantiate this and use it to modify the _validator_config array property
141
-     * for the messenger using messengers set_validate_config() method.
142
-     * This is so we can specify specific validation instructions for a messenger/message_type combo
143
-     * that aren't handled by the defaults setup in the messenger.
144
-     *
145
-     * @abstract
146
-     * @access protected
147
-     * @return void
148
-     */
149
-    abstract protected function _modify_validator();
150
-
151
-
152
-    /**
153
-     * loads all objects used by validator
154
-     *
155
-     * @access private
156
-     * @throws \EE_Error
157
-     */
158
-    private function _load_objects()
159
-    {
160
-        //load messenger
161
-        $messenger = ucwords(str_replace('_', ' ', $this->_m_name));
162
-        $messenger = str_replace(' ', '_', $messenger);
163
-        $messenger = 'EE_' . $messenger . '_messenger';
164
-
165
-        if (! class_exists($messenger)) {
166
-            throw new EE_Error(
167
-                sprintf(
168
-                    esc_html__('There is no messenger class for the given string (%s)', 'event_espresso'),
169
-                    $this->_m_name
170
-                )
171
-            );
172
-        }
173
-
174
-        $this->_messenger = new $messenger();
175
-
176
-        //load message type
177
-        $message_type = ucwords(str_replace('_', ' ', $this->_mt_name));
178
-        $message_type = str_replace(' ', '_', $message_type);
179
-        $message_type = 'EE_' . $message_type . '_message_type';
180
-
181
-        if (! class_exists($message_type)) {
182
-            throw new EE_Error(
183
-                sprintf(
184
-                    esc_html__('There is no message type class for the given string (%s)', 'event_espresso'),
185
-                    $this->_mt_name
186
-                )
187
-            );
188
-        }
189
-
190
-        $this->_message_type = new $message_type();
191
-    }
192
-
193
-
194
-    /**
195
-     * used to set the $_validators property
196
-     *
197
-     * @access private
198
-     * @return void
199
-     * @throws ReflectionException
200
-     */
201
-    private function _set_validators()
202
-    {
203
-        // let's get all valid shortcodes from mt and message type
204
-        // (messenger will have its set in the _validator_config property for the messenger)
205
-        $mt_codes = $this->_message_type->get_valid_shortcodes();
206
-
207
-
208
-        //get messenger validator_config
209
-        $msgr_validator = $this->_messenger->get_validator_config();
210
-
211
-
212
-        //we only want the valid shortcodes for the given context!
213
-        $context  = $this->_context;
214
-        $mt_codes = $mt_codes[$context];
215
-
216
-        // in this first loop we're just getting all shortcode group indexes from the msgr_validator
217
-        // into a single array (so we can get the appropriate shortcode objects for the groups)
218
-        $shortcode_groups = $mt_codes;
219
-        $groups_per_field = array();
220
-
221
-        foreach ($msgr_validator as $field => $config) {
222
-            if (empty($config) || ! isset($config['shortcodes'])) {
223
-                continue;
224
-            }  //Nothing to see here.
225
-            $groups_per_field[$field] = array_intersect($config['shortcodes'], $mt_codes);
226
-            $shortcode_groups         = array_merge($config['shortcodes'], $shortcode_groups);
227
-        }
228
-
229
-        $shortcode_groups = array_unique($shortcode_groups);
230
-
231
-        // okay now we've got our groups.
232
-        // Let's get the codes from the objects into an array indexed by group for easy retrieval later.
233
-        $codes_from_objs = array();
234
-
235
-        foreach ($shortcode_groups as $group) {
236
-            $ref       = ucwords(str_replace('_', ' ', $group));
237
-            $ref       = str_replace(' ', '_', $ref);
238
-            $classname = 'EE_' . $ref . '_Shortcodes';
239
-            if (class_exists($classname)) {
240
-                $a                       = new ReflectionClass($classname);
241
-                $obj                     = $a->newInstance();
242
-                $codes_from_objs[$group] = $obj->get_shortcodes();
243
-            }
244
-        }
245
-
246
-
247
-        //let's just replace the $mt shortcode group indexes with the actual shortcodes (unique)
248
-        $final_mt_codes = array();
249
-        foreach ($mt_codes as $group) {
250
-            $final_mt_codes = array_merge($final_mt_codes, $codes_from_objs[$group]);
251
-        }
252
-
253
-        $mt_codes = $final_mt_codes;
254
-
255
-
256
-        // k now in this next loop we're going to loop through $msgr_validator again
257
-        // and setup the _validators property from the data we've setup so far.
258
-        foreach ($msgr_validator as $field => $config) {
259
-            //if required shortcode is not in our list of codes for the given field, then we skip this field.
260
-            $required = isset($config['required'])
261
-                ? array_intersect($config['required'], array_keys($mt_codes))
262
-                : true;
263
-            if (empty($required)) {
264
-                continue;
265
-            }
266
-
267
-            //If we have an override then we use it to indicate the codes we want.
268
-            if (isset($this->_valid_shortcodes_modifier[$context][$field])) {
269
-                $this->_validators[$field]['shortcodes'] = $this->_reassemble_valid_shortcodes_from_group(
270
-                    $this->_valid_shortcodes_modifier[$context][$field],
271
-                    $codes_from_objs
272
-                );
273
-            } //if we have specific shortcodes for a field then we need to use them
274
-            elseif (isset($groups_per_field[$field])) {
275
-                $this->_validators[$field]['shortcodes'] = $this->_reassemble_valid_shortcodes_from_group(
276
-                    $groups_per_field[$field],
277
-                    $codes_from_objs
278
-                );
279
-            } //if empty config then we're assuming we're just going to use the shortcodes from the message type context
280
-            elseif (empty($config)) {
281
-                $this->_validators[$field]['shortcodes'] = $mt_codes;
282
-            } //if we have specific shortcodes then we need to use them
283
-            elseif (isset($config['specific_shortcodes'])) {
284
-                $this->_validators[$field]['shortcodes'] = $config['specific_shortcodes'];
285
-            } //otherwise the shortcodes are what is set by the messenger for that field
286
-            else {
287
-                foreach ($config['shortcodes'] as $group) {
288
-                    $this->_validators[$field]['shortcodes'] = isset($this->_validators[$field]['shortcodes'])
289
-                        ? array_merge($this->_validators[$field]['shortcodes'], $codes_from_objs[$group])
290
-                        : $codes_from_objs[$group];
291
-                }
292
-            }
293
-
294
-            //now let's just make sure that any excluded specific shortcodes are removed.
295
-            $specific_excludes = $this->get_specific_shortcode_excludes();
296
-            if (isset($specific_excludes[$field])) {
297
-                foreach ($specific_excludes[$field] as $sex) {
298
-                    if (isset($this->_validators[$field]['shortcodes'][$sex])) {
299
-                        unset($this->_validators[$field]['shortcodes'][$sex]);
300
-                    }
301
-                }
302
-            }
303
-
304
-            //hey! don't forget to include the type if present!
305
-            $this->_validators[$field]['type'] = isset($config['type']) ? $config['type'] : null;
306
-        }
307
-    }
308
-
309
-
310
-    /**
311
-     * This just returns the validators property that contains information
312
-     * about the various shortcodes and their availability with each field
313
-     *
314
-     * @return array
315
-     */
316
-    public function get_validators()
317
-    {
318
-        return $this->_validators;
319
-    }
320
-
321
-
322
-    /**
323
-     * This simply returns the specific shortcode_excludes property that is set.
324
-     *
325
-     * @since 4.5.0
326
-     * @return array
327
-     */
328
-    public function get_specific_shortcode_excludes()
329
-    {
330
-        //specific validator filter
331
-        $shortcode_excludes = apply_filters(
332
-            'FHEE__' . get_class($this) . '__get_specific_shortcode_excludes;',
333
-            $this->_specific_shortcode_excludes,
334
-            $this->_context
335
-        );
336
-        //global filter
337
-        return apply_filters(
338
-            'FHEE__EE_Messages_Validator__get_specific_shortcode_excludes',
339
-            $shortcode_excludes,
340
-            $this->_context,
341
-            $this
342
-        );
343
-    }
344
-
345
-
346
-    /**
347
-     * This is the main method that handles validation
348
-     * What it does is loop through the _fields (the ones that get validated)
349
-     * and checks them against the shortcodes array for the field and the 'type' indicated by the
350
-     *
351
-     * @access public
352
-     * @return mixed (bool|array)  if errors present we return the array otherwise true
353
-     */
354
-    public function validate()
355
-    {
356
-        //some defaults
357
-        $template_fields = $this->_messenger->get_template_fields();
358
-        //loop through the fields and check!
359
-        foreach ($this->_fields as $field => $value) {
360
-            $this->_errors[$field] = array();
361
-            $err_msg               = '';
362
-            $field_label           = '';
363
-            //if field is not present in the _validators array then we continue
364
-            if (! isset($this->_validators[$field])) {
365
-                unset($this->_errors[$field]);
366
-                continue;
367
-            }
368
-
369
-            //get the translated field label!
370
-            //first check if it's in the main fields list
371
-            if (isset($template_fields[$field])) {
372
-                if (empty($template_fields[$field])) {
373
-                    $field_label = $field;
374
-                } //most likely the field is found in the 'extra' array.
375
-                else {
376
-                    $field_label = $template_fields[$field]['label'];
377
-                }
378
-            }
379
-
380
-            // if field label is empty OR is equal to the current field
381
-            // then we need to loop through the 'extra' fields in the template_fields config (if present)
382
-            if (isset($template_fields['extra']) && (empty($field_label) || $field_label === $field)) {
383
-                foreach ($template_fields['extra'] as $main_field => $secondary_field) {
384
-                    foreach ($secondary_field as $name => $values) {
385
-                        if ($name === $field) {
386
-                            $field_label = $values['label'];
387
-                        }
388
-
389
-                        // if we've got a 'main' secondary field, let's see if that matches what field we're on
390
-                        // which means it contains the label for this field.
391
-                        if ($name === 'main' && $main_field === $field_label) {
392
-                            $field_label = $values['label'];
393
-                        }
394
-                    }
395
-                }
396
-            }
397
-
398
-            //field is present. Let's validate shortcodes first (but only if shortcodes present).
399
-            if (isset($this->_validators[$field]['shortcodes'])
400
-                && ! empty($this->_validators[$field]['shortcodes'])
401
-            ) {
402
-                $invalid_shortcodes = $this->_invalid_shortcodes($value, $this->_validators[$field]['shortcodes']);
403
-                // if true then that means there is a returned error message
404
-                // that we'll need to add to the _errors array for this field.
405
-                if ($invalid_shortcodes) {
406
-                    $v_s     = array_keys($this->_validators[$field]['shortcodes']);
407
-                    $err_msg = sprintf(
408
-                        esc_html__(
409
-                            '%3$sThe following shortcodes were found in the "%1$s" field that ARE not valid: %2$s%4$s',
410
-                            'event_espresso'
411
-                        ),
412
-                        '<strong>' . $field_label . '</strong>',
413
-                        $invalid_shortcodes,
414
-                        '<p>',
415
-                        '</p >'
416
-                    );
417
-                    $err_msg .= sprintf(
418
-                        esc_html__('%2$sValid shortcodes for this field are: %1$s%3$s', 'event_espresso'),
419
-                        implode(', ', $v_s),
420
-                        '<strong>',
421
-                        '</strong>'
422
-                    );
423
-                }
424
-            }
425
-
426
-            //if there's a "type" to be validated then let's do that too.
427
-            if (isset($this->_validators[$field]['type']) && ! empty($this->_validators[$field]['type'])) {
428
-                switch ($this->_validators[$field]['type']) {
429
-                    case 'number':
430
-                        if (! is_numeric($value)) {
431
-                            $err_msg .= sprintf(
432
-                                esc_html__(
433
-                                    '%3$sThe %1$s field is supposed to be a number. The value given (%2$s)  is not.  Please double-check and make sure the field contains a number%4$s',
434
-                                    'event_espresso'
435
-                                ),
436
-                                $field_label,
437
-                                $value,
438
-                                '<p>',
439
-                                '</p >'
440
-                            );
441
-                        }
442
-                        break;
443
-                    case 'email':
444
-                        $valid_email = $this->_validate_email($value);
445
-                        if (! $valid_email) {
446
-                            $err_msg .= htmlentities(
447
-                                sprintf(
448
-                                    esc_html__(
449
-                                        'The %1$s field has at least one string that is not a valid email address record.  Valid emails are in the format: "Name <[email protected]>" or "[email protected]" and multiple emails can be separated by a comma.'
450
-                                    ),
451
-                                    $field_label
452
-
453
-                                )
454
-                            );
455
-                        }
456
-                        break;
457
-                    default:
458
-                        break;
459
-                }
460
-            }
461
-
462
-            //if $err_msg isn't empty let's setup the _errors array for this field.
463
-            if (! empty($err_msg)) {
464
-                $this->_errors[$field]['msg'] = $err_msg;
465
-            } else {
466
-                unset($this->_errors[$field]);
467
-            }
468
-        }
469
-
470
-        // if we have ANY errors, then we want to make sure we return the values
471
-        // for ALL the fields so the user doesn't have to retype them all.
472
-        if (! empty($this->_errors)) {
473
-            foreach ($this->_fields as $field => $value) {
474
-                $this->_errors[$field]['value'] = stripslashes($value);
475
-            }
476
-        }
477
-
478
-        //return any errors or just TRUE if everything validates
479
-        return empty($this->_errors) ? true : $this->_errors;
480
-    }
481
-
482
-
483
-    /**
484
-     * Reassembles and returns an array of valid shortcodes
485
-     * given the array of groups and array of shortcodes indexed by group.
486
-     *
487
-     * @param  array $groups          array of shortcode groups that we want shortcodes for
488
-     * @param  array $codes_from_objs All the codes available.
489
-     * @return array                   an array of actual shortcodes (that will be used for validation).
490
-     */
491
-    private function _reassemble_valid_shortcodes_from_group($groups, $codes_from_objs)
492
-    {
493
-        $shortcodes = array();
494
-        foreach ($groups as $group) {
495
-            $shortcodes = array_merge($shortcodes, $codes_from_objs[$group]);
496
-        }
497
-        return $shortcodes;
498
-    }
499
-
500
-
501
-    /**
502
-     * Validates a string against a list of accepted shortcodes
503
-     * This function takes in an array of shortcodes
504
-     * and makes sure that the given string ONLY contains shortcodes in that array.
505
-     *
506
-     * @param  string $value            string to evaluate
507
-     * @param  array  $valid_shortcodes array of shortcodes that are acceptable.
508
-     * @return mixed (bool|string)  return either a list of invalid shortcodes OR false if the shortcodes validate.
509
-     */
510
-    protected function _invalid_shortcodes($value, $valid_shortcodes)
511
-    {
512
-        //first we need to go through the string and get the shortcodes in the string
513
-        preg_match_all('/(\[.+?\])/', $value, $matches);
514
-        $incoming_shortcodes = (array)$matches[0];
515
-
516
-        //get a diff of the shortcodes in the string vs the valid shortcodes
517
-        $diff = array_diff($incoming_shortcodes, array_keys($valid_shortcodes));
518
-
519
-        //we need to account for custom codes so let's loop through the diff and remove any of those type of codes
520
-        foreach ($diff as $ind => $code) {
521
-            if (preg_match('/(\[[A-Za-z0-9\_]+_\*)/', $code)) {
522
-                //strip the shortcode so we just have the BASE string (i.e. [ANSWER_*] )
523
-                $dynamic_sc = preg_replace('/(_\*+.+)/', '_*]', $code);
524
-                //does this exist in the $valid_shortcodes?  If so then unset.
525
-                if (isset($valid_shortcodes[$dynamic_sc])) {
526
-                    unset($diff[$ind]);
527
-                }
528
-            }
529
-        }
530
-
531
-        if (empty($diff)) {
532
-            return false;
533
-        } //there is no diff, we have no invalid shortcodes, so return
534
-
535
-        //made it here? then let's assemble the error message
536
-        $invalid_shortcodes = implode('</strong>,<strong>', $diff);
537
-        $invalid_shortcodes = '<strong>' . $invalid_shortcodes . '</strong>';
538
-        return $invalid_shortcodes;
539
-    }
540
-
541
-
542
-    /**
543
-     * Validates an incoming string and makes sure we have valid emails in the string.
544
-     *
545
-     * @param  string $value incoming value to validate
546
-     * @return bool        true if the string validates, false if it doesn't
547
-     */
548
-    protected function _validate_email($value)
549
-    {
550
-        $validate = true;
551
-        $or_val   = $value;
552
-
553
-        // empty strings will validate because this is how a message template
554
-        // for a particular context can be "turned off" (if there is no email then no message)
555
-        if (empty($value)) {
556
-            return $validate;
557
-        }
558
-
559
-        // first determine if there ARE any shortcodes.
560
-        // If there are shortcodes and then later we find that there were no other valid emails
561
-        // but the field isn't empty...
562
-        // that means we've got extra commas that were left after stripping out shortcodes so probably still valid.
563
-        $has_shortcodes = preg_match('/(\[.+?\])/', $value);
564
-
565
-        //first we need to strip out all the shortcodes!
566
-        $value = preg_replace('/(\[.+?\])/', '', $value);
567
-
568
-        // if original value is not empty and new value is, then we've parsed out a shortcode
569
-        // and we now have an empty string which DOES validate.
570
-        // We also validate complete empty field for email because
571
-        // its possible that this message is being "turned off" for a particular context
572
-
573
-
574
-        if (! empty($or_val) && empty($value)) {
575
-            return $validate;
576
-        }
577
-
578
-        //trim any commas from beginning and end of string ( after whitespace trimmed );
579
-        $value = trim(trim($value), ',');
580
-
581
-
582
-        //next we need to split up the string if its comma delimited.
583
-        $emails = explode(',', $value);
584
-        $empty  = false; //used to indicate that there is an empty comma.
585
-        //now let's loop through the emails and do our checks
586
-        foreach ($emails as $email) {
587
-            if (empty($email)) {
588
-                $empty = true;
589
-                continue;
590
-            }
591
-
592
-            //trim whitespace
593
-            $email = trim($email);
594
-            //either its of type "[email protected]", or its of type "fname lname <[email protected]>"
595
-            if (is_email($email)) {
596
-                continue;
597
-            }
598
-            $matches  = array();
599
-            $validate = preg_match('/(.*)<(.+)>/', $email, $matches) ? true : false;
600
-            if ($validate && is_email($matches[2])) {
601
-                continue;
602
-            }
603
-            return false;
604
-        }
605
-
606
-        $validate = $empty && ! $has_shortcodes ? false : $validate;
607
-
608
-        return $validate;
609
-    }
610
-
611
-
612
-    /**
613
-     * Magic getter
614
-     * Using this to provide back compat with add-ons referencing deprecated properties.
615
-     *
616
-     * @param string $property Property being requested
617
-     * @throws Exception
618
-     * @return mixed
619
-     */
620
-    public function __get($property)
621
-    {
622
-        $expected_properties_map = array(
623
-            /**
624
-             * @deprecated 4.9.0
625
-             */
626
-            '_MSGR'   => '_messenger',
627
-            /**
628
-             * @deprecated 4.9.0
629
-             */
630
-            '_MSGTYP' => '_message_type',
631
-        );
632
-
633
-        if (isset($expected_properties_map[$property])) {
634
-            return $this->{$expected_properties_map[$property]};
635
-        }
636
-
637
-        throw new Exception(
638
-            sprintf(
639
-                esc_html__('The property %1$s being requested on %2$s does not exist', 'event_espresso'),
640
-                $property,
641
-                get_class($this)
642
-            )
643
-        );
644
-    }
23
+	/**
24
+	 * These properties just hold the name for the Messenger and Message Type (defined by child classes).
25
+	 * These are used for retrieving objects etc.
26
+	 *
27
+	 * @var string
28
+	 */
29
+	protected $_m_name;
30
+	protected $_mt_name;
31
+
32
+
33
+	/**
34
+	 * This will hold any error messages from the validation process.
35
+	 * The _errors property holds an associative array of error messages
36
+	 * listing the field as the key and the message as the value.
37
+	 *
38
+	 * @var array()
39
+	 */
40
+	private $_errors = array();
41
+
42
+
43
+	/**
44
+	 * holds an array of fields being validated
45
+	 *
46
+	 * @var array
47
+	 */
48
+	protected $_fields;
49
+
50
+
51
+	/**
52
+	 * this will hold the incoming context
53
+	 *
54
+	 * @var string
55
+	 */
56
+	protected $_context;
57
+
58
+
59
+	/**
60
+	 * this holds an array of fields and the relevant validation information
61
+	 * that the incoming fields data get validated against.
62
+	 * This gets setup in the _set_props() method.
63
+	 *
64
+	 * @var array
65
+	 */
66
+	protected $_validators;
67
+
68
+
69
+	/**
70
+	 * holds the messenger object
71
+	 *
72
+	 * @var object
73
+	 */
74
+	protected $_messenger;
75
+
76
+
77
+	/**
78
+	 * holds the message type object
79
+	 *
80
+	 * @var object
81
+	 */
82
+	protected $_message_type;
83
+
84
+
85
+	/**
86
+	 * will hold any valid_shortcode modifications made by the _modify_validator() method.
87
+	 *
88
+	 * @var array
89
+	 */
90
+	protected $_valid_shortcodes_modifier;
91
+
92
+
93
+	/**
94
+	 * There may be times where a message type wants to include a shortcode group but exclude specific
95
+	 * shortcodes.  If that's the case then it can set this property as an array of shortcodes to exclude and
96
+	 * they will not be allowed.
97
+	 * Array should be indexed by field and values are an array of specific shortcodes to exclude.
98
+	 *
99
+	 * @var array
100
+	 */
101
+	protected $_specific_shortcode_excludes = array();
102
+
103
+
104
+	/**
105
+	 * Runs the validator using the incoming fields array as the fields/values to check.
106
+	 *
107
+	 * @param array $fields The fields sent by the EEM object.
108
+	 * @param       $context
109
+	 * @throws EE_Error
110
+	 * @throws ReflectionException
111
+	 */
112
+	public function __construct($fields, $context)
113
+	{
114
+		//check that _m_name and _mt_name have been set by child class otherwise we get out.
115
+		if (empty($this->_m_name) || empty($this->_mt_name)) {
116
+			throw new EE_Error(
117
+				esc_html__(
118
+					'EE_Messages_Validator child classes MUST set the $_m_name and $_mt_name property.  Check that the child class is doing this',
119
+					'event_espresso'
120
+				)
121
+			);
122
+		}
123
+		$this->_fields  = $fields;
124
+		$this->_context = $context;
125
+
126
+		//load messenger and message_type objects and the related shortcode objects.
127
+		$this->_load_objects();
128
+
129
+
130
+		//modify any messenger/message_type specific validation instructions.  This is what child classes define.
131
+		$this->_modify_validator();
132
+
133
+
134
+		//let's set validators property
135
+		$this->_set_validators();
136
+	}
137
+
138
+
139
+	/**
140
+	 * Child classes instantiate this and use it to modify the _validator_config array property
141
+	 * for the messenger using messengers set_validate_config() method.
142
+	 * This is so we can specify specific validation instructions for a messenger/message_type combo
143
+	 * that aren't handled by the defaults setup in the messenger.
144
+	 *
145
+	 * @abstract
146
+	 * @access protected
147
+	 * @return void
148
+	 */
149
+	abstract protected function _modify_validator();
150
+
151
+
152
+	/**
153
+	 * loads all objects used by validator
154
+	 *
155
+	 * @access private
156
+	 * @throws \EE_Error
157
+	 */
158
+	private function _load_objects()
159
+	{
160
+		//load messenger
161
+		$messenger = ucwords(str_replace('_', ' ', $this->_m_name));
162
+		$messenger = str_replace(' ', '_', $messenger);
163
+		$messenger = 'EE_' . $messenger . '_messenger';
164
+
165
+		if (! class_exists($messenger)) {
166
+			throw new EE_Error(
167
+				sprintf(
168
+					esc_html__('There is no messenger class for the given string (%s)', 'event_espresso'),
169
+					$this->_m_name
170
+				)
171
+			);
172
+		}
173
+
174
+		$this->_messenger = new $messenger();
175
+
176
+		//load message type
177
+		$message_type = ucwords(str_replace('_', ' ', $this->_mt_name));
178
+		$message_type = str_replace(' ', '_', $message_type);
179
+		$message_type = 'EE_' . $message_type . '_message_type';
180
+
181
+		if (! class_exists($message_type)) {
182
+			throw new EE_Error(
183
+				sprintf(
184
+					esc_html__('There is no message type class for the given string (%s)', 'event_espresso'),
185
+					$this->_mt_name
186
+				)
187
+			);
188
+		}
189
+
190
+		$this->_message_type = new $message_type();
191
+	}
192
+
193
+
194
+	/**
195
+	 * used to set the $_validators property
196
+	 *
197
+	 * @access private
198
+	 * @return void
199
+	 * @throws ReflectionException
200
+	 */
201
+	private function _set_validators()
202
+	{
203
+		// let's get all valid shortcodes from mt and message type
204
+		// (messenger will have its set in the _validator_config property for the messenger)
205
+		$mt_codes = $this->_message_type->get_valid_shortcodes();
206
+
207
+
208
+		//get messenger validator_config
209
+		$msgr_validator = $this->_messenger->get_validator_config();
210
+
211
+
212
+		//we only want the valid shortcodes for the given context!
213
+		$context  = $this->_context;
214
+		$mt_codes = $mt_codes[$context];
215
+
216
+		// in this first loop we're just getting all shortcode group indexes from the msgr_validator
217
+		// into a single array (so we can get the appropriate shortcode objects for the groups)
218
+		$shortcode_groups = $mt_codes;
219
+		$groups_per_field = array();
220
+
221
+		foreach ($msgr_validator as $field => $config) {
222
+			if (empty($config) || ! isset($config['shortcodes'])) {
223
+				continue;
224
+			}  //Nothing to see here.
225
+			$groups_per_field[$field] = array_intersect($config['shortcodes'], $mt_codes);
226
+			$shortcode_groups         = array_merge($config['shortcodes'], $shortcode_groups);
227
+		}
228
+
229
+		$shortcode_groups = array_unique($shortcode_groups);
230
+
231
+		// okay now we've got our groups.
232
+		// Let's get the codes from the objects into an array indexed by group for easy retrieval later.
233
+		$codes_from_objs = array();
234
+
235
+		foreach ($shortcode_groups as $group) {
236
+			$ref       = ucwords(str_replace('_', ' ', $group));
237
+			$ref       = str_replace(' ', '_', $ref);
238
+			$classname = 'EE_' . $ref . '_Shortcodes';
239
+			if (class_exists($classname)) {
240
+				$a                       = new ReflectionClass($classname);
241
+				$obj                     = $a->newInstance();
242
+				$codes_from_objs[$group] = $obj->get_shortcodes();
243
+			}
244
+		}
245
+
246
+
247
+		//let's just replace the $mt shortcode group indexes with the actual shortcodes (unique)
248
+		$final_mt_codes = array();
249
+		foreach ($mt_codes as $group) {
250
+			$final_mt_codes = array_merge($final_mt_codes, $codes_from_objs[$group]);
251
+		}
252
+
253
+		$mt_codes = $final_mt_codes;
254
+
255
+
256
+		// k now in this next loop we're going to loop through $msgr_validator again
257
+		// and setup the _validators property from the data we've setup so far.
258
+		foreach ($msgr_validator as $field => $config) {
259
+			//if required shortcode is not in our list of codes for the given field, then we skip this field.
260
+			$required = isset($config['required'])
261
+				? array_intersect($config['required'], array_keys($mt_codes))
262
+				: true;
263
+			if (empty($required)) {
264
+				continue;
265
+			}
266
+
267
+			//If we have an override then we use it to indicate the codes we want.
268
+			if (isset($this->_valid_shortcodes_modifier[$context][$field])) {
269
+				$this->_validators[$field]['shortcodes'] = $this->_reassemble_valid_shortcodes_from_group(
270
+					$this->_valid_shortcodes_modifier[$context][$field],
271
+					$codes_from_objs
272
+				);
273
+			} //if we have specific shortcodes for a field then we need to use them
274
+			elseif (isset($groups_per_field[$field])) {
275
+				$this->_validators[$field]['shortcodes'] = $this->_reassemble_valid_shortcodes_from_group(
276
+					$groups_per_field[$field],
277
+					$codes_from_objs
278
+				);
279
+			} //if empty config then we're assuming we're just going to use the shortcodes from the message type context
280
+			elseif (empty($config)) {
281
+				$this->_validators[$field]['shortcodes'] = $mt_codes;
282
+			} //if we have specific shortcodes then we need to use them
283
+			elseif (isset($config['specific_shortcodes'])) {
284
+				$this->_validators[$field]['shortcodes'] = $config['specific_shortcodes'];
285
+			} //otherwise the shortcodes are what is set by the messenger for that field
286
+			else {
287
+				foreach ($config['shortcodes'] as $group) {
288
+					$this->_validators[$field]['shortcodes'] = isset($this->_validators[$field]['shortcodes'])
289
+						? array_merge($this->_validators[$field]['shortcodes'], $codes_from_objs[$group])
290
+						: $codes_from_objs[$group];
291
+				}
292
+			}
293
+
294
+			//now let's just make sure that any excluded specific shortcodes are removed.
295
+			$specific_excludes = $this->get_specific_shortcode_excludes();
296
+			if (isset($specific_excludes[$field])) {
297
+				foreach ($specific_excludes[$field] as $sex) {
298
+					if (isset($this->_validators[$field]['shortcodes'][$sex])) {
299
+						unset($this->_validators[$field]['shortcodes'][$sex]);
300
+					}
301
+				}
302
+			}
303
+
304
+			//hey! don't forget to include the type if present!
305
+			$this->_validators[$field]['type'] = isset($config['type']) ? $config['type'] : null;
306
+		}
307
+	}
308
+
309
+
310
+	/**
311
+	 * This just returns the validators property that contains information
312
+	 * about the various shortcodes and their availability with each field
313
+	 *
314
+	 * @return array
315
+	 */
316
+	public function get_validators()
317
+	{
318
+		return $this->_validators;
319
+	}
320
+
321
+
322
+	/**
323
+	 * This simply returns the specific shortcode_excludes property that is set.
324
+	 *
325
+	 * @since 4.5.0
326
+	 * @return array
327
+	 */
328
+	public function get_specific_shortcode_excludes()
329
+	{
330
+		//specific validator filter
331
+		$shortcode_excludes = apply_filters(
332
+			'FHEE__' . get_class($this) . '__get_specific_shortcode_excludes;',
333
+			$this->_specific_shortcode_excludes,
334
+			$this->_context
335
+		);
336
+		//global filter
337
+		return apply_filters(
338
+			'FHEE__EE_Messages_Validator__get_specific_shortcode_excludes',
339
+			$shortcode_excludes,
340
+			$this->_context,
341
+			$this
342
+		);
343
+	}
344
+
345
+
346
+	/**
347
+	 * This is the main method that handles validation
348
+	 * What it does is loop through the _fields (the ones that get validated)
349
+	 * and checks them against the shortcodes array for the field and the 'type' indicated by the
350
+	 *
351
+	 * @access public
352
+	 * @return mixed (bool|array)  if errors present we return the array otherwise true
353
+	 */
354
+	public function validate()
355
+	{
356
+		//some defaults
357
+		$template_fields = $this->_messenger->get_template_fields();
358
+		//loop through the fields and check!
359
+		foreach ($this->_fields as $field => $value) {
360
+			$this->_errors[$field] = array();
361
+			$err_msg               = '';
362
+			$field_label           = '';
363
+			//if field is not present in the _validators array then we continue
364
+			if (! isset($this->_validators[$field])) {
365
+				unset($this->_errors[$field]);
366
+				continue;
367
+			}
368
+
369
+			//get the translated field label!
370
+			//first check if it's in the main fields list
371
+			if (isset($template_fields[$field])) {
372
+				if (empty($template_fields[$field])) {
373
+					$field_label = $field;
374
+				} //most likely the field is found in the 'extra' array.
375
+				else {
376
+					$field_label = $template_fields[$field]['label'];
377
+				}
378
+			}
379
+
380
+			// if field label is empty OR is equal to the current field
381
+			// then we need to loop through the 'extra' fields in the template_fields config (if present)
382
+			if (isset($template_fields['extra']) && (empty($field_label) || $field_label === $field)) {
383
+				foreach ($template_fields['extra'] as $main_field => $secondary_field) {
384
+					foreach ($secondary_field as $name => $values) {
385
+						if ($name === $field) {
386
+							$field_label = $values['label'];
387
+						}
388
+
389
+						// if we've got a 'main' secondary field, let's see if that matches what field we're on
390
+						// which means it contains the label for this field.
391
+						if ($name === 'main' && $main_field === $field_label) {
392
+							$field_label = $values['label'];
393
+						}
394
+					}
395
+				}
396
+			}
397
+
398
+			//field is present. Let's validate shortcodes first (but only if shortcodes present).
399
+			if (isset($this->_validators[$field]['shortcodes'])
400
+				&& ! empty($this->_validators[$field]['shortcodes'])
401
+			) {
402
+				$invalid_shortcodes = $this->_invalid_shortcodes($value, $this->_validators[$field]['shortcodes']);
403
+				// if true then that means there is a returned error message
404
+				// that we'll need to add to the _errors array for this field.
405
+				if ($invalid_shortcodes) {
406
+					$v_s     = array_keys($this->_validators[$field]['shortcodes']);
407
+					$err_msg = sprintf(
408
+						esc_html__(
409
+							'%3$sThe following shortcodes were found in the "%1$s" field that ARE not valid: %2$s%4$s',
410
+							'event_espresso'
411
+						),
412
+						'<strong>' . $field_label . '</strong>',
413
+						$invalid_shortcodes,
414
+						'<p>',
415
+						'</p >'
416
+					);
417
+					$err_msg .= sprintf(
418
+						esc_html__('%2$sValid shortcodes for this field are: %1$s%3$s', 'event_espresso'),
419
+						implode(', ', $v_s),
420
+						'<strong>',
421
+						'</strong>'
422
+					);
423
+				}
424
+			}
425
+
426
+			//if there's a "type" to be validated then let's do that too.
427
+			if (isset($this->_validators[$field]['type']) && ! empty($this->_validators[$field]['type'])) {
428
+				switch ($this->_validators[$field]['type']) {
429
+					case 'number':
430
+						if (! is_numeric($value)) {
431
+							$err_msg .= sprintf(
432
+								esc_html__(
433
+									'%3$sThe %1$s field is supposed to be a number. The value given (%2$s)  is not.  Please double-check and make sure the field contains a number%4$s',
434
+									'event_espresso'
435
+								),
436
+								$field_label,
437
+								$value,
438
+								'<p>',
439
+								'</p >'
440
+							);
441
+						}
442
+						break;
443
+					case 'email':
444
+						$valid_email = $this->_validate_email($value);
445
+						if (! $valid_email) {
446
+							$err_msg .= htmlentities(
447
+								sprintf(
448
+									esc_html__(
449
+										'The %1$s field has at least one string that is not a valid email address record.  Valid emails are in the format: "Name <[email protected]>" or "[email protected]" and multiple emails can be separated by a comma.'
450
+									),
451
+									$field_label
452
+
453
+								)
454
+							);
455
+						}
456
+						break;
457
+					default:
458
+						break;
459
+				}
460
+			}
461
+
462
+			//if $err_msg isn't empty let's setup the _errors array for this field.
463
+			if (! empty($err_msg)) {
464
+				$this->_errors[$field]['msg'] = $err_msg;
465
+			} else {
466
+				unset($this->_errors[$field]);
467
+			}
468
+		}
469
+
470
+		// if we have ANY errors, then we want to make sure we return the values
471
+		// for ALL the fields so the user doesn't have to retype them all.
472
+		if (! empty($this->_errors)) {
473
+			foreach ($this->_fields as $field => $value) {
474
+				$this->_errors[$field]['value'] = stripslashes($value);
475
+			}
476
+		}
477
+
478
+		//return any errors or just TRUE if everything validates
479
+		return empty($this->_errors) ? true : $this->_errors;
480
+	}
481
+
482
+
483
+	/**
484
+	 * Reassembles and returns an array of valid shortcodes
485
+	 * given the array of groups and array of shortcodes indexed by group.
486
+	 *
487
+	 * @param  array $groups          array of shortcode groups that we want shortcodes for
488
+	 * @param  array $codes_from_objs All the codes available.
489
+	 * @return array                   an array of actual shortcodes (that will be used for validation).
490
+	 */
491
+	private function _reassemble_valid_shortcodes_from_group($groups, $codes_from_objs)
492
+	{
493
+		$shortcodes = array();
494
+		foreach ($groups as $group) {
495
+			$shortcodes = array_merge($shortcodes, $codes_from_objs[$group]);
496
+		}
497
+		return $shortcodes;
498
+	}
499
+
500
+
501
+	/**
502
+	 * Validates a string against a list of accepted shortcodes
503
+	 * This function takes in an array of shortcodes
504
+	 * and makes sure that the given string ONLY contains shortcodes in that array.
505
+	 *
506
+	 * @param  string $value            string to evaluate
507
+	 * @param  array  $valid_shortcodes array of shortcodes that are acceptable.
508
+	 * @return mixed (bool|string)  return either a list of invalid shortcodes OR false if the shortcodes validate.
509
+	 */
510
+	protected function _invalid_shortcodes($value, $valid_shortcodes)
511
+	{
512
+		//first we need to go through the string and get the shortcodes in the string
513
+		preg_match_all('/(\[.+?\])/', $value, $matches);
514
+		$incoming_shortcodes = (array)$matches[0];
515
+
516
+		//get a diff of the shortcodes in the string vs the valid shortcodes
517
+		$diff = array_diff($incoming_shortcodes, array_keys($valid_shortcodes));
518
+
519
+		//we need to account for custom codes so let's loop through the diff and remove any of those type of codes
520
+		foreach ($diff as $ind => $code) {
521
+			if (preg_match('/(\[[A-Za-z0-9\_]+_\*)/', $code)) {
522
+				//strip the shortcode so we just have the BASE string (i.e. [ANSWER_*] )
523
+				$dynamic_sc = preg_replace('/(_\*+.+)/', '_*]', $code);
524
+				//does this exist in the $valid_shortcodes?  If so then unset.
525
+				if (isset($valid_shortcodes[$dynamic_sc])) {
526
+					unset($diff[$ind]);
527
+				}
528
+			}
529
+		}
530
+
531
+		if (empty($diff)) {
532
+			return false;
533
+		} //there is no diff, we have no invalid shortcodes, so return
534
+
535
+		//made it here? then let's assemble the error message
536
+		$invalid_shortcodes = implode('</strong>,<strong>', $diff);
537
+		$invalid_shortcodes = '<strong>' . $invalid_shortcodes . '</strong>';
538
+		return $invalid_shortcodes;
539
+	}
540
+
541
+
542
+	/**
543
+	 * Validates an incoming string and makes sure we have valid emails in the string.
544
+	 *
545
+	 * @param  string $value incoming value to validate
546
+	 * @return bool        true if the string validates, false if it doesn't
547
+	 */
548
+	protected function _validate_email($value)
549
+	{
550
+		$validate = true;
551
+		$or_val   = $value;
552
+
553
+		// empty strings will validate because this is how a message template
554
+		// for a particular context can be "turned off" (if there is no email then no message)
555
+		if (empty($value)) {
556
+			return $validate;
557
+		}
558
+
559
+		// first determine if there ARE any shortcodes.
560
+		// If there are shortcodes and then later we find that there were no other valid emails
561
+		// but the field isn't empty...
562
+		// that means we've got extra commas that were left after stripping out shortcodes so probably still valid.
563
+		$has_shortcodes = preg_match('/(\[.+?\])/', $value);
564
+
565
+		//first we need to strip out all the shortcodes!
566
+		$value = preg_replace('/(\[.+?\])/', '', $value);
567
+
568
+		// if original value is not empty and new value is, then we've parsed out a shortcode
569
+		// and we now have an empty string which DOES validate.
570
+		// We also validate complete empty field for email because
571
+		// its possible that this message is being "turned off" for a particular context
572
+
573
+
574
+		if (! empty($or_val) && empty($value)) {
575
+			return $validate;
576
+		}
577
+
578
+		//trim any commas from beginning and end of string ( after whitespace trimmed );
579
+		$value = trim(trim($value), ',');
580
+
581
+
582
+		//next we need to split up the string if its comma delimited.
583
+		$emails = explode(',', $value);
584
+		$empty  = false; //used to indicate that there is an empty comma.
585
+		//now let's loop through the emails and do our checks
586
+		foreach ($emails as $email) {
587
+			if (empty($email)) {
588
+				$empty = true;
589
+				continue;
590
+			}
591
+
592
+			//trim whitespace
593
+			$email = trim($email);
594
+			//either its of type "[email protected]", or its of type "fname lname <[email protected]>"
595
+			if (is_email($email)) {
596
+				continue;
597
+			}
598
+			$matches  = array();
599
+			$validate = preg_match('/(.*)<(.+)>/', $email, $matches) ? true : false;
600
+			if ($validate && is_email($matches[2])) {
601
+				continue;
602
+			}
603
+			return false;
604
+		}
605
+
606
+		$validate = $empty && ! $has_shortcodes ? false : $validate;
607
+
608
+		return $validate;
609
+	}
610
+
611
+
612
+	/**
613
+	 * Magic getter
614
+	 * Using this to provide back compat with add-ons referencing deprecated properties.
615
+	 *
616
+	 * @param string $property Property being requested
617
+	 * @throws Exception
618
+	 * @return mixed
619
+	 */
620
+	public function __get($property)
621
+	{
622
+		$expected_properties_map = array(
623
+			/**
624
+			 * @deprecated 4.9.0
625
+			 */
626
+			'_MSGR'   => '_messenger',
627
+			/**
628
+			 * @deprecated 4.9.0
629
+			 */
630
+			'_MSGTYP' => '_message_type',
631
+		);
632
+
633
+		if (isset($expected_properties_map[$property])) {
634
+			return $this->{$expected_properties_map[$property]};
635
+		}
636
+
637
+		throw new Exception(
638
+			sprintf(
639
+				esc_html__('The property %1$s being requested on %2$s does not exist', 'event_espresso'),
640
+				$property,
641
+				get_class($this)
642
+			)
643
+		);
644
+	}
645 645
 }
Please login to merge, or discard this patch.
Spacing   +15 added lines, -15 removed lines patch added patch discarded remove patch
@@ -160,9 +160,9 @@  discard block
 block discarded – undo
160 160
         //load messenger
161 161
         $messenger = ucwords(str_replace('_', ' ', $this->_m_name));
162 162
         $messenger = str_replace(' ', '_', $messenger);
163
-        $messenger = 'EE_' . $messenger . '_messenger';
163
+        $messenger = 'EE_'.$messenger.'_messenger';
164 164
 
165
-        if (! class_exists($messenger)) {
165
+        if ( ! class_exists($messenger)) {
166 166
             throw new EE_Error(
167 167
                 sprintf(
168 168
                     esc_html__('There is no messenger class for the given string (%s)', 'event_espresso'),
@@ -176,9 +176,9 @@  discard block
 block discarded – undo
176 176
         //load message type
177 177
         $message_type = ucwords(str_replace('_', ' ', $this->_mt_name));
178 178
         $message_type = str_replace(' ', '_', $message_type);
179
-        $message_type = 'EE_' . $message_type . '_message_type';
179
+        $message_type = 'EE_'.$message_type.'_message_type';
180 180
 
181
-        if (! class_exists($message_type)) {
181
+        if ( ! class_exists($message_type)) {
182 182
             throw new EE_Error(
183 183
                 sprintf(
184 184
                     esc_html__('There is no message type class for the given string (%s)', 'event_espresso'),
@@ -235,7 +235,7 @@  discard block
 block discarded – undo
235 235
         foreach ($shortcode_groups as $group) {
236 236
             $ref       = ucwords(str_replace('_', ' ', $group));
237 237
             $ref       = str_replace(' ', '_', $ref);
238
-            $classname = 'EE_' . $ref . '_Shortcodes';
238
+            $classname = 'EE_'.$ref.'_Shortcodes';
239 239
             if (class_exists($classname)) {
240 240
                 $a                       = new ReflectionClass($classname);
241 241
                 $obj                     = $a->newInstance();
@@ -329,7 +329,7 @@  discard block
 block discarded – undo
329 329
     {
330 330
         //specific validator filter
331 331
         $shortcode_excludes = apply_filters(
332
-            'FHEE__' . get_class($this) . '__get_specific_shortcode_excludes;',
332
+            'FHEE__'.get_class($this).'__get_specific_shortcode_excludes;',
333 333
             $this->_specific_shortcode_excludes,
334 334
             $this->_context
335 335
         );
@@ -361,7 +361,7 @@  discard block
 block discarded – undo
361 361
             $err_msg               = '';
362 362
             $field_label           = '';
363 363
             //if field is not present in the _validators array then we continue
364
-            if (! isset($this->_validators[$field])) {
364
+            if ( ! isset($this->_validators[$field])) {
365 365
                 unset($this->_errors[$field]);
366 366
                 continue;
367 367
             }
@@ -409,7 +409,7 @@  discard block
 block discarded – undo
409 409
                             '%3$sThe following shortcodes were found in the "%1$s" field that ARE not valid: %2$s%4$s',
410 410
                             'event_espresso'
411 411
                         ),
412
-                        '<strong>' . $field_label . '</strong>',
412
+                        '<strong>'.$field_label.'</strong>',
413 413
                         $invalid_shortcodes,
414 414
                         '<p>',
415 415
                         '</p >'
@@ -427,7 +427,7 @@  discard block
 block discarded – undo
427 427
             if (isset($this->_validators[$field]['type']) && ! empty($this->_validators[$field]['type'])) {
428 428
                 switch ($this->_validators[$field]['type']) {
429 429
                     case 'number':
430
-                        if (! is_numeric($value)) {
430
+                        if ( ! is_numeric($value)) {
431 431
                             $err_msg .= sprintf(
432 432
                                 esc_html__(
433 433
                                     '%3$sThe %1$s field is supposed to be a number. The value given (%2$s)  is not.  Please double-check and make sure the field contains a number%4$s',
@@ -442,7 +442,7 @@  discard block
 block discarded – undo
442 442
                         break;
443 443
                     case 'email':
444 444
                         $valid_email = $this->_validate_email($value);
445
-                        if (! $valid_email) {
445
+                        if ( ! $valid_email) {
446 446
                             $err_msg .= htmlentities(
447 447
                                 sprintf(
448 448
                                     esc_html__(
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
             }
461 461
 
462 462
             //if $err_msg isn't empty let's setup the _errors array for this field.
463
-            if (! empty($err_msg)) {
463
+            if ( ! empty($err_msg)) {
464 464
                 $this->_errors[$field]['msg'] = $err_msg;
465 465
             } else {
466 466
                 unset($this->_errors[$field]);
@@ -469,7 +469,7 @@  discard block
 block discarded – undo
469 469
 
470 470
         // if we have ANY errors, then we want to make sure we return the values
471 471
         // for ALL the fields so the user doesn't have to retype them all.
472
-        if (! empty($this->_errors)) {
472
+        if ( ! empty($this->_errors)) {
473 473
             foreach ($this->_fields as $field => $value) {
474 474
                 $this->_errors[$field]['value'] = stripslashes($value);
475 475
             }
@@ -511,7 +511,7 @@  discard block
 block discarded – undo
511 511
     {
512 512
         //first we need to go through the string and get the shortcodes in the string
513 513
         preg_match_all('/(\[.+?\])/', $value, $matches);
514
-        $incoming_shortcodes = (array)$matches[0];
514
+        $incoming_shortcodes = (array) $matches[0];
515 515
 
516 516
         //get a diff of the shortcodes in the string vs the valid shortcodes
517 517
         $diff = array_diff($incoming_shortcodes, array_keys($valid_shortcodes));
@@ -534,7 +534,7 @@  discard block
 block discarded – undo
534 534
 
535 535
         //made it here? then let's assemble the error message
536 536
         $invalid_shortcodes = implode('</strong>,<strong>', $diff);
537
-        $invalid_shortcodes = '<strong>' . $invalid_shortcodes . '</strong>';
537
+        $invalid_shortcodes = '<strong>'.$invalid_shortcodes.'</strong>';
538 538
         return $invalid_shortcodes;
539 539
     }
540 540
 
@@ -571,7 +571,7 @@  discard block
 block discarded – undo
571 571
         // its possible that this message is being "turned off" for a particular context
572 572
 
573 573
 
574
-        if (! empty($or_val) && empty($value)) {
574
+        if ( ! empty($or_val) && empty($value)) {
575 575
             return $validate;
576 576
         }
577 577
 
Please login to merge, or discard this patch.